@almadar/ui 5.61.0 → 5.63.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/avl/index.cjs +3599 -1810
- package/dist/avl/index.js +2431 -642
- package/dist/components/core/atoms/Box.d.ts +2 -0
- package/dist/components/core/molecules/CalendarGrid.d.ts +9 -1
- package/dist/components/core/molecules/GraphCanvas.d.ts +4 -0
- package/dist/components/core/molecules/PositionedCanvas.d.ts +14 -1
- package/dist/components/core/molecules/ReplyTree.d.ts +13 -1
- package/dist/components/core/templates/index.d.ts +4 -0
- package/dist/components/game/molecules/CardHand.d.ts +35 -0
- package/dist/components/game/molecules/DialogueBox.d.ts +8 -2
- package/dist/components/game/molecules/index.d.ts +1 -0
- package/dist/components/game/molecules/three/index.cjs +283 -115
- package/dist/components/game/molecules/three/index.js +283 -115
- package/dist/components/game/organisms/CardBattlerBoard.d.ts +46 -0
- package/dist/components/game/organisms/CityBuilderBoard.d.ts +63 -0
- package/dist/components/game/organisms/TopDownShooterBoard.d.ts +64 -0
- package/dist/components/game/organisms/TowerDefenseBoard.d.ts +10 -1
- package/dist/components/game/organisms/TraitSlot.d.ts +1 -3
- package/dist/components/game/organisms/VisualNovelBoard.d.ts +53 -0
- package/dist/components/game/organisms/hooks/useCamera.d.ts +16 -0
- package/dist/components/game/organisms/index.d.ts +4 -0
- package/dist/components/game/templates/CardBattlerTemplate.d.ts +35 -0
- package/dist/components/game/templates/CityBuilderTemplate.d.ts +40 -0
- package/dist/components/game/templates/GameCanvas3DBattleTemplate.d.ts +5 -2
- package/dist/components/game/templates/GameCanvas3DCastleTemplate.d.ts +5 -2
- package/dist/components/game/templates/GameCanvas3DWorldMapTemplate.d.ts +5 -2
- package/dist/components/game/templates/TopDownShooterTemplate.d.ts +42 -0
- package/dist/components/game/templates/VisualNovelTemplate.d.ts +28 -0
- package/dist/components/game/templates/game3dAssetManifest.d.ts +50 -0
- package/dist/components/game/templates/index.d.ts +4 -0
- package/dist/components/index.cjs +3465 -1659
- package/dist/components/index.js +2444 -647
- package/dist/components/marketing/organisms/CaseStudyOrganism.d.ts +10 -1
- package/dist/components/marketing/organisms/FeatureGridOrganism.d.ts +10 -1
- package/dist/components/marketing/organisms/HeroOrganism.d.ts +24 -1
- package/dist/components/marketing/organisms/PricingOrganism.d.ts +14 -1
- package/dist/components/marketing/organisms/ShowcaseOrganism.d.ts +14 -1
- package/dist/components/marketing/organisms/StatsOrganism.d.ts +6 -1
- package/dist/components/marketing/organisms/StepFlowOrganism.d.ts +9 -1
- package/dist/components/marketing/organisms/TeamOrganism.d.ts +10 -1
- package/dist/docs/index.cjs +169 -1
- package/dist/docs/index.d.cts +2 -0
- package/dist/docs/index.js +169 -1
- package/dist/hooks/index.cjs +253 -1
- package/dist/hooks/index.d.ts +2 -0
- package/dist/hooks/index.js +252 -2
- package/dist/hooks/useCanvasGestures.d.ts +44 -0
- package/dist/hooks/useTapReveal.d.ts +32 -0
- package/dist/locales/index.cjs +315 -3
- package/dist/locales/index.js +315 -3
- package/dist/marketing/index.cjs +59 -0
- package/dist/marketing/index.d.cts +2 -0
- package/dist/marketing/index.js +59 -0
- package/dist/providers/index.cjs +3408 -1619
- package/dist/providers/index.js +2407 -618
- package/dist/runtime/index.cjs +3464 -1675
- package/dist/runtime/index.js +2411 -622
- package/locales/ar.json +105 -1
- package/locales/en.json +105 -1
- package/locales/sl.json +105 -1
- package/package.json +2 -2
package/dist/providers/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import * as
|
|
2
|
-
import
|
|
1
|
+
import * as React85 from 'react';
|
|
2
|
+
import React85__default, { createContext, useContext, useMemo, useRef, useEffect, useCallback, Suspense, useState, useLayoutEffect, lazy, useId, useSyncExternalStore, forwardRef, useImperativeHandle, Component } from 'react';
|
|
3
3
|
import { EventBusContext, useTraitScope, TraitScopeProvider } from '@almadar/ui/providers';
|
|
4
4
|
import { createLogger, isLogLevelEnabled } from '@almadar/logger';
|
|
5
5
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
@@ -246,12 +246,60 @@ var init_cn = __esm({
|
|
|
246
246
|
"lib/cn.ts"() {
|
|
247
247
|
}
|
|
248
248
|
});
|
|
249
|
+
function useTapReveal(options = {}) {
|
|
250
|
+
const { onReveal, onDismiss, refs, enabled = true } = options;
|
|
251
|
+
const [revealed, setRevealed] = useState(false);
|
|
252
|
+
const onRevealRef = useRef(onReveal);
|
|
253
|
+
const onDismissRef = useRef(onDismiss);
|
|
254
|
+
onRevealRef.current = onReveal;
|
|
255
|
+
onDismissRef.current = onDismiss;
|
|
256
|
+
const reveal = useCallback(() => {
|
|
257
|
+
setRevealed((wasRevealed) => {
|
|
258
|
+
if (!wasRevealed) onRevealRef.current?.();
|
|
259
|
+
return true;
|
|
260
|
+
});
|
|
261
|
+
}, []);
|
|
262
|
+
const dismiss = useCallback(() => {
|
|
263
|
+
setRevealed((wasRevealed) => {
|
|
264
|
+
if (wasRevealed) onDismissRef.current?.();
|
|
265
|
+
return false;
|
|
266
|
+
});
|
|
267
|
+
}, []);
|
|
268
|
+
const onPointerDown = useCallback(
|
|
269
|
+
(e) => {
|
|
270
|
+
if (!enabled || e.pointerType === "mouse") return;
|
|
271
|
+
if (revealed) dismiss();
|
|
272
|
+
else reveal();
|
|
273
|
+
},
|
|
274
|
+
[enabled, revealed, reveal, dismiss]
|
|
275
|
+
);
|
|
276
|
+
useEffect(() => {
|
|
277
|
+
if (!revealed || typeof document === "undefined") return;
|
|
278
|
+
const onDocDown = (ev) => {
|
|
279
|
+
const target = ev.target;
|
|
280
|
+
if (!(target instanceof Node)) return;
|
|
281
|
+
const inside = (refs ?? []).some((r) => r.current?.contains(target));
|
|
282
|
+
if (!inside) dismiss();
|
|
283
|
+
};
|
|
284
|
+
const id = setTimeout(() => document.addEventListener("pointerdown", onDocDown), 0);
|
|
285
|
+
return () => {
|
|
286
|
+
clearTimeout(id);
|
|
287
|
+
document.removeEventListener("pointerdown", onDocDown);
|
|
288
|
+
};
|
|
289
|
+
}, [revealed, refs, dismiss]);
|
|
290
|
+
return { revealed, triggerProps: { onPointerDown }, reveal, dismiss };
|
|
291
|
+
}
|
|
292
|
+
var init_useTapReveal = __esm({
|
|
293
|
+
"hooks/useTapReveal.ts"() {
|
|
294
|
+
}
|
|
295
|
+
});
|
|
249
296
|
var paddingStyles, paddingXStyles, paddingYStyles, marginStyles, marginXStyles, marginYStyles, bgStyles, roundedStyles, shadowStyles, displayStyles, overflowStyles, positionStyles, Box;
|
|
250
297
|
var init_Box = __esm({
|
|
251
298
|
"components/core/atoms/Box.tsx"() {
|
|
252
299
|
"use client";
|
|
253
300
|
init_cn();
|
|
254
301
|
init_useEventBus();
|
|
302
|
+
init_useTapReveal();
|
|
255
303
|
paddingStyles = {
|
|
256
304
|
none: "p-0",
|
|
257
305
|
xs: "p-1",
|
|
@@ -354,7 +402,7 @@ var init_Box = __esm({
|
|
|
354
402
|
fixed: "fixed",
|
|
355
403
|
sticky: "sticky"
|
|
356
404
|
};
|
|
357
|
-
Box =
|
|
405
|
+
Box = React85__default.forwardRef(
|
|
358
406
|
({
|
|
359
407
|
padding,
|
|
360
408
|
paddingX,
|
|
@@ -377,10 +425,12 @@ var init_Box = __esm({
|
|
|
377
425
|
action,
|
|
378
426
|
actionPayload,
|
|
379
427
|
hoverEvent,
|
|
428
|
+
tapReveal = true,
|
|
380
429
|
maxWidth,
|
|
381
430
|
onClick,
|
|
382
431
|
onMouseEnter,
|
|
383
432
|
onMouseLeave,
|
|
433
|
+
onPointerDown,
|
|
384
434
|
...rest
|
|
385
435
|
}, ref) => {
|
|
386
436
|
const eventBus = useEventBus();
|
|
@@ -403,8 +453,21 @@ var init_Box = __esm({
|
|
|
403
453
|
}
|
|
404
454
|
onMouseLeave?.(e);
|
|
405
455
|
}, [hoverEvent, eventBus, onMouseLeave]);
|
|
456
|
+
const { triggerProps } = useTapReveal({
|
|
457
|
+
enabled: tapReveal && !!hoverEvent,
|
|
458
|
+
onReveal: useCallback(() => {
|
|
459
|
+
if (hoverEvent) eventBus.emit(`UI:${hoverEvent}`, { hovered: true });
|
|
460
|
+
}, [hoverEvent, eventBus]),
|
|
461
|
+
onDismiss: useCallback(() => {
|
|
462
|
+
if (hoverEvent) eventBus.emit(`UI:${hoverEvent}`, { hovered: false });
|
|
463
|
+
}, [hoverEvent, eventBus])
|
|
464
|
+
});
|
|
465
|
+
const handlePointerDown = useCallback((e) => {
|
|
466
|
+
if (hoverEvent && tapReveal) triggerProps.onPointerDown(e);
|
|
467
|
+
onPointerDown?.(e);
|
|
468
|
+
}, [hoverEvent, tapReveal, triggerProps, onPointerDown]);
|
|
406
469
|
const isClickable = action || onClick;
|
|
407
|
-
return
|
|
470
|
+
return React85__default.createElement(
|
|
408
471
|
Component2,
|
|
409
472
|
{
|
|
410
473
|
ref,
|
|
@@ -430,6 +493,7 @@ var init_Box = __esm({
|
|
|
430
493
|
onClick: isClickable ? handleClick : void 0,
|
|
431
494
|
onMouseEnter: hoverEvent || onMouseEnter ? handleMouseEnter : void 0,
|
|
432
495
|
onMouseLeave: hoverEvent || onMouseLeave ? handleMouseLeave : void 0,
|
|
496
|
+
onPointerDown: hoverEvent && tapReveal || onPointerDown ? handlePointerDown : void 0,
|
|
433
497
|
style: maxWidth ? { maxWidth, ...rest.style } : rest.style,
|
|
434
498
|
...rest
|
|
435
499
|
},
|
|
@@ -499,7 +563,7 @@ function loadLib(key, importer) {
|
|
|
499
563
|
return p2;
|
|
500
564
|
}
|
|
501
565
|
function lazyFamilyIcon(libKey, importer, pick, fallbackName, family) {
|
|
502
|
-
const Lazy =
|
|
566
|
+
const Lazy = React85__default.lazy(async () => {
|
|
503
567
|
const lib = await loadLib(libKey, importer);
|
|
504
568
|
const Comp = pick(lib);
|
|
505
569
|
if (!Comp) {
|
|
@@ -509,7 +573,7 @@ function lazyFamilyIcon(libKey, importer, pick, fallbackName, family) {
|
|
|
509
573
|
return { default: Comp };
|
|
510
574
|
});
|
|
511
575
|
const Wrapped = (props) => /* @__PURE__ */ jsx(
|
|
512
|
-
|
|
576
|
+
React85__default.Suspense,
|
|
513
577
|
{
|
|
514
578
|
fallback: /* @__PURE__ */ jsx(
|
|
515
579
|
"span",
|
|
@@ -1235,7 +1299,7 @@ var init_Icon = __esm({
|
|
|
1235
1299
|
const directIcon = typeof icon === "string" ? void 0 : icon;
|
|
1236
1300
|
const effectiveName = typeof icon === "string" ? icon : name;
|
|
1237
1301
|
const family = useIconFamily();
|
|
1238
|
-
const RenderedComponent =
|
|
1302
|
+
const RenderedComponent = React85__default.useMemo(() => {
|
|
1239
1303
|
if (directIcon) return null;
|
|
1240
1304
|
return effectiveName ? resolveIconForFamily(effectiveName, family) : null;
|
|
1241
1305
|
}, [directIcon, effectiveName, family]);
|
|
@@ -1294,7 +1358,7 @@ function resolveIconProp(value, sizeClass) {
|
|
|
1294
1358
|
const IconComp = value;
|
|
1295
1359
|
return /* @__PURE__ */ jsx(IconComp, { className: sizeClass });
|
|
1296
1360
|
}
|
|
1297
|
-
if (
|
|
1361
|
+
if (React85__default.isValidElement(value)) {
|
|
1298
1362
|
return value;
|
|
1299
1363
|
}
|
|
1300
1364
|
if (typeof value === "object" && value !== null && "render" in value) {
|
|
@@ -1370,7 +1434,7 @@ var init_Button = __esm({
|
|
|
1370
1434
|
md: "h-icon-default w-icon-default",
|
|
1371
1435
|
lg: "h-icon-default w-icon-default"
|
|
1372
1436
|
};
|
|
1373
|
-
Button =
|
|
1437
|
+
Button = React85__default.forwardRef(
|
|
1374
1438
|
({
|
|
1375
1439
|
className,
|
|
1376
1440
|
variant = "primary",
|
|
@@ -1435,7 +1499,7 @@ var Dialog;
|
|
|
1435
1499
|
var init_Dialog = __esm({
|
|
1436
1500
|
"components/core/atoms/Dialog.tsx"() {
|
|
1437
1501
|
init_cn();
|
|
1438
|
-
Dialog =
|
|
1502
|
+
Dialog = React85__default.forwardRef(
|
|
1439
1503
|
({
|
|
1440
1504
|
role = "dialog",
|
|
1441
1505
|
"aria-modal": ariaModal = true,
|
|
@@ -2049,7 +2113,7 @@ var init_Badge = __esm({
|
|
|
2049
2113
|
md: "px-2.5 py-1 text-sm",
|
|
2050
2114
|
lg: "px-3 py-1.5 text-base"
|
|
2051
2115
|
};
|
|
2052
|
-
Badge =
|
|
2116
|
+
Badge = React85__default.forwardRef(
|
|
2053
2117
|
({ className, variant = "default", size = "sm", amount, label, icon, children, onRemove, removeLabel, ...props }, ref) => {
|
|
2054
2118
|
const iconSizes3 = {
|
|
2055
2119
|
sm: "h-icon-default w-icon-default",
|
|
@@ -2385,7 +2449,7 @@ var init_SvgFlow = __esm({
|
|
|
2385
2449
|
width = 100,
|
|
2386
2450
|
height = 100
|
|
2387
2451
|
}) => {
|
|
2388
|
-
const markerId =
|
|
2452
|
+
const markerId = React85__default.useMemo(() => {
|
|
2389
2453
|
flowIdCounter += 1;
|
|
2390
2454
|
return `almadar-flow-arrow-${flowIdCounter}`;
|
|
2391
2455
|
}, []);
|
|
@@ -2978,7 +3042,7 @@ var init_SvgRing = __esm({
|
|
|
2978
3042
|
width = 100,
|
|
2979
3043
|
height = 100
|
|
2980
3044
|
}) => {
|
|
2981
|
-
const gradientId =
|
|
3045
|
+
const gradientId = React85__default.useMemo(() => {
|
|
2982
3046
|
ringIdCounter += 1;
|
|
2983
3047
|
return `almadar-ring-glow-${ringIdCounter}`;
|
|
2984
3048
|
}, []);
|
|
@@ -3159,7 +3223,7 @@ var init_Input = __esm({
|
|
|
3159
3223
|
init_cn();
|
|
3160
3224
|
init_Icon();
|
|
3161
3225
|
init_useEventBus();
|
|
3162
|
-
Input =
|
|
3226
|
+
Input = React85__default.forwardRef(
|
|
3163
3227
|
({
|
|
3164
3228
|
className,
|
|
3165
3229
|
inputType,
|
|
@@ -3319,7 +3383,7 @@ var Label;
|
|
|
3319
3383
|
var init_Label = __esm({
|
|
3320
3384
|
"components/core/atoms/Label.tsx"() {
|
|
3321
3385
|
init_cn();
|
|
3322
|
-
Label =
|
|
3386
|
+
Label = React85__default.forwardRef(
|
|
3323
3387
|
({ className, required, children, ...props }, ref) => {
|
|
3324
3388
|
return /* @__PURE__ */ jsxs(
|
|
3325
3389
|
"label",
|
|
@@ -3346,7 +3410,7 @@ var init_Textarea = __esm({
|
|
|
3346
3410
|
"components/core/atoms/Textarea.tsx"() {
|
|
3347
3411
|
init_cn();
|
|
3348
3412
|
init_useEventBus();
|
|
3349
|
-
Textarea =
|
|
3413
|
+
Textarea = React85__default.forwardRef(
|
|
3350
3414
|
({ className, error, onChange, ...props }, ref) => {
|
|
3351
3415
|
const eventBus = useEventBus();
|
|
3352
3416
|
const handleChange = (e) => {
|
|
@@ -3585,7 +3649,7 @@ var init_Select = __esm({
|
|
|
3585
3649
|
init_cn();
|
|
3586
3650
|
init_Icon();
|
|
3587
3651
|
init_useEventBus();
|
|
3588
|
-
Select =
|
|
3652
|
+
Select = React85__default.forwardRef(
|
|
3589
3653
|
(props, _ref) => {
|
|
3590
3654
|
const { multiple, searchable, clearable } = props;
|
|
3591
3655
|
if (multiple || searchable || clearable) {
|
|
@@ -3602,7 +3666,7 @@ var init_Checkbox = __esm({
|
|
|
3602
3666
|
"components/core/atoms/Checkbox.tsx"() {
|
|
3603
3667
|
init_cn();
|
|
3604
3668
|
init_useEventBus();
|
|
3605
|
-
Checkbox =
|
|
3669
|
+
Checkbox = React85__default.forwardRef(
|
|
3606
3670
|
({ className, label, id, onChange, ...props }, ref) => {
|
|
3607
3671
|
const inputId = id || `checkbox-${Math.random().toString(36).substr(2, 9)}`;
|
|
3608
3672
|
const eventBus = useEventBus();
|
|
@@ -3656,7 +3720,7 @@ var init_Spinner = __esm({
|
|
|
3656
3720
|
md: "h-6 w-6",
|
|
3657
3721
|
lg: "h-8 w-8"
|
|
3658
3722
|
};
|
|
3659
|
-
Spinner =
|
|
3723
|
+
Spinner = React85__default.forwardRef(
|
|
3660
3724
|
({ className, size = "md", overlay, ...props }, ref) => {
|
|
3661
3725
|
if (overlay) {
|
|
3662
3726
|
return /* @__PURE__ */ jsx(
|
|
@@ -3746,7 +3810,7 @@ var init_Card = __esm({
|
|
|
3746
3810
|
chip: "shadow-none rounded-pill border-[length:var(--border-width)] border-border",
|
|
3747
3811
|
"tile-image-first": "p-0 overflow-hidden"
|
|
3748
3812
|
};
|
|
3749
|
-
Card =
|
|
3813
|
+
Card = React85__default.forwardRef(
|
|
3750
3814
|
({
|
|
3751
3815
|
className,
|
|
3752
3816
|
variant = "bordered",
|
|
@@ -3794,9 +3858,9 @@ var init_Card = __esm({
|
|
|
3794
3858
|
}
|
|
3795
3859
|
);
|
|
3796
3860
|
Card.displayName = "Card";
|
|
3797
|
-
CardHeader =
|
|
3861
|
+
CardHeader = React85__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("mb-4", className), ...props }));
|
|
3798
3862
|
CardHeader.displayName = "CardHeader";
|
|
3799
|
-
CardTitle =
|
|
3863
|
+
CardTitle = React85__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
3800
3864
|
"h3",
|
|
3801
3865
|
{
|
|
3802
3866
|
ref,
|
|
@@ -3809,11 +3873,11 @@ var init_Card = __esm({
|
|
|
3809
3873
|
}
|
|
3810
3874
|
));
|
|
3811
3875
|
CardTitle.displayName = "CardTitle";
|
|
3812
|
-
CardContent =
|
|
3876
|
+
CardContent = React85__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("", className), ...props }));
|
|
3813
3877
|
CardContent.displayName = "CardContent";
|
|
3814
3878
|
CardBody = CardContent;
|
|
3815
3879
|
CardBody.displayName = "CardBody";
|
|
3816
|
-
CardFooter =
|
|
3880
|
+
CardFooter = React85__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
3817
3881
|
"div",
|
|
3818
3882
|
{
|
|
3819
3883
|
ref,
|
|
@@ -3868,7 +3932,7 @@ var init_FilterPill = __esm({
|
|
|
3868
3932
|
md: "w-3.5 h-3.5",
|
|
3869
3933
|
lg: "w-4 h-4"
|
|
3870
3934
|
};
|
|
3871
|
-
FilterPill =
|
|
3935
|
+
FilterPill = React85__default.forwardRef(
|
|
3872
3936
|
({
|
|
3873
3937
|
className,
|
|
3874
3938
|
variant = "default",
|
|
@@ -3997,8 +4061,8 @@ var init_Avatar = __esm({
|
|
|
3997
4061
|
actionPayload
|
|
3998
4062
|
}) => {
|
|
3999
4063
|
const eventBus = useEventBus();
|
|
4000
|
-
const [imgFailed, setImgFailed] =
|
|
4001
|
-
|
|
4064
|
+
const [imgFailed, setImgFailed] = React85__default.useState(false);
|
|
4065
|
+
React85__default.useEffect(() => {
|
|
4002
4066
|
setImgFailed(false);
|
|
4003
4067
|
}, [src]);
|
|
4004
4068
|
const initials = providedInitials ?? (name ? generateInitials(name) : void 0);
|
|
@@ -4383,7 +4447,7 @@ var init_Radio = __esm({
|
|
|
4383
4447
|
md: "w-2.5 h-2.5",
|
|
4384
4448
|
lg: "w-3 h-3"
|
|
4385
4449
|
};
|
|
4386
|
-
Radio =
|
|
4450
|
+
Radio = React85__default.forwardRef(
|
|
4387
4451
|
({
|
|
4388
4452
|
label,
|
|
4389
4453
|
helperText,
|
|
@@ -4400,12 +4464,12 @@ var init_Radio = __esm({
|
|
|
4400
4464
|
onChange,
|
|
4401
4465
|
...props
|
|
4402
4466
|
}, ref) => {
|
|
4403
|
-
const reactId =
|
|
4467
|
+
const reactId = React85__default.useId();
|
|
4404
4468
|
const baseId = id || `radio-${reactId}`;
|
|
4405
4469
|
const hasError = !!error;
|
|
4406
4470
|
const eventBus = useEventBus();
|
|
4407
|
-
const [selected, setSelected] =
|
|
4408
|
-
|
|
4471
|
+
const [selected, setSelected] = React85__default.useState(value);
|
|
4472
|
+
React85__default.useEffect(() => {
|
|
4409
4473
|
if (value !== void 0) setSelected(value);
|
|
4410
4474
|
}, [value]);
|
|
4411
4475
|
const pick = (next, e) => {
|
|
@@ -4587,7 +4651,7 @@ var init_Switch = __esm({
|
|
|
4587
4651
|
"components/core/atoms/Switch.tsx"() {
|
|
4588
4652
|
"use client";
|
|
4589
4653
|
init_cn();
|
|
4590
|
-
Switch =
|
|
4654
|
+
Switch = React85.forwardRef(
|
|
4591
4655
|
({
|
|
4592
4656
|
checked,
|
|
4593
4657
|
defaultChecked = false,
|
|
@@ -4598,10 +4662,10 @@ var init_Switch = __esm({
|
|
|
4598
4662
|
name,
|
|
4599
4663
|
className
|
|
4600
4664
|
}, ref) => {
|
|
4601
|
-
const [isChecked, setIsChecked] =
|
|
4665
|
+
const [isChecked, setIsChecked] = React85.useState(
|
|
4602
4666
|
checked !== void 0 ? checked : defaultChecked
|
|
4603
4667
|
);
|
|
4604
|
-
|
|
4668
|
+
React85.useEffect(() => {
|
|
4605
4669
|
if (checked !== void 0) {
|
|
4606
4670
|
setIsChecked(checked);
|
|
4607
4671
|
}
|
|
@@ -4840,6 +4904,11 @@ var init_TextHighlight = __esm({
|
|
|
4840
4904
|
if (hoverEvent) eventBus.emit(`UI:${hoverEvent}`, { hovered: false, annotationId });
|
|
4841
4905
|
onMouseLeave?.();
|
|
4842
4906
|
},
|
|
4907
|
+
onPointerDown: (e) => {
|
|
4908
|
+
if (e.pointerType === "mouse") return;
|
|
4909
|
+
if (hoverEvent) eventBus.emit(`UI:${hoverEvent}`, { hovered: true, annotationId });
|
|
4910
|
+
onMouseEnter?.();
|
|
4911
|
+
},
|
|
4843
4912
|
role: "button",
|
|
4844
4913
|
tabIndex: 0,
|
|
4845
4914
|
onKeyDown: (e) => {
|
|
@@ -4956,7 +5025,7 @@ var Aside;
|
|
|
4956
5025
|
var init_Aside = __esm({
|
|
4957
5026
|
"components/core/atoms/Aside.tsx"() {
|
|
4958
5027
|
init_cn();
|
|
4959
|
-
Aside =
|
|
5028
|
+
Aside = React85__default.forwardRef(
|
|
4960
5029
|
({ className, children, ...rest }, ref) => /* @__PURE__ */ jsx("aside", { ref, className: cn(className), ...rest, children })
|
|
4961
5030
|
);
|
|
4962
5031
|
Aside.displayName = "Aside";
|
|
@@ -5015,6 +5084,7 @@ var init_LawReferenceTooltip = __esm({
|
|
|
5015
5084
|
init_Typography();
|
|
5016
5085
|
init_Divider();
|
|
5017
5086
|
init_cn();
|
|
5087
|
+
init_useTapReveal();
|
|
5018
5088
|
positionStyles2 = {
|
|
5019
5089
|
top: "bottom-full left-1/2 -translate-x-1/2 mb-2",
|
|
5020
5090
|
bottom: "top-full left-1/2 -translate-x-1/2 mt-2",
|
|
@@ -5034,8 +5104,9 @@ var init_LawReferenceTooltip = __esm({
|
|
|
5034
5104
|
className
|
|
5035
5105
|
}) => {
|
|
5036
5106
|
const { t } = useTranslate();
|
|
5037
|
-
const [isVisible, setIsVisible] =
|
|
5038
|
-
const timeoutRef =
|
|
5107
|
+
const [isVisible, setIsVisible] = React85__default.useState(false);
|
|
5108
|
+
const timeoutRef = React85__default.useRef(null);
|
|
5109
|
+
const triggerRef = React85__default.useRef(null);
|
|
5039
5110
|
const handleMouseEnter = () => {
|
|
5040
5111
|
if (timeoutRef.current) clearTimeout(timeoutRef.current);
|
|
5041
5112
|
timeoutRef.current = setTimeout(() => setIsVisible(true), 200);
|
|
@@ -5044,7 +5115,9 @@ var init_LawReferenceTooltip = __esm({
|
|
|
5044
5115
|
if (timeoutRef.current) clearTimeout(timeoutRef.current);
|
|
5045
5116
|
setIsVisible(false);
|
|
5046
5117
|
};
|
|
5047
|
-
|
|
5118
|
+
const { revealed, triggerProps } = useTapReveal({ refs: [triggerRef] });
|
|
5119
|
+
const open = isVisible || revealed;
|
|
5120
|
+
React85__default.useEffect(() => {
|
|
5048
5121
|
return () => {
|
|
5049
5122
|
if (timeoutRef.current) clearTimeout(timeoutRef.current);
|
|
5050
5123
|
};
|
|
@@ -5052,6 +5125,7 @@ var init_LawReferenceTooltip = __esm({
|
|
|
5052
5125
|
return /* @__PURE__ */ jsxs(
|
|
5053
5126
|
Box,
|
|
5054
5127
|
{
|
|
5128
|
+
ref: triggerRef,
|
|
5055
5129
|
as: "span",
|
|
5056
5130
|
position: "relative",
|
|
5057
5131
|
display: "inline-block",
|
|
@@ -5060,9 +5134,10 @@ var init_LawReferenceTooltip = __esm({
|
|
|
5060
5134
|
onMouseLeave: handleMouseLeave,
|
|
5061
5135
|
onFocus: handleMouseEnter,
|
|
5062
5136
|
onBlur: handleMouseLeave,
|
|
5137
|
+
onPointerDown: triggerProps.onPointerDown,
|
|
5063
5138
|
children: [
|
|
5064
5139
|
children,
|
|
5065
|
-
|
|
5140
|
+
open && /* @__PURE__ */ jsxs(
|
|
5066
5141
|
Box,
|
|
5067
5142
|
{
|
|
5068
5143
|
padding: "sm",
|
|
@@ -5254,7 +5329,7 @@ var init_StatusDot = __esm({
|
|
|
5254
5329
|
md: "w-2.5 h-2.5",
|
|
5255
5330
|
lg: "w-3 h-3"
|
|
5256
5331
|
};
|
|
5257
|
-
StatusDot =
|
|
5332
|
+
StatusDot = React85__default.forwardRef(
|
|
5258
5333
|
({ className, status = "offline", pulse = false, size = "md", label, ...props }, ref) => {
|
|
5259
5334
|
return /* @__PURE__ */ jsx(
|
|
5260
5335
|
"span",
|
|
@@ -5308,7 +5383,7 @@ var init_TrendIndicator = __esm({
|
|
|
5308
5383
|
down: "trending-down",
|
|
5309
5384
|
flat: "arrow-right"
|
|
5310
5385
|
};
|
|
5311
|
-
TrendIndicator =
|
|
5386
|
+
TrendIndicator = React85__default.forwardRef(
|
|
5312
5387
|
({
|
|
5313
5388
|
className,
|
|
5314
5389
|
value,
|
|
@@ -5375,7 +5450,7 @@ var init_RangeSlider = __esm({
|
|
|
5375
5450
|
md: "w-4 h-4",
|
|
5376
5451
|
lg: "w-5 h-5"
|
|
5377
5452
|
};
|
|
5378
|
-
RangeSlider =
|
|
5453
|
+
RangeSlider = React85__default.forwardRef(
|
|
5379
5454
|
({
|
|
5380
5455
|
className,
|
|
5381
5456
|
min = 0,
|
|
@@ -5883,7 +5958,7 @@ var init_ContentSection = __esm({
|
|
|
5883
5958
|
md: "py-16",
|
|
5884
5959
|
lg: "py-24"
|
|
5885
5960
|
};
|
|
5886
|
-
ContentSection =
|
|
5961
|
+
ContentSection = React85__default.forwardRef(
|
|
5887
5962
|
({ children, background = "default", padding = "lg", id, className }, ref) => {
|
|
5888
5963
|
return /* @__PURE__ */ jsx(
|
|
5889
5964
|
Box,
|
|
@@ -6417,7 +6492,7 @@ var init_AnimatedReveal = __esm({
|
|
|
6417
6492
|
"scale-up": { opacity: 1, transform: "scale(1) translateY(0)" },
|
|
6418
6493
|
"none": {}
|
|
6419
6494
|
};
|
|
6420
|
-
AnimatedReveal =
|
|
6495
|
+
AnimatedReveal = React85__default.forwardRef(
|
|
6421
6496
|
({
|
|
6422
6497
|
trigger = "scroll",
|
|
6423
6498
|
animation = "fade-up",
|
|
@@ -6577,7 +6652,7 @@ var init_AnimatedGraphic = __esm({
|
|
|
6577
6652
|
"components/marketing/atoms/AnimatedGraphic.tsx"() {
|
|
6578
6653
|
"use client";
|
|
6579
6654
|
init_cn();
|
|
6580
|
-
AnimatedGraphic =
|
|
6655
|
+
AnimatedGraphic = React85__default.forwardRef(
|
|
6581
6656
|
({
|
|
6582
6657
|
src,
|
|
6583
6658
|
svgContent,
|
|
@@ -6600,7 +6675,7 @@ var init_AnimatedGraphic = __esm({
|
|
|
6600
6675
|
const fetchedSvg = useFetchedSvg(svgContent ? void 0 : src);
|
|
6601
6676
|
const resolvedSvg = svgContent ?? fetchedSvg;
|
|
6602
6677
|
const prevAnimateRef = useRef(animate);
|
|
6603
|
-
const setRef =
|
|
6678
|
+
const setRef = React85__default.useCallback(
|
|
6604
6679
|
(node) => {
|
|
6605
6680
|
containerRef.current = node;
|
|
6606
6681
|
if (typeof ref === "function") ref(node);
|
|
@@ -6826,9 +6901,9 @@ function ScoreDisplay({
|
|
|
6826
6901
|
...rest
|
|
6827
6902
|
}) {
|
|
6828
6903
|
const resolvedValue = typeof value === "number" && !Number.isNaN(value) ? value : typeof rest.score === "number" && !Number.isNaN(rest.score) ? rest.score : 0;
|
|
6829
|
-
const [displayValue, setDisplayValue] =
|
|
6830
|
-
const [isAnimating, setIsAnimating] =
|
|
6831
|
-
|
|
6904
|
+
const [displayValue, setDisplayValue] = React85.useState(resolvedValue);
|
|
6905
|
+
const [isAnimating, setIsAnimating] = React85.useState(false);
|
|
6906
|
+
React85.useEffect(() => {
|
|
6832
6907
|
if (!animated || displayValue === resolvedValue) {
|
|
6833
6908
|
setDisplayValue(resolvedValue);
|
|
6834
6909
|
return;
|
|
@@ -6911,9 +6986,9 @@ function ControlButton({
|
|
|
6911
6986
|
className
|
|
6912
6987
|
}) {
|
|
6913
6988
|
const eventBus = useEventBus();
|
|
6914
|
-
const [isPressed, setIsPressed] =
|
|
6989
|
+
const [isPressed, setIsPressed] = React85.useState(false);
|
|
6915
6990
|
const actualPressed = pressed ?? isPressed;
|
|
6916
|
-
const handlePointerDown =
|
|
6991
|
+
const handlePointerDown = React85.useCallback(
|
|
6917
6992
|
(e) => {
|
|
6918
6993
|
e.preventDefault();
|
|
6919
6994
|
if (disabled) return;
|
|
@@ -6923,7 +6998,7 @@ function ControlButton({
|
|
|
6923
6998
|
},
|
|
6924
6999
|
[disabled, pressEvent, eventBus, onPress]
|
|
6925
7000
|
);
|
|
6926
|
-
const handlePointerUp =
|
|
7001
|
+
const handlePointerUp = React85.useCallback(
|
|
6927
7002
|
(e) => {
|
|
6928
7003
|
e.preventDefault();
|
|
6929
7004
|
if (disabled) return;
|
|
@@ -6933,7 +7008,7 @@ function ControlButton({
|
|
|
6933
7008
|
},
|
|
6934
7009
|
[disabled, releaseEvent, eventBus, onRelease]
|
|
6935
7010
|
);
|
|
6936
|
-
const handlePointerLeave =
|
|
7011
|
+
const handlePointerLeave = React85.useCallback(
|
|
6937
7012
|
(e) => {
|
|
6938
7013
|
if (isPressed) {
|
|
6939
7014
|
setIsPressed(false);
|
|
@@ -7554,8 +7629,8 @@ function XPBar({
|
|
|
7554
7629
|
}) {
|
|
7555
7630
|
const sizes = sizeMap9[size];
|
|
7556
7631
|
const percentage = max > 0 ? Math.max(0, Math.min(100, current / max * 100)) : 0;
|
|
7557
|
-
const [fillWidth, setFillWidth] =
|
|
7558
|
-
|
|
7632
|
+
const [fillWidth, setFillWidth] = React85.useState(animated ? 0 : percentage);
|
|
7633
|
+
React85.useEffect(() => {
|
|
7559
7634
|
if (!animated) {
|
|
7560
7635
|
setFillWidth(percentage);
|
|
7561
7636
|
return;
|
|
@@ -8043,9 +8118,9 @@ function MiniMap({
|
|
|
8043
8118
|
viewportRect = DEFAULT_VIEWPORT,
|
|
8044
8119
|
className
|
|
8045
8120
|
}) {
|
|
8046
|
-
const canvasRef =
|
|
8047
|
-
const frameRef =
|
|
8048
|
-
|
|
8121
|
+
const canvasRef = React85.useRef(null);
|
|
8122
|
+
const frameRef = React85.useRef(0);
|
|
8123
|
+
React85.useEffect(() => {
|
|
8049
8124
|
const canvas = canvasRef.current;
|
|
8050
8125
|
if (!canvas) return;
|
|
8051
8126
|
const ctx = canvas.getContext("2d");
|
|
@@ -8234,7 +8309,7 @@ var init_ErrorBoundary = __esm({
|
|
|
8234
8309
|
}
|
|
8235
8310
|
);
|
|
8236
8311
|
};
|
|
8237
|
-
ErrorBoundary = class extends
|
|
8312
|
+
ErrorBoundary = class extends React85__default.Component {
|
|
8238
8313
|
constructor(props) {
|
|
8239
8314
|
super(props);
|
|
8240
8315
|
__publicField(this, "reset", () => {
|
|
@@ -9625,8 +9700,8 @@ function ActionButtons({
|
|
|
9625
9700
|
disabled
|
|
9626
9701
|
}) {
|
|
9627
9702
|
const eventBus = useEventBus();
|
|
9628
|
-
const [activeButtons, setActiveButtons] =
|
|
9629
|
-
const handlePress =
|
|
9703
|
+
const [activeButtons, setActiveButtons] = React85.useState(/* @__PURE__ */ new Set());
|
|
9704
|
+
const handlePress = React85.useCallback(
|
|
9630
9705
|
(id) => {
|
|
9631
9706
|
setActiveButtons((prev) => new Set(prev).add(id));
|
|
9632
9707
|
if (actionEvent) eventBus.emit(`UI:${actionEvent}`, { id, pressed: true });
|
|
@@ -9634,7 +9709,7 @@ function ActionButtons({
|
|
|
9634
9709
|
},
|
|
9635
9710
|
[actionEvent, eventBus, onAction]
|
|
9636
9711
|
);
|
|
9637
|
-
const handleRelease =
|
|
9712
|
+
const handleRelease = React85.useCallback(
|
|
9638
9713
|
(id) => {
|
|
9639
9714
|
setActiveButtons((prev) => {
|
|
9640
9715
|
const next = new Set(prev);
|
|
@@ -10271,8 +10346,8 @@ var init_AnimatedCounter = __esm({
|
|
|
10271
10346
|
const [displayValue, setDisplayValue] = useState("0");
|
|
10272
10347
|
const [hasAnimated, setHasAnimated] = useState(false);
|
|
10273
10348
|
const animate = useCallback(() => {
|
|
10274
|
-
const { num:
|
|
10275
|
-
if (
|
|
10349
|
+
const { num: num3, prefix, suffix, decimals } = parseValue(value);
|
|
10350
|
+
if (num3 === 0) {
|
|
10276
10351
|
setDisplayValue(String(value));
|
|
10277
10352
|
return;
|
|
10278
10353
|
}
|
|
@@ -10281,7 +10356,7 @@ var init_AnimatedCounter = __esm({
|
|
|
10281
10356
|
const elapsed = now - startTime;
|
|
10282
10357
|
const progress = Math.min(elapsed / duration, 1);
|
|
10283
10358
|
const eased = 1 - Math.pow(1 - progress, 3);
|
|
10284
|
-
const current = eased *
|
|
10359
|
+
const current = eased * num3;
|
|
10285
10360
|
setDisplayValue(`${prefix}${current.toFixed(decimals)}${suffix}`);
|
|
10286
10361
|
if (progress < 1) {
|
|
10287
10362
|
requestAnimationFrame(tick);
|
|
@@ -10822,6 +10897,36 @@ function useCamera() {
|
|
|
10822
10897
|
cameraRef.current.zoom = Math.max(0.5, Math.min(3, cameraRef.current.zoom * zoomDelta));
|
|
10823
10898
|
drawFn?.();
|
|
10824
10899
|
}, []);
|
|
10900
|
+
const handlePointerDown = useCallback((e) => {
|
|
10901
|
+
handleMouseDown(e);
|
|
10902
|
+
}, [handleMouseDown]);
|
|
10903
|
+
const handlePointerUp = useCallback(() => {
|
|
10904
|
+
handleMouseUp();
|
|
10905
|
+
}, [handleMouseUp]);
|
|
10906
|
+
const handlePointerMove = useCallback((e, drawFn) => {
|
|
10907
|
+
return handleMouseMove(e, drawFn);
|
|
10908
|
+
}, [handleMouseMove]);
|
|
10909
|
+
const panBy = useCallback((dx, dy, drawFn) => {
|
|
10910
|
+
cameraRef.current.x -= dx;
|
|
10911
|
+
cameraRef.current.y -= dy;
|
|
10912
|
+
targetCameraRef.current = null;
|
|
10913
|
+
drawFn?.();
|
|
10914
|
+
}, []);
|
|
10915
|
+
const zoomAtPoint = useCallback((factor, centerX, centerY, viewportSize, drawFn) => {
|
|
10916
|
+
const cam = cameraRef.current;
|
|
10917
|
+
const oldZoom = cam.zoom;
|
|
10918
|
+
const newZoom = Math.max(0.5, Math.min(3, oldZoom * factor));
|
|
10919
|
+
if (newZoom === oldZoom) {
|
|
10920
|
+
drawFn?.();
|
|
10921
|
+
return;
|
|
10922
|
+
}
|
|
10923
|
+
const inv = 1 / oldZoom - 1 / newZoom;
|
|
10924
|
+
cam.x += (centerX - viewportSize.width / 2) * inv;
|
|
10925
|
+
cam.y += (centerY - viewportSize.height / 2) * inv;
|
|
10926
|
+
cam.zoom = newZoom;
|
|
10927
|
+
targetCameraRef.current = null;
|
|
10928
|
+
drawFn?.();
|
|
10929
|
+
}, []);
|
|
10825
10930
|
const screenToWorld = useCallback((clientX, clientY, canvas, viewportSize) => {
|
|
10826
10931
|
const rect = canvas.getBoundingClientRect();
|
|
10827
10932
|
const screenX = clientX - rect.left;
|
|
@@ -10853,6 +10958,11 @@ function useCamera() {
|
|
|
10853
10958
|
handleMouseMove,
|
|
10854
10959
|
handleMouseLeave,
|
|
10855
10960
|
handleWheel,
|
|
10961
|
+
handlePointerDown,
|
|
10962
|
+
handlePointerUp,
|
|
10963
|
+
handlePointerMove,
|
|
10964
|
+
panBy,
|
|
10965
|
+
zoomAtPoint,
|
|
10856
10966
|
screenToWorld,
|
|
10857
10967
|
lerpToTarget
|
|
10858
10968
|
};
|
|
@@ -10862,6 +10972,113 @@ var init_useCamera = __esm({
|
|
|
10862
10972
|
"use client";
|
|
10863
10973
|
}
|
|
10864
10974
|
});
|
|
10975
|
+
function localPoint(canvas, clientX, clientY) {
|
|
10976
|
+
if (!canvas) return { x: clientX, y: clientY };
|
|
10977
|
+
const rect = canvas.getBoundingClientRect();
|
|
10978
|
+
return { x: clientX - rect.left, y: clientY - rect.top };
|
|
10979
|
+
}
|
|
10980
|
+
function useCanvasGestures(options) {
|
|
10981
|
+
const {
|
|
10982
|
+
canvasRef,
|
|
10983
|
+
enabled = true,
|
|
10984
|
+
wheelStep = 1.1,
|
|
10985
|
+
onPointerDown,
|
|
10986
|
+
onPointerMove,
|
|
10987
|
+
onPointerUp,
|
|
10988
|
+
onZoom,
|
|
10989
|
+
onPanDelta,
|
|
10990
|
+
onMultiTouchStart
|
|
10991
|
+
} = options;
|
|
10992
|
+
const pointers = useRef(/* @__PURE__ */ new Map());
|
|
10993
|
+
const pinch = useRef(null);
|
|
10994
|
+
const computePinch = useCallback(() => {
|
|
10995
|
+
const pts = [...pointers.current.values()];
|
|
10996
|
+
const dx = pts[1].x - pts[0].x;
|
|
10997
|
+
const dy = pts[1].y - pts[0].y;
|
|
10998
|
+
return {
|
|
10999
|
+
distance: Math.hypot(dx, dy) || 1,
|
|
11000
|
+
centroid: { x: (pts[0].x + pts[1].x) / 2, y: (pts[0].y + pts[1].y) / 2 }
|
|
11001
|
+
};
|
|
11002
|
+
}, []);
|
|
11003
|
+
const handlePointerDown = useCallback(
|
|
11004
|
+
(e) => {
|
|
11005
|
+
if (!enabled) return;
|
|
11006
|
+
e.currentTarget.setPointerCapture(e.pointerId);
|
|
11007
|
+
pointers.current.set(e.pointerId, localPoint(canvasRef.current, e.clientX, e.clientY));
|
|
11008
|
+
if (pointers.current.size === 2) {
|
|
11009
|
+
onMultiTouchStart?.();
|
|
11010
|
+
pinch.current = computePinch();
|
|
11011
|
+
} else if (pointers.current.size === 1) {
|
|
11012
|
+
onPointerDown?.(e);
|
|
11013
|
+
}
|
|
11014
|
+
},
|
|
11015
|
+
[enabled, canvasRef, onMultiTouchStart, computePinch, onPointerDown]
|
|
11016
|
+
);
|
|
11017
|
+
const handlePointerMove = useCallback(
|
|
11018
|
+
(e) => {
|
|
11019
|
+
if (!enabled) return;
|
|
11020
|
+
if (pointers.current.has(e.pointerId)) {
|
|
11021
|
+
pointers.current.set(e.pointerId, localPoint(canvasRef.current, e.clientX, e.clientY));
|
|
11022
|
+
}
|
|
11023
|
+
if (pointers.current.size >= 2 && pinch.current) {
|
|
11024
|
+
const next = computePinch();
|
|
11025
|
+
const prev = pinch.current;
|
|
11026
|
+
if (next.distance !== prev.distance) {
|
|
11027
|
+
onZoom?.(next.distance / prev.distance, next.centroid.x, next.centroid.y);
|
|
11028
|
+
}
|
|
11029
|
+
onPanDelta?.(next.centroid.x - prev.centroid.x, next.centroid.y - prev.centroid.y);
|
|
11030
|
+
pinch.current = next;
|
|
11031
|
+
return;
|
|
11032
|
+
}
|
|
11033
|
+
onPointerMove?.(e);
|
|
11034
|
+
},
|
|
11035
|
+
[enabled, canvasRef, computePinch, onZoom, onPanDelta, onPointerMove]
|
|
11036
|
+
);
|
|
11037
|
+
const endPointer = useCallback(
|
|
11038
|
+
(e, fireUp) => {
|
|
11039
|
+
const wasMulti = pointers.current.size >= 2;
|
|
11040
|
+
pointers.current.delete(e.pointerId);
|
|
11041
|
+
if (pointers.current.size < 2) pinch.current = null;
|
|
11042
|
+
if (wasMulti && pointers.current.size === 1) return;
|
|
11043
|
+
if (pointers.current.size === 0 && fireUp) onPointerUp?.(e);
|
|
11044
|
+
},
|
|
11045
|
+
[onPointerUp]
|
|
11046
|
+
);
|
|
11047
|
+
const handlePointerUp = useCallback(
|
|
11048
|
+
(e) => {
|
|
11049
|
+
if (!enabled) return;
|
|
11050
|
+
endPointer(e, true);
|
|
11051
|
+
},
|
|
11052
|
+
[enabled, endPointer]
|
|
11053
|
+
);
|
|
11054
|
+
const handlePointerCancel = useCallback(
|
|
11055
|
+
(e) => {
|
|
11056
|
+
if (!enabled) return;
|
|
11057
|
+
endPointer(e, false);
|
|
11058
|
+
},
|
|
11059
|
+
[enabled, endPointer]
|
|
11060
|
+
);
|
|
11061
|
+
const handleWheel = useCallback(
|
|
11062
|
+
(e) => {
|
|
11063
|
+
if (!enabled) return;
|
|
11064
|
+
e.preventDefault();
|
|
11065
|
+
const { x, y } = localPoint(canvasRef.current, e.clientX, e.clientY);
|
|
11066
|
+
onZoom?.(e.deltaY < 0 ? wheelStep : 1 / wheelStep, x, y);
|
|
11067
|
+
},
|
|
11068
|
+
[enabled, canvasRef, wheelStep, onZoom]
|
|
11069
|
+
);
|
|
11070
|
+
return {
|
|
11071
|
+
onPointerDown: handlePointerDown,
|
|
11072
|
+
onPointerMove: handlePointerMove,
|
|
11073
|
+
onPointerUp: handlePointerUp,
|
|
11074
|
+
onPointerCancel: handlePointerCancel,
|
|
11075
|
+
onWheel: handleWheel
|
|
11076
|
+
};
|
|
11077
|
+
}
|
|
11078
|
+
var init_useCanvasGestures = __esm({
|
|
11079
|
+
"hooks/useCanvasGestures.ts"() {
|
|
11080
|
+
}
|
|
11081
|
+
});
|
|
10865
11082
|
function unitAtlasUrl(unit) {
|
|
10866
11083
|
if (unit.spriteSheet) return unit.spriteSheet;
|
|
10867
11084
|
const sprite = unit.sprite;
|
|
@@ -11099,7 +11316,7 @@ function IsometricCanvas({
|
|
|
11099
11316
|
// Tuning
|
|
11100
11317
|
diamondTopY: diamondTopYProp,
|
|
11101
11318
|
// Remote asset loading
|
|
11102
|
-
assetBaseUrl
|
|
11319
|
+
assetBaseUrl,
|
|
11103
11320
|
assetManifest
|
|
11104
11321
|
}) {
|
|
11105
11322
|
const tilesProp = Array.isArray(_tilesPropRaw) ? _tilesPropRaw : [];
|
|
@@ -11178,7 +11395,7 @@ function IsometricCanvas({
|
|
|
11178
11395
|
const attackTargetSet = useMemo(() => {
|
|
11179
11396
|
return new Set(attackTargets.map((p2) => `${p2.x},${p2.y}`));
|
|
11180
11397
|
}, [attackTargets]);
|
|
11181
|
-
const
|
|
11398
|
+
const resolveManifestUrl7 = useCallback((relativePath) => {
|
|
11182
11399
|
if (!relativePath) return void 0;
|
|
11183
11400
|
if (assetBaseUrl) return `${assetBaseUrl.replace(/\/$/, "")}${relativePath.startsWith("/") ? "" : "/"}${relativePath}`;
|
|
11184
11401
|
return relativePath;
|
|
@@ -11191,7 +11408,7 @@ function IsometricCanvas({
|
|
|
11191
11408
|
const url = getTerrainSprite(tile.terrain ?? "");
|
|
11192
11409
|
if (url) urls.push(url);
|
|
11193
11410
|
} else {
|
|
11194
|
-
const url =
|
|
11411
|
+
const url = resolveManifestUrl7(assetManifest?.terrains?.[tile.terrain ?? ""]);
|
|
11195
11412
|
if (url) urls.push(url);
|
|
11196
11413
|
}
|
|
11197
11414
|
}
|
|
@@ -11201,7 +11418,7 @@ function IsometricCanvas({
|
|
|
11201
11418
|
const url = getFeatureSprite(feature.type);
|
|
11202
11419
|
if (url) urls.push(url);
|
|
11203
11420
|
} else {
|
|
11204
|
-
const url =
|
|
11421
|
+
const url = resolveManifestUrl7(assetManifest?.features?.[feature.type]);
|
|
11205
11422
|
if (url) urls.push(url);
|
|
11206
11423
|
}
|
|
11207
11424
|
}
|
|
@@ -11211,13 +11428,13 @@ function IsometricCanvas({
|
|
|
11211
11428
|
const url = getUnitSprite(unit);
|
|
11212
11429
|
if (url) urls.push(url);
|
|
11213
11430
|
} else if (unit.unitType) {
|
|
11214
|
-
const url =
|
|
11431
|
+
const url = resolveManifestUrl7(assetManifest?.units?.[unit.unitType]);
|
|
11215
11432
|
if (url) urls.push(url);
|
|
11216
11433
|
}
|
|
11217
11434
|
}
|
|
11218
11435
|
if (assetManifest?.effects) {
|
|
11219
11436
|
for (const path of Object.values(assetManifest.effects)) {
|
|
11220
|
-
const url =
|
|
11437
|
+
const url = resolveManifestUrl7(path);
|
|
11221
11438
|
if (url) urls.push(url);
|
|
11222
11439
|
}
|
|
11223
11440
|
}
|
|
@@ -11225,7 +11442,7 @@ function IsometricCanvas({
|
|
|
11225
11442
|
if (atlasSheetUrls.length) urls.push(...atlasSheetUrls);
|
|
11226
11443
|
if (backgroundImage) urls.push(backgroundImage);
|
|
11227
11444
|
return [...new Set(urls.filter(Boolean))];
|
|
11228
|
-
}, [sortedTiles, features, units, getTerrainSprite, getFeatureSprite, getUnitSprite, effectSpriteUrls, atlasSheetUrls, backgroundImage, assetManifest,
|
|
11445
|
+
}, [sortedTiles, features, units, getTerrainSprite, getFeatureSprite, getUnitSprite, effectSpriteUrls, atlasSheetUrls, backgroundImage, assetManifest, resolveManifestUrl7]);
|
|
11229
11446
|
const { getImage, pendingCount } = useImageCache(spriteUrls);
|
|
11230
11447
|
useEffect(() => {
|
|
11231
11448
|
if (typeof window === "undefined") return;
|
|
@@ -11240,23 +11457,24 @@ function IsometricCanvas({
|
|
|
11240
11457
|
cameraRef,
|
|
11241
11458
|
targetCameraRef,
|
|
11242
11459
|
dragDistance,
|
|
11243
|
-
handleMouseDown,
|
|
11244
|
-
handleMouseUp,
|
|
11245
|
-
handleMouseMove,
|
|
11246
11460
|
handleMouseLeave,
|
|
11247
|
-
|
|
11461
|
+
handlePointerDown,
|
|
11462
|
+
handlePointerUp,
|
|
11463
|
+
handlePointerMove,
|
|
11464
|
+
panBy,
|
|
11465
|
+
zoomAtPoint,
|
|
11248
11466
|
screenToWorld,
|
|
11249
11467
|
lerpToTarget
|
|
11250
11468
|
} = useCamera();
|
|
11251
11469
|
const resolveTerrainSpriteUrl = useCallback((tile) => {
|
|
11252
|
-
return tile.terrainSprite || getTerrainSprite?.(tile.terrain ?? "") ||
|
|
11253
|
-
}, [getTerrainSprite, assetManifest,
|
|
11470
|
+
return tile.terrainSprite || getTerrainSprite?.(tile.terrain ?? "") || resolveManifestUrl7(assetManifest?.terrains?.[tile.terrain ?? ""]);
|
|
11471
|
+
}, [getTerrainSprite, assetManifest, resolveManifestUrl7]);
|
|
11254
11472
|
const resolveFeatureSpriteUrl = useCallback((featureType) => {
|
|
11255
|
-
return getFeatureSprite?.(featureType) ||
|
|
11256
|
-
}, [getFeatureSprite, assetManifest,
|
|
11473
|
+
return getFeatureSprite?.(featureType) || resolveManifestUrl7(assetManifest?.features?.[featureType]);
|
|
11474
|
+
}, [getFeatureSprite, assetManifest, resolveManifestUrl7]);
|
|
11257
11475
|
const resolveUnitSpriteUrl = useCallback((unit) => {
|
|
11258
|
-
return unit.sprite || getUnitSprite?.(unit) || (unit.unitType ?
|
|
11259
|
-
}, [getUnitSprite, assetManifest,
|
|
11476
|
+
return unit.sprite || getUnitSprite?.(unit) || (unit.unitType ? resolveManifestUrl7(assetManifest?.units?.[unit.unitType]) : void 0);
|
|
11477
|
+
}, [getUnitSprite, assetManifest, resolveManifestUrl7]);
|
|
11260
11478
|
const drawMinimap = useCallback(() => {
|
|
11261
11479
|
if (!showMinimap) return;
|
|
11262
11480
|
const miniCanvas = minimapRef.current;
|
|
@@ -11358,7 +11576,15 @@ function IsometricCanvas({
|
|
|
11358
11576
|
const spriteUrl = resolveTerrainSpriteUrl(tile);
|
|
11359
11577
|
const img = spriteUrl ? getImage(spriteUrl) : null;
|
|
11360
11578
|
if (img) {
|
|
11361
|
-
|
|
11579
|
+
if (img.naturalWidth === 0) {
|
|
11580
|
+
ctx.drawImage(img, pos.x, pos.y, scaledTileWidth, scaledTileHeight);
|
|
11581
|
+
} else {
|
|
11582
|
+
const drawW = scaledTileWidth;
|
|
11583
|
+
const drawH = scaledTileWidth * (img.naturalHeight / img.naturalWidth);
|
|
11584
|
+
const drawX = pos.x;
|
|
11585
|
+
const drawY = pos.y + scaledTileHeight - drawH;
|
|
11586
|
+
ctx.drawImage(img, drawX, drawY, drawW, drawH);
|
|
11587
|
+
}
|
|
11362
11588
|
} else {
|
|
11363
11589
|
const centerX = pos.x + scaledTileWidth / 2;
|
|
11364
11590
|
const topY = pos.y + scaledDiamondTopY;
|
|
@@ -11671,11 +11897,16 @@ function IsometricCanvas({
|
|
|
11671
11897
|
cancelAnimationFrame(rafIdRef.current);
|
|
11672
11898
|
};
|
|
11673
11899
|
}, [draw, units.length, validMoves.length, attackTargets.length, selectedUnitId, hasActiveEffects2, pendingCount, atlasPending, lerpToTarget, targetCameraRef]);
|
|
11674
|
-
const
|
|
11675
|
-
|
|
11676
|
-
|
|
11677
|
-
|
|
11678
|
-
|
|
11900
|
+
const singlePointerActiveRef = useRef(false);
|
|
11901
|
+
const handleCanvasPointerDown = useCallback((e) => {
|
|
11902
|
+
singlePointerActiveRef.current = true;
|
|
11903
|
+
if (enableCamera) handlePointerDown(e);
|
|
11904
|
+
}, [enableCamera, handlePointerDown]);
|
|
11905
|
+
const handleCanvasPointerMove = useCallback((e) => {
|
|
11906
|
+
if (enableCamera) handlePointerMove(e, () => draw(animTimeRef.current));
|
|
11907
|
+
}, [enableCamera, handlePointerMove, draw]);
|
|
11908
|
+
const handleCanvasHover = useCallback((e) => {
|
|
11909
|
+
if (singlePointerActiveRef.current) return;
|
|
11679
11910
|
if (!onTileHover && !tileHoverEvent || !canvasRef.current) return;
|
|
11680
11911
|
const world = screenToWorld(e.clientX, e.clientY, canvasRef.current, viewportSize);
|
|
11681
11912
|
const adjustedX = world.x - scaledTileWidth / 2;
|
|
@@ -11686,26 +11917,10 @@ function IsometricCanvas({
|
|
|
11686
11917
|
if (tileHoverEvent) eventBus.emit(`UI:${tileHoverEvent}`, { x: isoPos.x, y: isoPos.y });
|
|
11687
11918
|
onTileHover?.(isoPos.x, isoPos.y);
|
|
11688
11919
|
}
|
|
11689
|
-
}, [
|
|
11690
|
-
const
|
|
11691
|
-
|
|
11692
|
-
if (
|
|
11693
|
-
onTileLeave?.();
|
|
11694
|
-
}, [handleMouseLeave, onTileLeave, tileLeaveEvent, eventBus]);
|
|
11695
|
-
const handleWheelWithCamera = useCallback((e) => {
|
|
11696
|
-
if (enableCamera) {
|
|
11697
|
-
handleWheel(e, () => draw(animTimeRef.current));
|
|
11698
|
-
}
|
|
11699
|
-
}, [enableCamera, handleWheel, draw]);
|
|
11700
|
-
useEffect(() => {
|
|
11701
|
-
const canvas = canvasRef.current;
|
|
11702
|
-
if (!canvas) return;
|
|
11703
|
-
canvas.addEventListener("wheel", handleWheelWithCamera, { passive: false });
|
|
11704
|
-
return () => {
|
|
11705
|
-
canvas.removeEventListener("wheel", handleWheelWithCamera);
|
|
11706
|
-
};
|
|
11707
|
-
}, [handleWheelWithCamera]);
|
|
11708
|
-
const handleClick = useCallback((e) => {
|
|
11920
|
+
}, [onTileHover, screenToWorld, viewportSize, scaledTileWidth, scaledDiamondTopY, scaledFloorHeight, scale, baseOffsetX, tilesProp, tileHoverEvent, eventBus]);
|
|
11921
|
+
const handleCanvasPointerUp = useCallback((e) => {
|
|
11922
|
+
singlePointerActiveRef.current = false;
|
|
11923
|
+
if (enableCamera) handlePointerUp();
|
|
11709
11924
|
if (dragDistance() > 5) return;
|
|
11710
11925
|
if (!canvasRef.current) return;
|
|
11711
11926
|
const world = screenToWorld(e.clientX, e.clientY, canvasRef.current, viewportSize);
|
|
@@ -11723,7 +11938,32 @@ function IsometricCanvas({
|
|
|
11723
11938
|
onTileClick?.(isoPos.x, isoPos.y);
|
|
11724
11939
|
}
|
|
11725
11940
|
}
|
|
11726
|
-
}, [dragDistance, screenToWorld, viewportSize, scaledTileWidth, scaledDiamondTopY, scaledFloorHeight, scale, baseOffsetX, units, tilesProp, onUnitClick, onTileClick, unitClickEvent, tileClickEvent, eventBus]);
|
|
11941
|
+
}, [enableCamera, handlePointerUp, dragDistance, screenToWorld, viewportSize, scaledTileWidth, scaledDiamondTopY, scaledFloorHeight, scale, baseOffsetX, units, tilesProp, onUnitClick, onTileClick, unitClickEvent, tileClickEvent, eventBus]);
|
|
11942
|
+
const handleCanvasPointerLeave = useCallback(() => {
|
|
11943
|
+
handleMouseLeave();
|
|
11944
|
+
if (tileLeaveEvent) eventBus.emit(`UI:${tileLeaveEvent}`, {});
|
|
11945
|
+
onTileLeave?.();
|
|
11946
|
+
}, [handleMouseLeave, onTileLeave, tileLeaveEvent, eventBus]);
|
|
11947
|
+
const applyZoom = useCallback((factor, centerX, centerY) => {
|
|
11948
|
+
if (enableCamera) zoomAtPoint(factor, centerX, centerY, viewportSize, () => draw(animTimeRef.current));
|
|
11949
|
+
}, [enableCamera, zoomAtPoint, viewportSize, draw]);
|
|
11950
|
+
const applyPanDelta = useCallback((dx, dy) => {
|
|
11951
|
+
if (enableCamera) panBy(dx, dy, () => draw(animTimeRef.current));
|
|
11952
|
+
}, [enableCamera, panBy, draw]);
|
|
11953
|
+
const cancelSinglePointer = useCallback(() => {
|
|
11954
|
+
singlePointerActiveRef.current = false;
|
|
11955
|
+
if (enableCamera) handlePointerUp();
|
|
11956
|
+
}, [enableCamera, handlePointerUp]);
|
|
11957
|
+
const gestureHandlers = useCanvasGestures({
|
|
11958
|
+
canvasRef,
|
|
11959
|
+
enabled: enableCamera || !!onTileHover || !!tileHoverEvent || !!onTileClick || !!tileClickEvent || !!onUnitClick || !!unitClickEvent,
|
|
11960
|
+
onPointerDown: handleCanvasPointerDown,
|
|
11961
|
+
onPointerMove: handleCanvasPointerMove,
|
|
11962
|
+
onPointerUp: handleCanvasPointerUp,
|
|
11963
|
+
onZoom: applyZoom,
|
|
11964
|
+
onPanDelta: applyPanDelta,
|
|
11965
|
+
onMultiTouchStart: cancelSinglePointer
|
|
11966
|
+
});
|
|
11727
11967
|
if (error) {
|
|
11728
11968
|
return /* @__PURE__ */ jsx(ErrorState, { title: t("canvas.errorTitle"), message: error.message, className });
|
|
11729
11969
|
}
|
|
@@ -11755,13 +11995,17 @@ function IsometricCanvas({
|
|
|
11755
11995
|
{
|
|
11756
11996
|
ref: canvasRef,
|
|
11757
11997
|
"data-testid": "game-canvas",
|
|
11758
|
-
|
|
11759
|
-
|
|
11760
|
-
|
|
11761
|
-
|
|
11762
|
-
|
|
11998
|
+
onPointerDown: gestureHandlers.onPointerDown,
|
|
11999
|
+
onPointerMove: (e) => {
|
|
12000
|
+
gestureHandlers.onPointerMove(e);
|
|
12001
|
+
handleCanvasHover(e);
|
|
12002
|
+
},
|
|
12003
|
+
onPointerUp: gestureHandlers.onPointerUp,
|
|
12004
|
+
onPointerCancel: gestureHandlers.onPointerCancel,
|
|
12005
|
+
onPointerLeave: handleCanvasPointerLeave,
|
|
12006
|
+
onWheel: gestureHandlers.onWheel,
|
|
11763
12007
|
onContextMenu: (e) => e.preventDefault(),
|
|
11764
|
-
className: "cursor-pointer",
|
|
12008
|
+
className: "cursor-pointer touch-none",
|
|
11765
12009
|
style: {
|
|
11766
12010
|
width: viewportSize.width,
|
|
11767
12011
|
height: viewportSize.height
|
|
@@ -11815,6 +12059,7 @@ var init_IsometricCanvas = __esm({
|
|
|
11815
12059
|
init_ErrorState();
|
|
11816
12060
|
init_useImageCache();
|
|
11817
12061
|
init_useCamera();
|
|
12062
|
+
init_useCanvasGestures();
|
|
11818
12063
|
init_useUnitSpriteAtlas();
|
|
11819
12064
|
init_verificationRegistry();
|
|
11820
12065
|
init_isometric();
|
|
@@ -13617,7 +13862,7 @@ var init_CodeBlock = __esm({
|
|
|
13617
13862
|
};
|
|
13618
13863
|
LINE_PROPS_FN = (n) => ({ "data-line": String(n - 1) });
|
|
13619
13864
|
HIDDEN_LINE_NUMBERS = { display: "none" };
|
|
13620
|
-
CodeBlock =
|
|
13865
|
+
CodeBlock = React85__default.memo(
|
|
13621
13866
|
({
|
|
13622
13867
|
code: rawCode,
|
|
13623
13868
|
language = "text",
|
|
@@ -13786,24 +14031,24 @@ var init_CodeBlock = __esm({
|
|
|
13786
14031
|
return;
|
|
13787
14032
|
}
|
|
13788
14033
|
lineEls.forEach((el) => {
|
|
13789
|
-
const
|
|
13790
|
-
if (hiddenLines.has(
|
|
14034
|
+
const num3 = parseInt(el.getAttribute("data-line") ?? "-1", 10);
|
|
14035
|
+
if (hiddenLines.has(num3)) {
|
|
13791
14036
|
el.style.display = "none";
|
|
13792
14037
|
return;
|
|
13793
14038
|
}
|
|
13794
14039
|
el.style.display = "";
|
|
13795
14040
|
el.style.position = "relative";
|
|
13796
14041
|
el.style.paddingLeft = "1.2em";
|
|
13797
|
-
const region = foldStartMap.get(
|
|
14042
|
+
const region = foldStartMap.get(num3);
|
|
13798
14043
|
if (!region) return;
|
|
13799
|
-
const isCollapsed = collapsed.has(
|
|
14044
|
+
const isCollapsed = collapsed.has(num3);
|
|
13800
14045
|
const toggle = document.createElement("span");
|
|
13801
14046
|
toggle.className = "fold-toggle";
|
|
13802
14047
|
toggle.textContent = isCollapsed ? "\u25B6" : "\u25BC";
|
|
13803
14048
|
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%";
|
|
13804
14049
|
toggle.addEventListener("click", (e) => {
|
|
13805
14050
|
e.stopPropagation();
|
|
13806
|
-
toggleFoldRef.current(
|
|
14051
|
+
toggleFoldRef.current(num3);
|
|
13807
14052
|
});
|
|
13808
14053
|
el.insertBefore(toggle, el.firstChild);
|
|
13809
14054
|
if (isCollapsed) {
|
|
@@ -14204,7 +14449,7 @@ var init_MarkdownContent = __esm({
|
|
|
14204
14449
|
init_Box();
|
|
14205
14450
|
init_CodeBlock();
|
|
14206
14451
|
init_cn();
|
|
14207
|
-
MarkdownContent =
|
|
14452
|
+
MarkdownContent = React85__default.memo(
|
|
14208
14453
|
({ content, direction = "ltr", className }) => {
|
|
14209
14454
|
const { t: _t } = useTranslate();
|
|
14210
14455
|
const safeContent = typeof content === "string" ? content : String(content ?? "");
|
|
@@ -14930,6 +15175,10 @@ var init_StateMachineView = __esm({
|
|
|
14930
15175
|
const handleMouseLeave2 = () => {
|
|
14931
15176
|
onHover(null, 0, 0);
|
|
14932
15177
|
};
|
|
15178
|
+
const handlePointerDown2 = (e) => {
|
|
15179
|
+
if (e.pointerType === "mouse") return;
|
|
15180
|
+
handleMouseEnter2();
|
|
15181
|
+
};
|
|
14933
15182
|
return /* @__PURE__ */ jsxs(
|
|
14934
15183
|
"g",
|
|
14935
15184
|
{
|
|
@@ -14939,6 +15188,7 @@ var init_StateMachineView = __esm({
|
|
|
14939
15188
|
onClick: () => onClick?.(bundle),
|
|
14940
15189
|
onMouseEnter: handleMouseEnter2,
|
|
14941
15190
|
onMouseLeave: handleMouseLeave2,
|
|
15191
|
+
onPointerDown: handlePointerDown2,
|
|
14942
15192
|
style: { pointerEvents: "auto" },
|
|
14943
15193
|
children: [
|
|
14944
15194
|
/* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsx(
|
|
@@ -15056,6 +15306,10 @@ var init_StateMachineView = __esm({
|
|
|
15056
15306
|
const handleMouseLeave = useCallback(() => {
|
|
15057
15307
|
onHover(null, 0, 0);
|
|
15058
15308
|
}, [onHover]);
|
|
15309
|
+
const handlePointerDown = useCallback((e) => {
|
|
15310
|
+
if (e.pointerType === "mouse") return;
|
|
15311
|
+
handleMouseEnter();
|
|
15312
|
+
}, [handleMouseEnter]);
|
|
15059
15313
|
const uniqueMarkerId = `arrow-${bundle.id}`;
|
|
15060
15314
|
const hasDetails = bundle.labels.some((l) => l.hasDetails);
|
|
15061
15315
|
return /* @__PURE__ */ jsxs(
|
|
@@ -15067,6 +15321,7 @@ var init_StateMachineView = __esm({
|
|
|
15067
15321
|
onClick: () => onClick?.(bundle),
|
|
15068
15322
|
onMouseEnter: handleMouseEnter,
|
|
15069
15323
|
onMouseLeave: handleMouseLeave,
|
|
15324
|
+
onPointerDown: handlePointerDown,
|
|
15070
15325
|
style: { pointerEvents: "auto" },
|
|
15071
15326
|
children: [
|
|
15072
15327
|
/* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsx(
|
|
@@ -15521,7 +15776,7 @@ var init_StateMachineView = __esm({
|
|
|
15521
15776
|
style: { top: title ? 30 : 0 },
|
|
15522
15777
|
children: [
|
|
15523
15778
|
entity && /* @__PURE__ */ jsx(EntityBox, { entity, config }),
|
|
15524
|
-
states.map((state) => renderStateNode ? /* @__PURE__ */ jsx(
|
|
15779
|
+
states.map((state) => renderStateNode ? /* @__PURE__ */ jsx(React85__default.Fragment, { children: renderStateNode(state, config) }, state.id) : /* @__PURE__ */ jsx(
|
|
15525
15780
|
StateNode,
|
|
15526
15781
|
{
|
|
15527
15782
|
state,
|
|
@@ -19422,8 +19677,8 @@ function EmojiEffect({
|
|
|
19422
19677
|
);
|
|
19423
19678
|
}
|
|
19424
19679
|
function CanvasEffect({
|
|
19425
|
-
effectSpriteUrl
|
|
19426
|
-
assetBaseUrl
|
|
19680
|
+
effectSpriteUrl,
|
|
19681
|
+
assetBaseUrl,
|
|
19427
19682
|
...props
|
|
19428
19683
|
}) {
|
|
19429
19684
|
const eventBus = useEventBus();
|
|
@@ -19466,6 +19721,380 @@ var init_CanvasEffect = __esm({
|
|
|
19466
19721
|
CanvasEffect.displayName = "CanvasEffect";
|
|
19467
19722
|
}
|
|
19468
19723
|
});
|
|
19724
|
+
function CardHand({
|
|
19725
|
+
cards = DEFAULT_CARDS,
|
|
19726
|
+
selectedId = "",
|
|
19727
|
+
size = "md",
|
|
19728
|
+
onCardClick,
|
|
19729
|
+
cardClickEvent,
|
|
19730
|
+
emptyLabel = "No cards in hand",
|
|
19731
|
+
className
|
|
19732
|
+
}) {
|
|
19733
|
+
const eventBus = useEventBus();
|
|
19734
|
+
const handleClick = React85.useCallback(
|
|
19735
|
+
(card) => {
|
|
19736
|
+
if (card.disabled) return;
|
|
19737
|
+
onCardClick?.(card.id);
|
|
19738
|
+
if (cardClickEvent) {
|
|
19739
|
+
eventBus.emit(`UI:${cardClickEvent}`, { cardId: card.id });
|
|
19740
|
+
}
|
|
19741
|
+
},
|
|
19742
|
+
[onCardClick, cardClickEvent, eventBus]
|
|
19743
|
+
);
|
|
19744
|
+
if (cards.length === 0) {
|
|
19745
|
+
return /* @__PURE__ */ jsx(Box, { className: cn("flex items-center justify-center p-4", className), children: /* @__PURE__ */ jsx(Typography, { variant: "small", color: "muted", children: emptyLabel }) });
|
|
19746
|
+
}
|
|
19747
|
+
const art = artSizeMap[size];
|
|
19748
|
+
return /* @__PURE__ */ jsx(Box, { className: cn("flex flex-wrap gap-2 justify-center items-end", className), children: cards.map((card) => {
|
|
19749
|
+
const selected = selectedId === card.id;
|
|
19750
|
+
return /* @__PURE__ */ jsxs(
|
|
19751
|
+
"button",
|
|
19752
|
+
{
|
|
19753
|
+
type: "button",
|
|
19754
|
+
onClick: () => handleClick(card),
|
|
19755
|
+
disabled: card.disabled,
|
|
19756
|
+
title: card.title,
|
|
19757
|
+
className: cn(
|
|
19758
|
+
"card-hand-card relative flex flex-col items-center rounded-interactive border-2",
|
|
19759
|
+
"bg-card/90 px-1.5 pt-1.5 pb-1 transition-all duration-150",
|
|
19760
|
+
cardSizeMap[size],
|
|
19761
|
+
card.disabled ? "border-border opacity-50 cursor-not-allowed" : "border-accent hover:brightness-125 hover:-translate-y-1 cursor-pointer",
|
|
19762
|
+
selected && "ring-2 ring-foreground ring-offset-1 ring-offset-background -translate-y-1"
|
|
19763
|
+
),
|
|
19764
|
+
children: [
|
|
19765
|
+
card.cost != null && /* @__PURE__ */ jsx(
|
|
19766
|
+
"span",
|
|
19767
|
+
{
|
|
19768
|
+
className: cn(
|
|
19769
|
+
"absolute -top-2 -left-2 flex items-center justify-center",
|
|
19770
|
+
"min-w-[22px] h-[22px] rounded-full px-1",
|
|
19771
|
+
"bg-info text-foreground text-xs font-bold border border-background"
|
|
19772
|
+
),
|
|
19773
|
+
children: card.cost
|
|
19774
|
+
}
|
|
19775
|
+
),
|
|
19776
|
+
/* @__PURE__ */ jsx(Box, { className: "flex-1 flex items-center justify-center w-full", children: card.iconUrl ? /* @__PURE__ */ jsx(
|
|
19777
|
+
"img",
|
|
19778
|
+
{
|
|
19779
|
+
src: card.iconUrl,
|
|
19780
|
+
alt: card.title ?? card.id,
|
|
19781
|
+
width: art,
|
|
19782
|
+
height: art,
|
|
19783
|
+
style: { imageRendering: "pixelated", objectFit: "contain" },
|
|
19784
|
+
className: "flex-shrink-0"
|
|
19785
|
+
}
|
|
19786
|
+
) : /* @__PURE__ */ jsx(
|
|
19787
|
+
Box,
|
|
19788
|
+
{
|
|
19789
|
+
className: "rounded bg-muted/40",
|
|
19790
|
+
style: { width: art, height: art }
|
|
19791
|
+
}
|
|
19792
|
+
) }),
|
|
19793
|
+
card.title != null && /* @__PURE__ */ jsx(
|
|
19794
|
+
Typography,
|
|
19795
|
+
{
|
|
19796
|
+
variant: "small",
|
|
19797
|
+
className: "w-full truncate text-center text-[10px] leading-tight font-semibold",
|
|
19798
|
+
children: card.title
|
|
19799
|
+
}
|
|
19800
|
+
),
|
|
19801
|
+
(card.attack != null || card.defense != null) && /* @__PURE__ */ jsxs(Box, { className: "flex w-full items-center justify-between px-0.5 text-[10px] font-bold leading-none", children: [
|
|
19802
|
+
/* @__PURE__ */ jsx("span", { className: "text-error", children: card.attack != null ? `\u2694${card.attack}` : "" }),
|
|
19803
|
+
/* @__PURE__ */ jsx("span", { className: "text-info", children: card.defense != null ? `\u{1F6E1}${card.defense}` : "" })
|
|
19804
|
+
] })
|
|
19805
|
+
]
|
|
19806
|
+
},
|
|
19807
|
+
card.id
|
|
19808
|
+
);
|
|
19809
|
+
}) });
|
|
19810
|
+
}
|
|
19811
|
+
var cardSizeMap, artSizeMap, DEFAULT_CARDS;
|
|
19812
|
+
var init_CardHand = __esm({
|
|
19813
|
+
"components/game/molecules/CardHand.tsx"() {
|
|
19814
|
+
"use client";
|
|
19815
|
+
init_cn();
|
|
19816
|
+
init_useEventBus();
|
|
19817
|
+
init_Box();
|
|
19818
|
+
init_Typography();
|
|
19819
|
+
cardSizeMap = {
|
|
19820
|
+
sm: "w-16 h-24",
|
|
19821
|
+
md: "w-20 h-28",
|
|
19822
|
+
lg: "w-24 h-36"
|
|
19823
|
+
};
|
|
19824
|
+
artSizeMap = {
|
|
19825
|
+
sm: 40,
|
|
19826
|
+
md: 52,
|
|
19827
|
+
lg: 64
|
|
19828
|
+
};
|
|
19829
|
+
DEFAULT_CARDS = [
|
|
19830
|
+
{ id: "card-1", title: "Brawler", cost: 1, attack: 2, defense: 1 },
|
|
19831
|
+
{ id: "card-2", title: "Guardian", cost: 2, attack: 1, defense: 4 },
|
|
19832
|
+
{ id: "card-3", title: "Striker", cost: 3, attack: 5, defense: 2 }
|
|
19833
|
+
];
|
|
19834
|
+
CardHand.displayName = "CardHand";
|
|
19835
|
+
}
|
|
19836
|
+
});
|
|
19837
|
+
function resolveManifestUrl(manifest, relative) {
|
|
19838
|
+
if (relative == null) return void 0;
|
|
19839
|
+
if (/^https?:\/\//.test(relative)) return relative;
|
|
19840
|
+
const base = manifest?.baseUrl;
|
|
19841
|
+
if (base == null) return relative;
|
|
19842
|
+
const cleanBase = base.replace(/\/$/, "");
|
|
19843
|
+
const cleanRel = relative.replace(/^\//, "");
|
|
19844
|
+
return `${cleanBase}/${cleanRel}`;
|
|
19845
|
+
}
|
|
19846
|
+
function rowToCard(r) {
|
|
19847
|
+
return {
|
|
19848
|
+
id: str(r.id),
|
|
19849
|
+
iconKey: r.iconKey == null ? void 0 : str(r.iconKey),
|
|
19850
|
+
title: r.title == null ? void 0 : str(r.title),
|
|
19851
|
+
cost: r.cost == null ? void 0 : num(r.cost),
|
|
19852
|
+
attack: r.attack == null ? void 0 : num(r.attack),
|
|
19853
|
+
defense: r.defense == null ? void 0 : num(r.defense)
|
|
19854
|
+
};
|
|
19855
|
+
}
|
|
19856
|
+
function toHandCards(cards, manifest, mana) {
|
|
19857
|
+
return cards.map((c) => {
|
|
19858
|
+
const key = c.iconKey ?? c.id;
|
|
19859
|
+
const iconUrl = resolveManifestUrl(manifest, manifest?.cards?.[key]);
|
|
19860
|
+
return {
|
|
19861
|
+
id: c.id,
|
|
19862
|
+
iconUrl,
|
|
19863
|
+
title: c.title,
|
|
19864
|
+
cost: c.cost,
|
|
19865
|
+
attack: c.attack,
|
|
19866
|
+
defense: c.defense,
|
|
19867
|
+
disabled: c.cost != null && c.cost > mana
|
|
19868
|
+
};
|
|
19869
|
+
});
|
|
19870
|
+
}
|
|
19871
|
+
function CardBattlerBoard({
|
|
19872
|
+
entity,
|
|
19873
|
+
deck: propDeck,
|
|
19874
|
+
hand: propHand,
|
|
19875
|
+
board: propBoard,
|
|
19876
|
+
mana: propMana,
|
|
19877
|
+
maxMana: propMaxMana,
|
|
19878
|
+
turn: propTurn,
|
|
19879
|
+
result: propResult,
|
|
19880
|
+
assetManifest: propAssetManifest,
|
|
19881
|
+
playCardEvent,
|
|
19882
|
+
endTurnEvent,
|
|
19883
|
+
playAgainEvent,
|
|
19884
|
+
gameEndEvent,
|
|
19885
|
+
className
|
|
19886
|
+
}) {
|
|
19887
|
+
const board = boardEntity(entity) ?? {};
|
|
19888
|
+
const eventBus = useEventBus();
|
|
19889
|
+
const { t } = useTranslate();
|
|
19890
|
+
const assetManifest = propAssetManifest ?? board.assetManifest;
|
|
19891
|
+
const entityHand = useMemo(() => rows(board.hand).map(rowToCard), [board.hand]);
|
|
19892
|
+
const rawHand = propHand ?? entityHand;
|
|
19893
|
+
const hand = rawHand.length > 0 ? rawHand : DEFAULT_HAND;
|
|
19894
|
+
const entityBoard = useMemo(() => rows(board.board).map(rowToCard), [board.board]);
|
|
19895
|
+
const playedCards = propBoard ?? entityBoard;
|
|
19896
|
+
const entityDeck = useMemo(() => rows(board.deck).map(rowToCard), [board.deck]);
|
|
19897
|
+
const deck = propDeck ?? entityDeck;
|
|
19898
|
+
const mana = propMana ?? num(board.mana, 3);
|
|
19899
|
+
const maxMana = propMaxMana ?? num(board.maxMana, 3);
|
|
19900
|
+
const turn = propTurn ?? num(board.turn, 1);
|
|
19901
|
+
const result = propResult ?? (str(board.result) || "none");
|
|
19902
|
+
const handCards = useMemo(() => toHandCards(hand, assetManifest, mana), [hand, assetManifest, mana]);
|
|
19903
|
+
const boardCards = useMemo(() => toHandCards(playedCards, assetManifest, mana), [playedCards, assetManifest, mana]);
|
|
19904
|
+
const emittedGameEnd = useRef(false);
|
|
19905
|
+
if (result !== "none" && !emittedGameEnd.current) {
|
|
19906
|
+
emittedGameEnd.current = true;
|
|
19907
|
+
if (gameEndEvent) {
|
|
19908
|
+
eventBus.emit(`UI:${gameEndEvent}`, { result });
|
|
19909
|
+
}
|
|
19910
|
+
}
|
|
19911
|
+
if (result === "none") {
|
|
19912
|
+
emittedGameEnd.current = false;
|
|
19913
|
+
}
|
|
19914
|
+
const handlePlayCard = useCallback((cardId) => {
|
|
19915
|
+
if (result !== "none") return;
|
|
19916
|
+
if (playCardEvent) {
|
|
19917
|
+
eventBus.emit(`UI:${playCardEvent}`, { cardId });
|
|
19918
|
+
}
|
|
19919
|
+
}, [result, playCardEvent, eventBus]);
|
|
19920
|
+
const handleEndTurn = useCallback(() => {
|
|
19921
|
+
if (result !== "none") return;
|
|
19922
|
+
if (endTurnEvent) {
|
|
19923
|
+
eventBus.emit(`UI:${endTurnEvent}`, {});
|
|
19924
|
+
}
|
|
19925
|
+
}, [result, endTurnEvent, eventBus]);
|
|
19926
|
+
const handlePlayAgain = useCallback(() => {
|
|
19927
|
+
if (playAgainEvent) {
|
|
19928
|
+
eventBus.emit(`UI:${playAgainEvent}`, {});
|
|
19929
|
+
}
|
|
19930
|
+
}, [playAgainEvent, eventBus]);
|
|
19931
|
+
return /* @__PURE__ */ jsxs(VStack, { className: cn("card-battler-board relative min-h-[600px] bg-background", className), gap: "none", children: [
|
|
19932
|
+
/* @__PURE__ */ jsxs(
|
|
19933
|
+
HStack,
|
|
19934
|
+
{
|
|
19935
|
+
className: "px-4 py-2 border-b border-border bg-surface",
|
|
19936
|
+
gap: "lg",
|
|
19937
|
+
align: "center",
|
|
19938
|
+
children: [
|
|
19939
|
+
/* @__PURE__ */ jsxs(HStack, { gap: "xs", align: "center", children: [
|
|
19940
|
+
/* @__PURE__ */ jsx(Typography, { variant: "small", color: "muted", children: t("cb.mana") ?? "Mana" }),
|
|
19941
|
+
/* @__PURE__ */ jsxs(Typography, { variant: "body2", weight: "bold", className: "text-info", children: [
|
|
19942
|
+
mana,
|
|
19943
|
+
" / ",
|
|
19944
|
+
maxMana
|
|
19945
|
+
] })
|
|
19946
|
+
] }),
|
|
19947
|
+
/* @__PURE__ */ jsxs(HStack, { gap: "xs", align: "center", children: [
|
|
19948
|
+
/* @__PURE__ */ jsx(Typography, { variant: "small", color: "muted", children: t("cb.turn") ?? "Turn" }),
|
|
19949
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body2", weight: "bold", children: turn })
|
|
19950
|
+
] }),
|
|
19951
|
+
/* @__PURE__ */ jsxs(HStack, { gap: "xs", align: "center", children: [
|
|
19952
|
+
/* @__PURE__ */ jsx(Typography, { variant: "small", color: "muted", children: t("cb.deck") ?? "Deck" }),
|
|
19953
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body2", weight: "bold", children: deck.length })
|
|
19954
|
+
] }),
|
|
19955
|
+
/* @__PURE__ */ jsx(Box, { className: "ml-auto", children: result === "none" && /* @__PURE__ */ jsx(Button, { variant: "primary", size: "sm", onClick: handleEndTurn, children: t("cb.endTurn") ?? "End Turn" }) })
|
|
19956
|
+
]
|
|
19957
|
+
}
|
|
19958
|
+
),
|
|
19959
|
+
/* @__PURE__ */ jsxs(Box, { className: "flex-1 relative p-4 overflow-auto", children: [
|
|
19960
|
+
/* @__PURE__ */ jsx(Typography, { variant: "small", color: "muted", className: "mb-2 uppercase tracking-wide", children: t("cb.battlefield") ?? "Battlefield" }),
|
|
19961
|
+
boardCards.length > 0 ? /* @__PURE__ */ jsx(
|
|
19962
|
+
CardHand,
|
|
19963
|
+
{
|
|
19964
|
+
cards: boardCards,
|
|
19965
|
+
size: "md",
|
|
19966
|
+
className: "justify-start"
|
|
19967
|
+
}
|
|
19968
|
+
) : /* @__PURE__ */ jsx(Box, { className: "flex items-center justify-center h-32 rounded-interactive border-2 border-dashed border-border", children: /* @__PURE__ */ jsx(Typography, { variant: "small", color: "muted", children: t("cb.emptyBoard") ?? "Play a card to begin" }) })
|
|
19969
|
+
] }),
|
|
19970
|
+
/* @__PURE__ */ jsxs(Box, { className: "border-t border-border bg-surface px-4 py-3", children: [
|
|
19971
|
+
/* @__PURE__ */ jsx(Typography, { variant: "small", color: "muted", className: "mb-2 uppercase tracking-wide", children: t("cb.hand") ?? "Your Hand" }),
|
|
19972
|
+
/* @__PURE__ */ jsx(
|
|
19973
|
+
CardHand,
|
|
19974
|
+
{
|
|
19975
|
+
cards: handCards,
|
|
19976
|
+
size: "lg",
|
|
19977
|
+
onCardClick: handlePlayCard,
|
|
19978
|
+
emptyLabel: t("cb.emptyHand") ?? "No cards in hand"
|
|
19979
|
+
}
|
|
19980
|
+
)
|
|
19981
|
+
] }),
|
|
19982
|
+
result !== "none" && /* @__PURE__ */ jsx(Box, { className: "absolute inset-0 z-50 flex items-center justify-center bg-background/70 backdrop-blur-sm", children: /* @__PURE__ */ jsxs(VStack, { className: "text-center p-8", gap: "lg", children: [
|
|
19983
|
+
/* @__PURE__ */ jsx(
|
|
19984
|
+
Typography,
|
|
19985
|
+
{
|
|
19986
|
+
variant: "h2",
|
|
19987
|
+
className: cn(
|
|
19988
|
+
"text-4xl font-black tracking-widest uppercase",
|
|
19989
|
+
result === "won" ? "text-warning" : "text-error"
|
|
19990
|
+
),
|
|
19991
|
+
children: result === "won" ? t("cb.victory") ?? "Victory!" : t("cb.defeat") ?? "Defeat!"
|
|
19992
|
+
}
|
|
19993
|
+
),
|
|
19994
|
+
/* @__PURE__ */ jsx(
|
|
19995
|
+
Button,
|
|
19996
|
+
{
|
|
19997
|
+
variant: "primary",
|
|
19998
|
+
className: "px-8 py-3 font-semibold",
|
|
19999
|
+
onClick: handlePlayAgain,
|
|
20000
|
+
children: t("cb.playAgain") ?? "Play Again"
|
|
20001
|
+
}
|
|
20002
|
+
)
|
|
20003
|
+
] }) })
|
|
20004
|
+
] });
|
|
20005
|
+
}
|
|
20006
|
+
var DEFAULT_HAND;
|
|
20007
|
+
var init_CardBattlerBoard = __esm({
|
|
20008
|
+
"components/game/organisms/CardBattlerBoard.tsx"() {
|
|
20009
|
+
"use client";
|
|
20010
|
+
init_cn();
|
|
20011
|
+
init_useEventBus();
|
|
20012
|
+
init_Box();
|
|
20013
|
+
init_Button();
|
|
20014
|
+
init_Typography();
|
|
20015
|
+
init_Stack();
|
|
20016
|
+
init_CardHand();
|
|
20017
|
+
init_boardEntity();
|
|
20018
|
+
DEFAULT_HAND = [
|
|
20019
|
+
{ id: "c1", iconKey: "bear", title: "Bear", cost: 3, attack: 5, defense: 4 },
|
|
20020
|
+
{ id: "c2", iconKey: "owl", title: "Owl", cost: 1, attack: 2, defense: 1 },
|
|
20021
|
+
{ id: "c3", iconKey: "gorilla", title: "Gorilla", cost: 4, attack: 6, defense: 5 },
|
|
20022
|
+
{ id: "c4", iconKey: "frog", title: "Frog", cost: 1, attack: 1, defense: 2 },
|
|
20023
|
+
{ id: "c5", iconKey: "snake", title: "Snake", cost: 2, attack: 4, defense: 1 }
|
|
20024
|
+
];
|
|
20025
|
+
CardBattlerBoard.displayName = "CardBattlerBoard";
|
|
20026
|
+
}
|
|
20027
|
+
});
|
|
20028
|
+
function isEntityRow(value) {
|
|
20029
|
+
return value != null && typeof value === "object" && !Array.isArray(value);
|
|
20030
|
+
}
|
|
20031
|
+
function CardBattlerTemplate({
|
|
20032
|
+
entity,
|
|
20033
|
+
title = "Card Battler",
|
|
20034
|
+
deck,
|
|
20035
|
+
hand,
|
|
20036
|
+
board,
|
|
20037
|
+
mana,
|
|
20038
|
+
maxMana,
|
|
20039
|
+
turn,
|
|
20040
|
+
result,
|
|
20041
|
+
assetManifest,
|
|
20042
|
+
playCardEvent,
|
|
20043
|
+
endTurnEvent,
|
|
20044
|
+
playAgainEvent,
|
|
20045
|
+
gameEndEvent,
|
|
20046
|
+
className
|
|
20047
|
+
}) {
|
|
20048
|
+
const resolved = isEntityRow(entity) ? entity : void 0;
|
|
20049
|
+
return /* @__PURE__ */ jsxs(
|
|
20050
|
+
Box,
|
|
20051
|
+
{
|
|
20052
|
+
display: "flex",
|
|
20053
|
+
fullHeight: true,
|
|
20054
|
+
className: cn("card-battler-template flex-col", className),
|
|
20055
|
+
children: [
|
|
20056
|
+
/* @__PURE__ */ jsx(
|
|
20057
|
+
HStack,
|
|
20058
|
+
{
|
|
20059
|
+
gap: "sm",
|
|
20060
|
+
align: "center",
|
|
20061
|
+
className: "px-4 py-3 border-b-2 border-border bg-surface shrink-0",
|
|
20062
|
+
children: /* @__PURE__ */ jsx(Typography, { variant: "h4", children: title })
|
|
20063
|
+
}
|
|
20064
|
+
),
|
|
20065
|
+
/* @__PURE__ */ jsx(Box, { className: "flex-1 relative overflow-hidden", children: /* @__PURE__ */ jsx(
|
|
20066
|
+
CardBattlerBoard,
|
|
20067
|
+
{
|
|
20068
|
+
entity: resolved,
|
|
20069
|
+
deck,
|
|
20070
|
+
hand,
|
|
20071
|
+
board,
|
|
20072
|
+
mana,
|
|
20073
|
+
maxMana,
|
|
20074
|
+
turn,
|
|
20075
|
+
result,
|
|
20076
|
+
assetManifest,
|
|
20077
|
+
playCardEvent,
|
|
20078
|
+
endTurnEvent,
|
|
20079
|
+
playAgainEvent,
|
|
20080
|
+
gameEndEvent,
|
|
20081
|
+
className: "h-full"
|
|
20082
|
+
}
|
|
20083
|
+
) })
|
|
20084
|
+
]
|
|
20085
|
+
}
|
|
20086
|
+
);
|
|
20087
|
+
}
|
|
20088
|
+
var init_CardBattlerTemplate = __esm({
|
|
20089
|
+
"components/game/templates/CardBattlerTemplate.tsx"() {
|
|
20090
|
+
init_cn();
|
|
20091
|
+
init_Box();
|
|
20092
|
+
init_Stack();
|
|
20093
|
+
init_Typography();
|
|
20094
|
+
init_CardBattlerBoard();
|
|
20095
|
+
CardBattlerTemplate.displayName = "CardBattlerTemplate";
|
|
20096
|
+
}
|
|
20097
|
+
});
|
|
19469
20098
|
|
|
19470
20099
|
// lib/getNestedValue.ts
|
|
19471
20100
|
function getNestedValue(obj, path) {
|
|
@@ -21248,6 +21877,315 @@ var init_ChartLegend = __esm({
|
|
|
21248
21877
|
ChartLegend.displayName = "ChartLegend";
|
|
21249
21878
|
}
|
|
21250
21879
|
});
|
|
21880
|
+
function resolveManifestUrl2(manifest, relative) {
|
|
21881
|
+
if (relative == null) return void 0;
|
|
21882
|
+
if (/^https?:\/\//.test(relative)) return relative;
|
|
21883
|
+
const base = manifest?.baseUrl;
|
|
21884
|
+
if (base == null) return relative;
|
|
21885
|
+
const cleanBase = base.replace(/\/$/, "");
|
|
21886
|
+
const cleanRel = relative.replace(/^\//, "");
|
|
21887
|
+
return `${cleanBase}/${cleanRel}`;
|
|
21888
|
+
}
|
|
21889
|
+
function buildDefaultCBTiles() {
|
|
21890
|
+
const tiles = [];
|
|
21891
|
+
for (let y = 0; y < CB_GRID_H; y++) {
|
|
21892
|
+
for (let x = 0; x < CB_GRID_W; x++) {
|
|
21893
|
+
const variant = (x * 3 + y * 5 + (x ^ y)) % 3;
|
|
21894
|
+
const terrainKey = ["grass", "stone", "dirt"][variant];
|
|
21895
|
+
tiles.push({ x, y, terrain: terrainKey, passable: true });
|
|
21896
|
+
}
|
|
21897
|
+
}
|
|
21898
|
+
return tiles;
|
|
21899
|
+
}
|
|
21900
|
+
function tilesToIso(tiles, manifest) {
|
|
21901
|
+
return tiles.map((t) => {
|
|
21902
|
+
const key = t.terrain ?? "grass";
|
|
21903
|
+
const sprite = t.terrainSprite ?? resolveManifestUrl2(manifest, manifest?.terrains?.[key]) ?? resolveManifestUrl2(manifest, manifest?.terrains?.grass);
|
|
21904
|
+
return {
|
|
21905
|
+
x: t.x,
|
|
21906
|
+
y: t.y,
|
|
21907
|
+
terrain: t.terrain,
|
|
21908
|
+
terrainSprite: sprite,
|
|
21909
|
+
passable: t.passable
|
|
21910
|
+
};
|
|
21911
|
+
});
|
|
21912
|
+
}
|
|
21913
|
+
function buildingsToFeatures(buildings, manifest) {
|
|
21914
|
+
return buildings.map((b) => ({
|
|
21915
|
+
id: b.id,
|
|
21916
|
+
x: b.x,
|
|
21917
|
+
y: b.y,
|
|
21918
|
+
type: b.type,
|
|
21919
|
+
sprite: resolveManifestUrl2(manifest, manifest?.features?.[b.type])
|
|
21920
|
+
}));
|
|
21921
|
+
}
|
|
21922
|
+
function CityBuilderBoard({
|
|
21923
|
+
entity,
|
|
21924
|
+
tiles: propTiles,
|
|
21925
|
+
buildings: propBuildings,
|
|
21926
|
+
assetManifest: propAssetManifest,
|
|
21927
|
+
buildTypes: propBuildTypes,
|
|
21928
|
+
pendingBuildType: propPendingBuildType,
|
|
21929
|
+
gold: propGold,
|
|
21930
|
+
wood: propWood,
|
|
21931
|
+
population: propPopulation,
|
|
21932
|
+
result: propResult,
|
|
21933
|
+
scale = 0.3,
|
|
21934
|
+
unitScale = 0.6,
|
|
21935
|
+
spriteHeightRatio = 1.5,
|
|
21936
|
+
spriteMaxWidthRatio = 0.7,
|
|
21937
|
+
selectBuildTypeEvent,
|
|
21938
|
+
placeBuildingEvent,
|
|
21939
|
+
gameEndEvent,
|
|
21940
|
+
className
|
|
21941
|
+
}) {
|
|
21942
|
+
const board = boardEntity(entity) ?? {};
|
|
21943
|
+
const eventBus = useEventBus();
|
|
21944
|
+
const { t } = useTranslate();
|
|
21945
|
+
const assetManifest = propAssetManifest ?? board.assetManifest;
|
|
21946
|
+
const entityTiles = useMemo(
|
|
21947
|
+
() => rows(board.tiles).map((r) => ({
|
|
21948
|
+
x: num(r.x),
|
|
21949
|
+
y: num(r.y),
|
|
21950
|
+
terrain: r.terrain == null ? void 0 : str(r.terrain),
|
|
21951
|
+
terrainSprite: r.terrainSprite == null ? void 0 : str(r.terrainSprite),
|
|
21952
|
+
passable: r.passable !== false
|
|
21953
|
+
})),
|
|
21954
|
+
[board.tiles]
|
|
21955
|
+
);
|
|
21956
|
+
const rawTiles = propTiles ?? entityTiles;
|
|
21957
|
+
const tiles = rawTiles.length >= CB_GRID_W * CB_GRID_H ? rawTiles : DEFAULT_CB_TILES;
|
|
21958
|
+
const entityBuildings = useMemo(
|
|
21959
|
+
() => rows(board.buildings).map((r) => ({
|
|
21960
|
+
id: str(r.id),
|
|
21961
|
+
x: num(r.x),
|
|
21962
|
+
y: num(r.y),
|
|
21963
|
+
type: str(r.type)
|
|
21964
|
+
})),
|
|
21965
|
+
[board.buildings]
|
|
21966
|
+
);
|
|
21967
|
+
const buildings = propBuildings ?? entityBuildings;
|
|
21968
|
+
const buildTypes = propBuildTypes ?? DEFAULT_BUILD_TYPES;
|
|
21969
|
+
const gold = propGold ?? num(board.gold, 100);
|
|
21970
|
+
const wood = propWood ?? num(board.wood, 80);
|
|
21971
|
+
const population = propPopulation ?? num(board.population, 0);
|
|
21972
|
+
const pendingBuildType = propPendingBuildType ?? (str(board.pendingBuildType) || buildTypes[0]?.type || "");
|
|
21973
|
+
const result = propResult ?? (str(board.result) || "none");
|
|
21974
|
+
const [hoveredTile, setHoveredTile] = useState(null);
|
|
21975
|
+
const emittedGameEnd = useRef(false);
|
|
21976
|
+
if (result !== "none" && !emittedGameEnd.current) {
|
|
21977
|
+
emittedGameEnd.current = true;
|
|
21978
|
+
if (gameEndEvent) {
|
|
21979
|
+
eventBus.emit(`UI:${gameEndEvent}`, { result });
|
|
21980
|
+
}
|
|
21981
|
+
}
|
|
21982
|
+
if (result === "none") {
|
|
21983
|
+
emittedGameEnd.current = false;
|
|
21984
|
+
}
|
|
21985
|
+
const pendingCost = useMemo(
|
|
21986
|
+
() => buildTypes.find((b) => b.type === pendingBuildType)?.cost ?? 0,
|
|
21987
|
+
[buildTypes, pendingBuildType]
|
|
21988
|
+
);
|
|
21989
|
+
const buildingPositions = useMemo(
|
|
21990
|
+
() => new Set(buildings.map((b) => `${b.x},${b.y}`)),
|
|
21991
|
+
[buildings]
|
|
21992
|
+
);
|
|
21993
|
+
const validMoves = useMemo(() => {
|
|
21994
|
+
if (result !== "none" || gold < pendingCost) return [];
|
|
21995
|
+
return tiles.filter(
|
|
21996
|
+
(t2) => t2.passable !== false && !buildingPositions.has(`${t2.x},${t2.y}`)
|
|
21997
|
+
).map((t2) => ({ x: t2.x, y: t2.y }));
|
|
21998
|
+
}, [tiles, buildingPositions, result, gold, pendingCost]);
|
|
21999
|
+
const isoTiles = useMemo(() => tilesToIso(tiles, assetManifest), [tiles, assetManifest]);
|
|
22000
|
+
const buildingFeatures = useMemo(() => buildingsToFeatures(buildings, assetManifest), [buildings, assetManifest]);
|
|
22001
|
+
const handleTileClick = useCallback((x, y) => {
|
|
22002
|
+
if (result !== "none") return;
|
|
22003
|
+
if (buildingPositions.has(`${x},${y}`)) return;
|
|
22004
|
+
if (gold < pendingCost) return;
|
|
22005
|
+
if (placeBuildingEvent) {
|
|
22006
|
+
eventBus.emit(`UI:${placeBuildingEvent}`, { x, y });
|
|
22007
|
+
}
|
|
22008
|
+
}, [result, buildingPositions, gold, pendingCost, placeBuildingEvent, eventBus]);
|
|
22009
|
+
const handleSelectBuildType = useCallback((buildType) => {
|
|
22010
|
+
if (selectBuildTypeEvent) {
|
|
22011
|
+
eventBus.emit(`UI:${selectBuildTypeEvent}`, { buildType });
|
|
22012
|
+
}
|
|
22013
|
+
}, [selectBuildTypeEvent, eventBus]);
|
|
22014
|
+
const canBuild = gold >= pendingCost && result === "none";
|
|
22015
|
+
return /* @__PURE__ */ jsxs(VStack, { className: cn("city-builder-board relative min-h-[600px] bg-background", className), gap: "none", children: [
|
|
22016
|
+
/* @__PURE__ */ jsxs(
|
|
22017
|
+
HStack,
|
|
22018
|
+
{
|
|
22019
|
+
className: "px-4 py-2 border-b border-border bg-surface",
|
|
22020
|
+
gap: "lg",
|
|
22021
|
+
align: "center",
|
|
22022
|
+
children: [
|
|
22023
|
+
/* @__PURE__ */ jsxs(HStack, { gap: "xs", align: "center", children: [
|
|
22024
|
+
/* @__PURE__ */ jsx(Typography, { variant: "small", color: "muted", children: t("cb.gold") ?? "Gold" }),
|
|
22025
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body2", weight: "bold", className: "text-warning", children: gold })
|
|
22026
|
+
] }),
|
|
22027
|
+
/* @__PURE__ */ jsxs(HStack, { gap: "xs", align: "center", children: [
|
|
22028
|
+
/* @__PURE__ */ jsx(Typography, { variant: "small", color: "muted", children: t("cb.wood") ?? "Wood" }),
|
|
22029
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body2", weight: "bold", className: "text-success", children: wood })
|
|
22030
|
+
] }),
|
|
22031
|
+
/* @__PURE__ */ jsxs(HStack, { gap: "xs", align: "center", children: [
|
|
22032
|
+
/* @__PURE__ */ jsx(Typography, { variant: "small", color: "muted", children: t("cb.population") ?? "Population" }),
|
|
22033
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body2", weight: "bold", children: population })
|
|
22034
|
+
] }),
|
|
22035
|
+
/* @__PURE__ */ jsx(HStack, { gap: "xs", align: "center", className: "ml-auto", children: buildTypes.map((b) => /* @__PURE__ */ jsxs(
|
|
22036
|
+
Button,
|
|
22037
|
+
{
|
|
22038
|
+
variant: b.type === pendingBuildType ? "primary" : "secondary",
|
|
22039
|
+
size: "sm",
|
|
22040
|
+
disabled: gold < b.cost || result !== "none",
|
|
22041
|
+
onClick: () => handleSelectBuildType(b.type),
|
|
22042
|
+
children: [
|
|
22043
|
+
b.label,
|
|
22044
|
+
" (",
|
|
22045
|
+
b.cost,
|
|
22046
|
+
")"
|
|
22047
|
+
]
|
|
22048
|
+
},
|
|
22049
|
+
b.type
|
|
22050
|
+
)) })
|
|
22051
|
+
]
|
|
22052
|
+
}
|
|
22053
|
+
),
|
|
22054
|
+
/* @__PURE__ */ jsxs(Box, { className: "relative flex-1", children: [
|
|
22055
|
+
/* @__PURE__ */ jsx(
|
|
22056
|
+
IsometricCanvas_default,
|
|
22057
|
+
{
|
|
22058
|
+
tiles: isoTiles,
|
|
22059
|
+
features: buildingFeatures,
|
|
22060
|
+
assetBaseUrl: assetManifest?.baseUrl,
|
|
22061
|
+
assetManifest,
|
|
22062
|
+
validMoves,
|
|
22063
|
+
hoveredTile,
|
|
22064
|
+
onTileClick: handleTileClick,
|
|
22065
|
+
onTileHover: (x, y) => setHoveredTile({ x, y }),
|
|
22066
|
+
onTileLeave: () => setHoveredTile(null),
|
|
22067
|
+
scale,
|
|
22068
|
+
unitScale,
|
|
22069
|
+
spriteHeightRatio,
|
|
22070
|
+
spriteMaxWidthRatio
|
|
22071
|
+
}
|
|
22072
|
+
),
|
|
22073
|
+
hoveredTile && canBuild && validMoves.some((m) => m.x === hoveredTile.x && m.y === hoveredTile.y) && /* @__PURE__ */ jsx(Box, { className: "absolute bottom-4 left-1/2 -translate-x-1/2 z-10 bg-background/80 rounded px-3 py-1 backdrop-blur-sm pointer-events-none", children: /* @__PURE__ */ jsx(Typography, { variant: "small", children: t("cb.placeBuilding") ?? `Build ${pendingBuildType} (${pendingCost} gold)` }) })
|
|
22074
|
+
] }),
|
|
22075
|
+
result !== "none" && /* @__PURE__ */ jsx(Box, { className: "absolute inset-0 z-50 flex items-center justify-center bg-background/70 backdrop-blur-sm", children: /* @__PURE__ */ jsxs(VStack, { className: "text-center p-8", gap: "lg", children: [
|
|
22076
|
+
/* @__PURE__ */ jsx(
|
|
22077
|
+
Typography,
|
|
22078
|
+
{
|
|
22079
|
+
variant: "h2",
|
|
22080
|
+
className: cn(
|
|
22081
|
+
"text-4xl font-black tracking-widest uppercase",
|
|
22082
|
+
result === "won" ? "text-warning" : "text-error"
|
|
22083
|
+
),
|
|
22084
|
+
children: result === "won" ? t("cb.victory") ?? "City Thrives!" : t("cb.defeat") ?? "City Collapsed!"
|
|
22085
|
+
}
|
|
22086
|
+
),
|
|
22087
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body1", className: "text-muted-foreground", children: result === "won" ? t("cb.reachedGoal") ?? `Your city reached a population of ${population}.` : t("cb.bankrupt") ?? "Your city ran out of resources." })
|
|
22088
|
+
] }) })
|
|
22089
|
+
] });
|
|
22090
|
+
}
|
|
22091
|
+
var CB_GRID_W, CB_GRID_H, DEFAULT_BUILD_TYPES, DEFAULT_CB_TILES;
|
|
22092
|
+
var init_CityBuilderBoard = __esm({
|
|
22093
|
+
"components/game/organisms/CityBuilderBoard.tsx"() {
|
|
22094
|
+
"use client";
|
|
22095
|
+
init_cn();
|
|
22096
|
+
init_useEventBus();
|
|
22097
|
+
init_Box();
|
|
22098
|
+
init_Button();
|
|
22099
|
+
init_Typography();
|
|
22100
|
+
init_Stack();
|
|
22101
|
+
init_IsometricCanvas();
|
|
22102
|
+
init_boardEntity();
|
|
22103
|
+
CB_GRID_W = 12;
|
|
22104
|
+
CB_GRID_H = 12;
|
|
22105
|
+
DEFAULT_BUILD_TYPES = [
|
|
22106
|
+
{ type: "house", label: "House", cost: 20 },
|
|
22107
|
+
{ type: "farm", label: "Farm", cost: 15 },
|
|
22108
|
+
{ type: "mine", label: "Mine", cost: 25 },
|
|
22109
|
+
{ type: "barracks", label: "Barracks", cost: 40 }
|
|
22110
|
+
];
|
|
22111
|
+
DEFAULT_CB_TILES = buildDefaultCBTiles();
|
|
22112
|
+
CityBuilderBoard.displayName = "CityBuilderBoard";
|
|
22113
|
+
}
|
|
22114
|
+
});
|
|
22115
|
+
function isEntityRow2(value) {
|
|
22116
|
+
return value != null && typeof value === "object" && !Array.isArray(value);
|
|
22117
|
+
}
|
|
22118
|
+
function CityBuilderTemplate({
|
|
22119
|
+
entity,
|
|
22120
|
+
title = "City Builder",
|
|
22121
|
+
tiles,
|
|
22122
|
+
buildings,
|
|
22123
|
+
buildTypes,
|
|
22124
|
+
pendingBuildType,
|
|
22125
|
+
assetManifest,
|
|
22126
|
+
gold,
|
|
22127
|
+
wood,
|
|
22128
|
+
population,
|
|
22129
|
+
result,
|
|
22130
|
+
scale,
|
|
22131
|
+
unitScale,
|
|
22132
|
+
selectBuildTypeEvent,
|
|
22133
|
+
placeBuildingEvent,
|
|
22134
|
+
gameEndEvent,
|
|
22135
|
+
className
|
|
22136
|
+
}) {
|
|
22137
|
+
const resolved = isEntityRow2(entity) ? entity : void 0;
|
|
22138
|
+
return /* @__PURE__ */ jsxs(
|
|
22139
|
+
Box,
|
|
22140
|
+
{
|
|
22141
|
+
display: "flex",
|
|
22142
|
+
fullHeight: true,
|
|
22143
|
+
className: cn("city-builder-template flex-col", className),
|
|
22144
|
+
children: [
|
|
22145
|
+
/* @__PURE__ */ jsx(
|
|
22146
|
+
HStack,
|
|
22147
|
+
{
|
|
22148
|
+
gap: "sm",
|
|
22149
|
+
align: "center",
|
|
22150
|
+
className: "px-4 py-3 border-b-2 border-border bg-surface shrink-0",
|
|
22151
|
+
children: /* @__PURE__ */ jsx(Typography, { variant: "h4", children: title })
|
|
22152
|
+
}
|
|
22153
|
+
),
|
|
22154
|
+
/* @__PURE__ */ jsx(Box, { className: "flex-1 relative overflow-hidden", children: /* @__PURE__ */ jsx(
|
|
22155
|
+
CityBuilderBoard,
|
|
22156
|
+
{
|
|
22157
|
+
entity: resolved,
|
|
22158
|
+
tiles,
|
|
22159
|
+
buildings,
|
|
22160
|
+
buildTypes,
|
|
22161
|
+
pendingBuildType,
|
|
22162
|
+
assetManifest,
|
|
22163
|
+
gold,
|
|
22164
|
+
wood,
|
|
22165
|
+
population,
|
|
22166
|
+
result,
|
|
22167
|
+
scale,
|
|
22168
|
+
unitScale,
|
|
22169
|
+
selectBuildTypeEvent,
|
|
22170
|
+
placeBuildingEvent,
|
|
22171
|
+
gameEndEvent,
|
|
22172
|
+
className: "h-full"
|
|
22173
|
+
}
|
|
22174
|
+
) })
|
|
22175
|
+
]
|
|
22176
|
+
}
|
|
22177
|
+
);
|
|
22178
|
+
}
|
|
22179
|
+
var init_CityBuilderTemplate = __esm({
|
|
22180
|
+
"components/game/templates/CityBuilderTemplate.tsx"() {
|
|
22181
|
+
init_cn();
|
|
22182
|
+
init_Box();
|
|
22183
|
+
init_Stack();
|
|
22184
|
+
init_Typography();
|
|
22185
|
+
init_CityBuilderBoard();
|
|
22186
|
+
CityBuilderTemplate.displayName = "CityBuilderTemplate";
|
|
22187
|
+
}
|
|
22188
|
+
});
|
|
21251
22189
|
function ClassifierBoard({
|
|
21252
22190
|
entity,
|
|
21253
22191
|
completeEvent = "PUZZLE_COMPLETE",
|
|
@@ -22062,7 +23000,7 @@ function CraftingRecipe({
|
|
|
22062
23000
|
className
|
|
22063
23001
|
}) {
|
|
22064
23002
|
const eventBus = useEventBus();
|
|
22065
|
-
const handleCraft =
|
|
23003
|
+
const handleCraft = React85.useCallback(() => {
|
|
22066
23004
|
onCraft?.();
|
|
22067
23005
|
if (craftEvent) {
|
|
22068
23006
|
eventBus.emit(craftEvent, { output: output.label });
|
|
@@ -22079,7 +23017,7 @@ function CraftingRecipe({
|
|
|
22079
23017
|
children: [
|
|
22080
23018
|
/* @__PURE__ */ jsx(HStack, { gap: "xs", className: "flex-wrap items-center", children: inputs.map((ingredient, index) => {
|
|
22081
23019
|
const hasSufficient = ingredient.available >= ingredient.required;
|
|
22082
|
-
return /* @__PURE__ */ jsxs(
|
|
23020
|
+
return /* @__PURE__ */ jsxs(React85.Fragment, { children: [
|
|
22083
23021
|
/* @__PURE__ */ jsx(Box, { className: "relative", children: /* @__PURE__ */ jsx(
|
|
22084
23022
|
ItemSlot,
|
|
22085
23023
|
{
|
|
@@ -22151,8 +23089,8 @@ function DPad({
|
|
|
22151
23089
|
}) {
|
|
22152
23090
|
const eventBus = useEventBus();
|
|
22153
23091
|
const sizes = sizeMap15[size];
|
|
22154
|
-
const [activeDirections, setActiveDirections] =
|
|
22155
|
-
const handlePress =
|
|
23092
|
+
const [activeDirections, setActiveDirections] = React85.useState(/* @__PURE__ */ new Set());
|
|
23093
|
+
const handlePress = React85.useCallback(
|
|
22156
23094
|
(direction) => {
|
|
22157
23095
|
setActiveDirections((prev) => new Set(prev).add(direction));
|
|
22158
23096
|
if (directionEvent) eventBus.emit(`UI:${directionEvent}`, { direction, pressed: true });
|
|
@@ -22160,7 +23098,7 @@ function DPad({
|
|
|
22160
23098
|
},
|
|
22161
23099
|
[directionEvent, eventBus, onDirection]
|
|
22162
23100
|
);
|
|
22163
|
-
const handleRelease =
|
|
23101
|
+
const handleRelease = React85.useCallback(
|
|
22164
23102
|
(direction) => {
|
|
22165
23103
|
setActiveDirections((prev) => {
|
|
22166
23104
|
const next = new Set(prev);
|
|
@@ -22882,10 +23820,84 @@ function SubMenu({
|
|
|
22882
23820
|
);
|
|
22883
23821
|
return typeof document !== "undefined" ? createPortal(panel, document.body) : panel;
|
|
22884
23822
|
}
|
|
23823
|
+
function MenuItemRow({
|
|
23824
|
+
item,
|
|
23825
|
+
itemId,
|
|
23826
|
+
hasSubMenu,
|
|
23827
|
+
isDanger,
|
|
23828
|
+
direction,
|
|
23829
|
+
isSubMenuOpen,
|
|
23830
|
+
activeSubMenuRef,
|
|
23831
|
+
eventBus,
|
|
23832
|
+
onItemClick,
|
|
23833
|
+
openSubMenu
|
|
23834
|
+
}) {
|
|
23835
|
+
const rowRef = useRef(null);
|
|
23836
|
+
const { triggerProps } = useTapReveal({
|
|
23837
|
+
enabled: hasSubMenu,
|
|
23838
|
+
onReveal: () => openSubMenu(itemId, rowRef.current),
|
|
23839
|
+
refs: [rowRef]
|
|
23840
|
+
});
|
|
23841
|
+
return /* @__PURE__ */ jsxs(Box, { children: [
|
|
23842
|
+
/* @__PURE__ */ jsx(
|
|
23843
|
+
Box,
|
|
23844
|
+
{
|
|
23845
|
+
ref: rowRef,
|
|
23846
|
+
as: "button",
|
|
23847
|
+
onClick: () => onItemClick({ ...item, id: itemId }, itemId),
|
|
23848
|
+
"aria-disabled": item.disabled || void 0,
|
|
23849
|
+
onMouseEnter: (e) => {
|
|
23850
|
+
if (hasSubMenu) openSubMenu(itemId, e.currentTarget);
|
|
23851
|
+
},
|
|
23852
|
+
onPointerDown: hasSubMenu ? triggerProps.onPointerDown : void 0,
|
|
23853
|
+
"data-testid": item.event ? `action-${item.event}` : void 0,
|
|
23854
|
+
className: cn(
|
|
23855
|
+
"w-full flex items-center justify-between gap-3 px-4 py-2 text-start",
|
|
23856
|
+
"text-sm transition-colors",
|
|
23857
|
+
"hover:bg-muted",
|
|
23858
|
+
"focus:outline-none focus:bg-muted",
|
|
23859
|
+
"disabled:opacity-50 disabled:cursor-not-allowed",
|
|
23860
|
+
item.disabled && "cursor-not-allowed",
|
|
23861
|
+
isDanger && "text-error hover:bg-error/10"
|
|
23862
|
+
),
|
|
23863
|
+
children: /* @__PURE__ */ jsxs(Box, { className: "flex items-center gap-3 flex-1 min-w-0", children: [
|
|
23864
|
+
item.icon && (typeof item.icon === "string" ? /* @__PURE__ */ jsx(Icon, { name: item.icon, size: "sm", className: "flex-shrink-0" }) : /* @__PURE__ */ jsx(Icon, { icon: item.icon, size: "sm", className: "flex-shrink-0" })),
|
|
23865
|
+
/* @__PURE__ */ jsx(
|
|
23866
|
+
Typography,
|
|
23867
|
+
{
|
|
23868
|
+
variant: "small",
|
|
23869
|
+
className: cn("flex-1", isDanger && "text-red-600"),
|
|
23870
|
+
children: item.label
|
|
23871
|
+
}
|
|
23872
|
+
),
|
|
23873
|
+
item.badge !== void 0 && /* @__PURE__ */ jsx(Badge, { variant: "default", size: "sm", children: item.badge }),
|
|
23874
|
+
hasSubMenu && /* @__PURE__ */ jsx(
|
|
23875
|
+
Icon,
|
|
23876
|
+
{
|
|
23877
|
+
name: direction === "rtl" ? "chevron-left" : "chevron-right",
|
|
23878
|
+
size: "sm",
|
|
23879
|
+
className: "flex-shrink-0"
|
|
23880
|
+
}
|
|
23881
|
+
)
|
|
23882
|
+
] })
|
|
23883
|
+
}
|
|
23884
|
+
),
|
|
23885
|
+
hasSubMenu && isSubMenuOpen && item.subMenu && /* @__PURE__ */ jsx(
|
|
23886
|
+
SubMenu,
|
|
23887
|
+
{
|
|
23888
|
+
items: item.subMenu,
|
|
23889
|
+
itemRef: activeSubMenuRef,
|
|
23890
|
+
direction,
|
|
23891
|
+
eventBus
|
|
23892
|
+
}
|
|
23893
|
+
)
|
|
23894
|
+
] });
|
|
23895
|
+
}
|
|
22885
23896
|
var MENU_GAP, menuContainerStyles, Menu;
|
|
22886
23897
|
var init_Menu = __esm({
|
|
22887
23898
|
"components/core/molecules/Menu.tsx"() {
|
|
22888
23899
|
"use client";
|
|
23900
|
+
init_useTapReveal();
|
|
22889
23901
|
init_Box();
|
|
22890
23902
|
init_Icon();
|
|
22891
23903
|
init_Divider();
|
|
@@ -22940,6 +23952,10 @@ var init_Menu = __esm({
|
|
|
22940
23952
|
setIsOpen(false);
|
|
22941
23953
|
}
|
|
22942
23954
|
};
|
|
23955
|
+
const openSubMenu = (itemId, el) => {
|
|
23956
|
+
setActiveSubMenu(itemId);
|
|
23957
|
+
setActiveSubMenuRef(el);
|
|
23958
|
+
};
|
|
22943
23959
|
useEffect(() => {
|
|
22944
23960
|
if (isOpen) {
|
|
22945
23961
|
updatePosition();
|
|
@@ -22967,8 +23983,8 @@ var init_Menu = __esm({
|
|
|
22967
23983
|
"bottom-end": "bottom-start"
|
|
22968
23984
|
};
|
|
22969
23985
|
const effectivePosition = direction === "rtl" ? rtlMirror[position] ?? position : position;
|
|
22970
|
-
const triggerChild =
|
|
22971
|
-
const triggerElement =
|
|
23986
|
+
const triggerChild = React85__default.isValidElement(trigger) ? trigger : /* @__PURE__ */ jsx(Typography, { variant: "small", as: "span", children: trigger });
|
|
23987
|
+
const triggerElement = React85__default.cloneElement(
|
|
22972
23988
|
triggerChild,
|
|
22973
23989
|
{
|
|
22974
23990
|
ref: triggerRef,
|
|
@@ -22983,61 +23999,22 @@ var init_Menu = __esm({
|
|
|
22983
23999
|
if (isDivider) {
|
|
22984
24000
|
return /* @__PURE__ */ jsx(Divider, { className: "my-1" }, `divider-${index}`);
|
|
22985
24001
|
}
|
|
22986
|
-
return /* @__PURE__ */
|
|
22987
|
-
|
|
22988
|
-
|
|
22989
|
-
|
|
22990
|
-
|
|
22991
|
-
|
|
22992
|
-
|
|
22993
|
-
|
|
22994
|
-
|
|
22995
|
-
|
|
22996
|
-
|
|
22997
|
-
|
|
22998
|
-
|
|
22999
|
-
|
|
23000
|
-
|
|
23001
|
-
|
|
23002
|
-
"text-sm transition-colors",
|
|
23003
|
-
"hover:bg-muted",
|
|
23004
|
-
"focus:outline-none focus:bg-muted",
|
|
23005
|
-
"disabled:opacity-50 disabled:cursor-not-allowed",
|
|
23006
|
-
item.disabled && "cursor-not-allowed",
|
|
23007
|
-
isDanger && "text-error hover:bg-error/10"
|
|
23008
|
-
),
|
|
23009
|
-
children: /* @__PURE__ */ jsxs(Box, { className: "flex items-center gap-3 flex-1 min-w-0", children: [
|
|
23010
|
-
item.icon && (typeof item.icon === "string" ? /* @__PURE__ */ jsx(Icon, { name: item.icon, size: "sm", className: "flex-shrink-0" }) : /* @__PURE__ */ jsx(Icon, { icon: item.icon, size: "sm", className: "flex-shrink-0" })),
|
|
23011
|
-
/* @__PURE__ */ jsx(
|
|
23012
|
-
Typography,
|
|
23013
|
-
{
|
|
23014
|
-
variant: "small",
|
|
23015
|
-
className: cn("flex-1", isDanger && "text-red-600"),
|
|
23016
|
-
children: item.label
|
|
23017
|
-
}
|
|
23018
|
-
),
|
|
23019
|
-
item.badge !== void 0 && /* @__PURE__ */ jsx(Badge, { variant: "default", size: "sm", children: item.badge }),
|
|
23020
|
-
hasSubMenu && /* @__PURE__ */ jsx(
|
|
23021
|
-
Icon,
|
|
23022
|
-
{
|
|
23023
|
-
name: direction === "rtl" ? "chevron-left" : "chevron-right",
|
|
23024
|
-
size: "sm",
|
|
23025
|
-
className: "flex-shrink-0"
|
|
23026
|
-
}
|
|
23027
|
-
)
|
|
23028
|
-
] })
|
|
23029
|
-
}
|
|
23030
|
-
),
|
|
23031
|
-
hasSubMenu && activeSubMenu === itemId && item.subMenu && /* @__PURE__ */ jsx(
|
|
23032
|
-
SubMenu,
|
|
23033
|
-
{
|
|
23034
|
-
items: item.subMenu,
|
|
23035
|
-
itemRef: activeSubMenuRef,
|
|
23036
|
-
direction,
|
|
23037
|
-
eventBus
|
|
23038
|
-
}
|
|
23039
|
-
)
|
|
23040
|
-
] }, itemId);
|
|
24002
|
+
return /* @__PURE__ */ jsx(
|
|
24003
|
+
MenuItemRow,
|
|
24004
|
+
{
|
|
24005
|
+
item,
|
|
24006
|
+
itemId,
|
|
24007
|
+
hasSubMenu,
|
|
24008
|
+
isDanger,
|
|
24009
|
+
direction,
|
|
24010
|
+
isSubMenuOpen: activeSubMenu === itemId,
|
|
24011
|
+
activeSubMenuRef,
|
|
24012
|
+
eventBus,
|
|
24013
|
+
onItemClick: handleItemClick,
|
|
24014
|
+
openSubMenu
|
|
24015
|
+
},
|
|
24016
|
+
itemId
|
|
24017
|
+
);
|
|
23041
24018
|
});
|
|
23042
24019
|
const panel = isOpen && triggerRect ? /* @__PURE__ */ jsxs(
|
|
23043
24020
|
"div",
|
|
@@ -23102,14 +24079,14 @@ function useDataDnd(args) {
|
|
|
23102
24079
|
const isZone = Boolean(dragGroup || accepts || sortable);
|
|
23103
24080
|
const enabled = isZone || Boolean(dndRoot);
|
|
23104
24081
|
const eventBus = useEventBus();
|
|
23105
|
-
const parentRoot =
|
|
24082
|
+
const parentRoot = React85__default.useContext(RootCtx);
|
|
23106
24083
|
const isRoot = enabled && parentRoot === null;
|
|
23107
|
-
const zoneId =
|
|
24084
|
+
const zoneId = React85__default.useId();
|
|
23108
24085
|
const ownGroup = dragGroup ?? accepts ?? zoneId;
|
|
23109
|
-
const [optimisticOrders, setOptimisticOrders] =
|
|
23110
|
-
const optimisticOrdersRef =
|
|
24086
|
+
const [optimisticOrders, setOptimisticOrders] = React85__default.useState(() => /* @__PURE__ */ new Map());
|
|
24087
|
+
const optimisticOrdersRef = React85__default.useRef(optimisticOrders);
|
|
23111
24088
|
optimisticOrdersRef.current = optimisticOrders;
|
|
23112
|
-
const clearOptimisticOrder =
|
|
24089
|
+
const clearOptimisticOrder = React85__default.useCallback((group) => {
|
|
23113
24090
|
setOptimisticOrders((prev) => {
|
|
23114
24091
|
if (!prev.has(group)) return prev;
|
|
23115
24092
|
const next = new Map(prev);
|
|
@@ -23134,7 +24111,7 @@ function useDataDnd(args) {
|
|
|
23134
24111
|
const raw = it[dndItemIdField];
|
|
23135
24112
|
return String(raw ?? `__idx_${idx}`);
|
|
23136
24113
|
}).join("|");
|
|
23137
|
-
const itemIds =
|
|
24114
|
+
const itemIds = React85__default.useMemo(
|
|
23138
24115
|
() => orderedItems.map((it, idx) => {
|
|
23139
24116
|
const raw = it[dndItemIdField];
|
|
23140
24117
|
return raw ?? `__idx_${idx}`;
|
|
@@ -23142,7 +24119,7 @@ function useDataDnd(args) {
|
|
|
23142
24119
|
[itemIdsSignature]
|
|
23143
24120
|
);
|
|
23144
24121
|
const itemsContentSig = items.map((it, idx) => String(it[dndItemIdField] ?? `__${idx}`)).join("|");
|
|
23145
|
-
|
|
24122
|
+
React85__default.useEffect(() => {
|
|
23146
24123
|
const root = isRoot ? null : parentRoot;
|
|
23147
24124
|
if (root) {
|
|
23148
24125
|
root.clearOptimisticOrder(ownGroup);
|
|
@@ -23150,20 +24127,20 @@ function useDataDnd(args) {
|
|
|
23150
24127
|
clearOptimisticOrder(ownGroup);
|
|
23151
24128
|
}
|
|
23152
24129
|
}, [itemsContentSig, ownGroup]);
|
|
23153
|
-
const zonesRef =
|
|
23154
|
-
const registerZone =
|
|
24130
|
+
const zonesRef = React85__default.useRef(/* @__PURE__ */ new Map());
|
|
24131
|
+
const registerZone = React85__default.useCallback((zoneId2, meta2) => {
|
|
23155
24132
|
zonesRef.current.set(zoneId2, meta2);
|
|
23156
24133
|
}, []);
|
|
23157
|
-
const unregisterZone =
|
|
24134
|
+
const unregisterZone = React85__default.useCallback((zoneId2) => {
|
|
23158
24135
|
zonesRef.current.delete(zoneId2);
|
|
23159
24136
|
}, []);
|
|
23160
|
-
const [activeDrag, setActiveDrag] =
|
|
23161
|
-
const [overZoneGroup, setOverZoneGroup] =
|
|
23162
|
-
const meta =
|
|
24137
|
+
const [activeDrag, setActiveDrag] = React85__default.useState(null);
|
|
24138
|
+
const [overZoneGroup, setOverZoneGroup] = React85__default.useState(null);
|
|
24139
|
+
const meta = React85__default.useMemo(
|
|
23163
24140
|
() => ({ group: ownGroup, dropEvent, reorderEvent, positionEvent, itemIds, rawItems: items, idField: dndItemIdField }),
|
|
23164
24141
|
[ownGroup, dropEvent, reorderEvent, positionEvent, itemIds, items, dndItemIdField]
|
|
23165
24142
|
);
|
|
23166
|
-
|
|
24143
|
+
React85__default.useEffect(() => {
|
|
23167
24144
|
const target = isRoot ? null : parentRoot;
|
|
23168
24145
|
if (!target) {
|
|
23169
24146
|
zonesRef.current.set(zoneId, meta);
|
|
@@ -23182,7 +24159,7 @@ function useDataDnd(args) {
|
|
|
23182
24159
|
}, [parentRoot, isRoot, zoneId, meta]);
|
|
23183
24160
|
const sensors = useAlmadarDndSensors(true);
|
|
23184
24161
|
const collisionDetection = almadarDndCollisionDetection;
|
|
23185
|
-
const findZoneByItem =
|
|
24162
|
+
const findZoneByItem = React85__default.useCallback(
|
|
23186
24163
|
(id) => {
|
|
23187
24164
|
for (const z of zonesRef.current.values()) {
|
|
23188
24165
|
if (z.itemIds.includes(id)) return z;
|
|
@@ -23191,7 +24168,7 @@ function useDataDnd(args) {
|
|
|
23191
24168
|
},
|
|
23192
24169
|
[]
|
|
23193
24170
|
);
|
|
23194
|
-
|
|
24171
|
+
React85__default.useCallback(
|
|
23195
24172
|
(group) => {
|
|
23196
24173
|
for (const z of zonesRef.current.values()) {
|
|
23197
24174
|
if (z.group === group) return z;
|
|
@@ -23200,7 +24177,7 @@ function useDataDnd(args) {
|
|
|
23200
24177
|
},
|
|
23201
24178
|
[]
|
|
23202
24179
|
);
|
|
23203
|
-
const handleDragEnd =
|
|
24180
|
+
const handleDragEnd = React85__default.useCallback(
|
|
23204
24181
|
(event) => {
|
|
23205
24182
|
const { active, over } = event;
|
|
23206
24183
|
const activeIdStr = String(active.id);
|
|
@@ -23291,8 +24268,8 @@ function useDataDnd(args) {
|
|
|
23291
24268
|
},
|
|
23292
24269
|
[eventBus]
|
|
23293
24270
|
);
|
|
23294
|
-
const sortableData =
|
|
23295
|
-
const SortableItem =
|
|
24271
|
+
const sortableData = React85__default.useMemo(() => ({ dndGroup: ownGroup }), [ownGroup]);
|
|
24272
|
+
const SortableItem = React85__default.useCallback(
|
|
23296
24273
|
({ id, children }) => {
|
|
23297
24274
|
const {
|
|
23298
24275
|
attributes,
|
|
@@ -23332,7 +24309,7 @@ function useDataDnd(args) {
|
|
|
23332
24309
|
id: droppableId,
|
|
23333
24310
|
data: sortableData
|
|
23334
24311
|
});
|
|
23335
|
-
const ctx =
|
|
24312
|
+
const ctx = React85__default.useContext(RootCtx);
|
|
23336
24313
|
const activeDrag2 = ctx?.activeDrag ?? null;
|
|
23337
24314
|
const overZoneGroup2 = ctx?.overZoneGroup ?? null;
|
|
23338
24315
|
const isThisZoneOver = overZoneGroup2 === ownGroup;
|
|
@@ -23347,7 +24324,7 @@ function useDataDnd(args) {
|
|
|
23347
24324
|
showForeignPlaceholder,
|
|
23348
24325
|
ctxAvailable: ctx != null
|
|
23349
24326
|
});
|
|
23350
|
-
|
|
24327
|
+
React85__default.useEffect(() => {
|
|
23351
24328
|
dndLog.info("dropzone:isOver:change", { droppableId, group: ownGroup, isOver, isThisZoneOver, showForeignPlaceholder, activeDragSourceGroup: activeDrag2?.sourceGroup ?? null });
|
|
23352
24329
|
}, [droppableId, isOver, isThisZoneOver, showForeignPlaceholder]);
|
|
23353
24330
|
return /* @__PURE__ */ jsx(
|
|
@@ -23361,11 +24338,11 @@ function useDataDnd(args) {
|
|
|
23361
24338
|
}
|
|
23362
24339
|
);
|
|
23363
24340
|
};
|
|
23364
|
-
const rootContextValue =
|
|
24341
|
+
const rootContextValue = React85__default.useMemo(
|
|
23365
24342
|
() => ({ registerZone, unregisterZone, activeDrag, overZoneGroup, optimisticOrders, clearOptimisticOrder }),
|
|
23366
24343
|
[registerZone, unregisterZone, activeDrag, overZoneGroup, optimisticOrders, clearOptimisticOrder]
|
|
23367
24344
|
);
|
|
23368
|
-
const handleDragStart =
|
|
24345
|
+
const handleDragStart = React85__default.useCallback((event) => {
|
|
23369
24346
|
const sourceZone = findZoneByItem(event.active.id);
|
|
23370
24347
|
const rect = event.active.rect.current.initial;
|
|
23371
24348
|
const height = rect?.height && rect.height > 0 ? rect.height : 64;
|
|
@@ -23384,7 +24361,7 @@ function useDataDnd(args) {
|
|
|
23384
24361
|
isRoot
|
|
23385
24362
|
});
|
|
23386
24363
|
}, [findZoneByItem, isRoot, zoneId]);
|
|
23387
|
-
const handleDragOver =
|
|
24364
|
+
const handleDragOver = React85__default.useCallback((event) => {
|
|
23388
24365
|
const { active, over } = event;
|
|
23389
24366
|
const overData = over?.data?.current;
|
|
23390
24367
|
const overGroup = overData?.dndGroup ?? null;
|
|
@@ -23454,7 +24431,7 @@ function useDataDnd(args) {
|
|
|
23454
24431
|
return next;
|
|
23455
24432
|
});
|
|
23456
24433
|
}, []);
|
|
23457
|
-
const handleDragCancel =
|
|
24434
|
+
const handleDragCancel = React85__default.useCallback((event) => {
|
|
23458
24435
|
setActiveDrag(null);
|
|
23459
24436
|
setOverZoneGroup(null);
|
|
23460
24437
|
dndLog.warn("dragCancel", {
|
|
@@ -23462,12 +24439,12 @@ function useDataDnd(args) {
|
|
|
23462
24439
|
reason: "dnd-kit cancelled the drag (escape key, pointer interrupted, or external)"
|
|
23463
24440
|
});
|
|
23464
24441
|
}, []);
|
|
23465
|
-
const handleDragEndWithCleanup =
|
|
24442
|
+
const handleDragEndWithCleanup = React85__default.useCallback((event) => {
|
|
23466
24443
|
handleDragEnd(event);
|
|
23467
24444
|
setActiveDrag(null);
|
|
23468
24445
|
setOverZoneGroup(null);
|
|
23469
24446
|
}, [handleDragEnd]);
|
|
23470
|
-
const wrapContainer =
|
|
24447
|
+
const wrapContainer = React85__default.useCallback(
|
|
23471
24448
|
(children) => {
|
|
23472
24449
|
if (!enabled) return children;
|
|
23473
24450
|
const strategy = layout === "grid" ? rectSortingStrategy : verticalListSortingStrategy;
|
|
@@ -23521,7 +24498,7 @@ var init_useDataDnd = __esm({
|
|
|
23521
24498
|
init_useAlmadarDndCollision();
|
|
23522
24499
|
init_Box();
|
|
23523
24500
|
dndLog = createLogger("almadar:ui:dnd");
|
|
23524
|
-
RootCtx =
|
|
24501
|
+
RootCtx = React85__default.createContext(null);
|
|
23525
24502
|
}
|
|
23526
24503
|
});
|
|
23527
24504
|
function renderIconInput(icon, props) {
|
|
@@ -24047,7 +25024,7 @@ function DataList({
|
|
|
24047
25024
|
}) {
|
|
24048
25025
|
const eventBus = useEventBus();
|
|
24049
25026
|
const { t } = useTranslate();
|
|
24050
|
-
const [visibleCount, setVisibleCount] =
|
|
25027
|
+
const [visibleCount, setVisibleCount] = React85__default.useState(pageSize || Infinity);
|
|
24051
25028
|
const fieldDefs = fields ?? columns ?? [];
|
|
24052
25029
|
const allDataRaw = Array.isArray(entity) ? entity : entity ? [entity] : [];
|
|
24053
25030
|
const dnd = useDataDnd({
|
|
@@ -24066,7 +25043,7 @@ function DataList({
|
|
|
24066
25043
|
const data = pageSize > 0 ? allData.slice(0, visibleCount) : allData;
|
|
24067
25044
|
const hasMoreLocal = pageSize > 0 && visibleCount < allData.length;
|
|
24068
25045
|
const hasRenderProp = typeof children === "function";
|
|
24069
|
-
|
|
25046
|
+
React85__default.useEffect(() => {
|
|
24070
25047
|
const renderItemTypeOf = typeof schemaRenderItem;
|
|
24071
25048
|
const childrenTypeOf = typeof children;
|
|
24072
25049
|
if (data.length > 0 && !hasRenderProp) {
|
|
@@ -24171,7 +25148,7 @@ function DataList({
|
|
|
24171
25148
|
const items2 = data.map((item) => item);
|
|
24172
25149
|
const groups2 = groupBy ? groupData(items2, groupBy) : [{ label: "", items: items2 }];
|
|
24173
25150
|
const contentField = titleField?.name ?? fieldDefs[0]?.name ?? "";
|
|
24174
|
-
return /* @__PURE__ */ jsx(VStack, { gap: "sm", className: cn("py-2", className), children: groups2.map((group, gi) => /* @__PURE__ */ jsxs(
|
|
25151
|
+
return /* @__PURE__ */ jsx(VStack, { gap: "sm", className: cn("py-2", className), children: groups2.map((group, gi) => /* @__PURE__ */ jsxs(React85__default.Fragment, { children: [
|
|
24175
25152
|
group.label && /* @__PURE__ */ jsx(Divider, { label: group.label, className: "my-2" }),
|
|
24176
25153
|
group.items.map((itemData, index) => {
|
|
24177
25154
|
const id = itemData.id || `${gi}-${index}`;
|
|
@@ -24312,7 +25289,7 @@ function DataList({
|
|
|
24312
25289
|
className
|
|
24313
25290
|
),
|
|
24314
25291
|
children: [
|
|
24315
|
-
groups.map((group, gi) => /* @__PURE__ */ jsxs(
|
|
25292
|
+
groups.map((group, gi) => /* @__PURE__ */ jsxs(React85__default.Fragment, { children: [
|
|
24316
25293
|
group.label && /* @__PURE__ */ jsx(Divider, { label: group.label, className: gi > 0 ? "mt-4" : "mt-0" }),
|
|
24317
25294
|
group.items.map(
|
|
24318
25295
|
(itemData, index) => renderItem(itemData, index, gi === groups.length - 1 && index === group.items.length - 1)
|
|
@@ -25228,7 +26205,7 @@ var init_Grid = __esm({
|
|
|
25228
26205
|
as: Component2 = "div"
|
|
25229
26206
|
}) => {
|
|
25230
26207
|
const mergedStyle = rows2 ? { gridTemplateRows: `repeat(${rows2}, minmax(0, 1fr))`, ...style } : style;
|
|
25231
|
-
return
|
|
26208
|
+
return React85__default.createElement(
|
|
25232
26209
|
Component2,
|
|
25233
26210
|
{
|
|
25234
26211
|
className: cn(
|
|
@@ -25340,6 +26317,7 @@ var init_Popover = __esm({
|
|
|
25340
26317
|
"use client";
|
|
25341
26318
|
init_Typography();
|
|
25342
26319
|
init_cn();
|
|
26320
|
+
init_useTapReveal();
|
|
25343
26321
|
arrowClasses = {
|
|
25344
26322
|
top: "top-full left-1/2 -translate-x-1/2 border-t-white border-l-transparent border-r-transparent border-b-transparent",
|
|
25345
26323
|
bottom: "bottom-full left-1/2 -translate-x-1/2 border-b-white border-l-transparent border-r-transparent border-t-transparent",
|
|
@@ -25410,18 +26388,32 @@ var init_Popover = __esm({
|
|
|
25410
26388
|
document.addEventListener("mousedown", handleClickOutside);
|
|
25411
26389
|
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
25412
26390
|
}, [isOpen, trigger]);
|
|
25413
|
-
const triggerProps
|
|
26391
|
+
const { triggerProps: tapTriggerProps } = useTapReveal({
|
|
26392
|
+
enabled: trigger === "hover",
|
|
26393
|
+
onReveal: handleOpen,
|
|
26394
|
+
onDismiss: handleClose,
|
|
26395
|
+
refs: [triggerRef, popoverRef]
|
|
26396
|
+
});
|
|
26397
|
+
const handlerProps = trigger === "click" ? {
|
|
25414
26398
|
onClick: handleToggle
|
|
25415
26399
|
} : {
|
|
25416
26400
|
onMouseEnter: handleOpen,
|
|
25417
|
-
onMouseLeave: handleClose
|
|
26401
|
+
onMouseLeave: handleClose,
|
|
26402
|
+
onPointerDown: tapTriggerProps.onPointerDown
|
|
25418
26403
|
};
|
|
25419
|
-
const childElement =
|
|
25420
|
-
const
|
|
26404
|
+
const childElement = React85__default.isValidElement(children) ? children : /* @__PURE__ */ jsx("span", { children });
|
|
26405
|
+
const childPointerDown = childElement.props.onPointerDown;
|
|
26406
|
+
const triggerElement = React85__default.cloneElement(
|
|
25421
26407
|
childElement,
|
|
25422
26408
|
{
|
|
25423
26409
|
ref: triggerRef,
|
|
25424
|
-
...
|
|
26410
|
+
...handlerProps,
|
|
26411
|
+
...trigger === "hover" ? {
|
|
26412
|
+
onPointerDown: (e) => {
|
|
26413
|
+
tapTriggerProps.onPointerDown(e);
|
|
26414
|
+
childPointerDown?.(e);
|
|
26415
|
+
}
|
|
26416
|
+
} : void 0
|
|
25425
26417
|
}
|
|
25426
26418
|
);
|
|
25427
26419
|
const panel = isOpen && triggerRect ? /* @__PURE__ */ jsxs(
|
|
@@ -25952,6 +26944,7 @@ var init_Tooltip = __esm({
|
|
|
25952
26944
|
"use client";
|
|
25953
26945
|
init_Typography();
|
|
25954
26946
|
init_cn();
|
|
26947
|
+
init_useTapReveal();
|
|
25955
26948
|
TRIGGER_GAP2 = 8;
|
|
25956
26949
|
arrowClasses2 = {
|
|
25957
26950
|
top: "top-full left-1/2 -translate-x-1/2 border-t-primary border-l-transparent border-r-transparent border-b-transparent",
|
|
@@ -25996,6 +26989,11 @@ var init_Tooltip = __esm({
|
|
|
25996
26989
|
setIsVisible(false);
|
|
25997
26990
|
}, hideDelay);
|
|
25998
26991
|
};
|
|
26992
|
+
const { triggerProps } = useTapReveal({
|
|
26993
|
+
onReveal: handleMouseEnter,
|
|
26994
|
+
onDismiss: handleMouseLeave,
|
|
26995
|
+
refs: [triggerRef, tooltipRef]
|
|
26996
|
+
});
|
|
25999
26997
|
useLayoutEffect(() => {
|
|
26000
26998
|
if (isVisible) {
|
|
26001
26999
|
updatePosition();
|
|
@@ -26007,13 +27005,18 @@ var init_Tooltip = __esm({
|
|
|
26007
27005
|
if (hideTimeoutRef.current) clearTimeout(hideTimeoutRef.current);
|
|
26008
27006
|
};
|
|
26009
27007
|
}, []);
|
|
26010
|
-
const triggerElement =
|
|
26011
|
-
const
|
|
27008
|
+
const triggerElement = React85__default.isValidElement(children) ? children : /* @__PURE__ */ jsx("span", { children });
|
|
27009
|
+
const childPointerDown = triggerElement.props.onPointerDown;
|
|
27010
|
+
const trigger = React85__default.cloneElement(triggerElement, {
|
|
26012
27011
|
ref: triggerRef,
|
|
26013
27012
|
onMouseEnter: handleMouseEnter,
|
|
26014
27013
|
onMouseLeave: handleMouseLeave,
|
|
26015
27014
|
onFocus: handleMouseEnter,
|
|
26016
|
-
onBlur: handleMouseLeave
|
|
27015
|
+
onBlur: handleMouseLeave,
|
|
27016
|
+
onPointerDown: (e) => {
|
|
27017
|
+
triggerProps.onPointerDown(e);
|
|
27018
|
+
childPointerDown?.(e);
|
|
27019
|
+
}
|
|
26017
27020
|
});
|
|
26018
27021
|
const tooltipContent = isVisible && triggerRect ? /* @__PURE__ */ jsxs(
|
|
26019
27022
|
"div",
|
|
@@ -26094,7 +27097,7 @@ var init_WizardProgress = __esm({
|
|
|
26094
27097
|
children: /* @__PURE__ */ jsx("div", { className: "flex items-center gap-2", children: normalizedSteps.map((step, index) => {
|
|
26095
27098
|
const isActive = index === currentStep;
|
|
26096
27099
|
const isCompleted = index < currentStep;
|
|
26097
|
-
return /* @__PURE__ */ jsxs(
|
|
27100
|
+
return /* @__PURE__ */ jsxs(React85__default.Fragment, { children: [
|
|
26098
27101
|
/* @__PURE__ */ jsx(
|
|
26099
27102
|
"button",
|
|
26100
27103
|
{
|
|
@@ -27055,7 +28058,7 @@ var init_ProgressDots = __esm({
|
|
|
27055
28058
|
}
|
|
27056
28059
|
});
|
|
27057
28060
|
function StatBadge({
|
|
27058
|
-
assetUrl
|
|
28061
|
+
assetUrl,
|
|
27059
28062
|
label,
|
|
27060
28063
|
value = 0,
|
|
27061
28064
|
max,
|
|
@@ -27122,7 +28125,7 @@ function StatBadge({
|
|
|
27122
28125
|
}
|
|
27123
28126
|
);
|
|
27124
28127
|
}
|
|
27125
|
-
var sizeMap17, variantMap2
|
|
28128
|
+
var sizeMap17, variantMap2;
|
|
27126
28129
|
var init_StatBadge = __esm({
|
|
27127
28130
|
"components/game/molecules/StatBadge.tsx"() {
|
|
27128
28131
|
init_cn();
|
|
@@ -27141,7 +28144,6 @@ var init_StatBadge = __esm({
|
|
|
27141
28144
|
warning: "bg-warning/15 border-warning/40 text-foreground",
|
|
27142
28145
|
danger: "bg-error/15 border-error/40 text-foreground"
|
|
27143
28146
|
};
|
|
27144
|
-
DEFAULT_ASSET_URL12 = "https://almadar-kflow-assets.web.app/shared/effects/particles/light_01.png";
|
|
27145
28147
|
StatBadge.displayName = "StatBadge";
|
|
27146
28148
|
}
|
|
27147
28149
|
});
|
|
@@ -27158,7 +28160,7 @@ function InventoryGrid({
|
|
|
27158
28160
|
const eventBus = useEventBus();
|
|
27159
28161
|
const slotCount = totalSlots ?? items.length;
|
|
27160
28162
|
const emptySlotCount = Math.max(0, slotCount - items.length);
|
|
27161
|
-
const handleSelect =
|
|
28163
|
+
const handleSelect = React85.useCallback(
|
|
27162
28164
|
(id) => {
|
|
27163
28165
|
onSelect?.(id);
|
|
27164
28166
|
if (selectEvent) {
|
|
@@ -27389,35 +28391,37 @@ function GameCanvas2D({
|
|
|
27389
28391
|
drawEvent,
|
|
27390
28392
|
fps = 60,
|
|
27391
28393
|
backgroundImage = "",
|
|
27392
|
-
assetBaseUrl
|
|
28394
|
+
assetBaseUrl,
|
|
27393
28395
|
className
|
|
27394
28396
|
}) {
|
|
27395
|
-
const canvasRef =
|
|
27396
|
-
const rafRef =
|
|
27397
|
-
const frameRef =
|
|
27398
|
-
const lastTimeRef =
|
|
27399
|
-
const imageCache =
|
|
28397
|
+
const canvasRef = React85.useRef(null);
|
|
28398
|
+
const rafRef = React85.useRef(0);
|
|
28399
|
+
const frameRef = React85.useRef(0);
|
|
28400
|
+
const lastTimeRef = React85.useRef(0);
|
|
28401
|
+
const imageCache = React85.useRef(/* @__PURE__ */ new Map());
|
|
27400
28402
|
const emit = useEmitEvent();
|
|
27401
|
-
const onDrawRef =
|
|
28403
|
+
const onDrawRef = React85.useRef(onDraw);
|
|
27402
28404
|
onDrawRef.current = onDraw;
|
|
27403
|
-
const onTickRef =
|
|
28405
|
+
const onTickRef = React85.useRef(onTick);
|
|
27404
28406
|
onTickRef.current = onTick;
|
|
27405
|
-
const tickEventRef =
|
|
28407
|
+
const tickEventRef = React85.useRef(tickEvent);
|
|
27406
28408
|
tickEventRef.current = tickEvent;
|
|
27407
|
-
const drawEventRef =
|
|
28409
|
+
const drawEventRef = React85.useRef(drawEvent);
|
|
27408
28410
|
drawEventRef.current = drawEvent;
|
|
27409
|
-
const emitRef =
|
|
28411
|
+
const emitRef = React85.useRef(emit);
|
|
27410
28412
|
emitRef.current = emit;
|
|
27411
|
-
const assetBaseUrlRef =
|
|
28413
|
+
const assetBaseUrlRef = React85.useRef(assetBaseUrl);
|
|
27412
28414
|
assetBaseUrlRef.current = assetBaseUrl;
|
|
27413
|
-
const backgroundImageRef =
|
|
28415
|
+
const backgroundImageRef = React85.useRef(backgroundImage);
|
|
27414
28416
|
backgroundImageRef.current = backgroundImage;
|
|
27415
|
-
const widthRef =
|
|
28417
|
+
const widthRef = React85.useRef(width);
|
|
27416
28418
|
widthRef.current = width;
|
|
27417
|
-
const heightRef =
|
|
28419
|
+
const heightRef = React85.useRef(height);
|
|
27418
28420
|
heightRef.current = height;
|
|
27419
|
-
const loadImage =
|
|
27420
|
-
const
|
|
28421
|
+
const loadImage = React85.useCallback((url) => {
|
|
28422
|
+
const base = assetBaseUrlRef.current;
|
|
28423
|
+
if (!url.startsWith("http") && !base) return null;
|
|
28424
|
+
const fullUrl = url.startsWith("http") ? url : `${base}${url}`;
|
|
27421
28425
|
const cached = imageCache.current.get(fullUrl);
|
|
27422
28426
|
if (cached?.complete && cached.naturalWidth > 0) return cached;
|
|
27423
28427
|
if (!cached) {
|
|
@@ -27428,7 +28432,7 @@ function GameCanvas2D({
|
|
|
27428
28432
|
}
|
|
27429
28433
|
return null;
|
|
27430
28434
|
}, []);
|
|
27431
|
-
|
|
28435
|
+
React85.useEffect(() => {
|
|
27432
28436
|
const canvas = canvasRef.current;
|
|
27433
28437
|
if (!canvas) return;
|
|
27434
28438
|
const ctx = canvas.getContext("2d");
|
|
@@ -27740,7 +28744,7 @@ function TurnPanel({
|
|
|
27740
28744
|
className
|
|
27741
28745
|
}) {
|
|
27742
28746
|
const eventBus = useEventBus();
|
|
27743
|
-
const handleAction =
|
|
28747
|
+
const handleAction = React85.useCallback(
|
|
27744
28748
|
(event) => {
|
|
27745
28749
|
if (event) {
|
|
27746
28750
|
eventBus.emit(event, { turn: currentTurn, phase, activeTeam });
|
|
@@ -27798,7 +28802,7 @@ var init_TurnPanel = __esm({
|
|
|
27798
28802
|
}
|
|
27799
28803
|
});
|
|
27800
28804
|
function EnemyPlate({
|
|
27801
|
-
assetUrl
|
|
28805
|
+
assetUrl,
|
|
27802
28806
|
name = "Shadow Guard",
|
|
27803
28807
|
health = 80,
|
|
27804
28808
|
maxHealth = 100,
|
|
@@ -27882,7 +28886,7 @@ function EnemyPlate({
|
|
|
27882
28886
|
}
|
|
27883
28887
|
);
|
|
27884
28888
|
}
|
|
27885
|
-
var effectVariantMap2, DEFAULT_ENEMY_EFFECTS
|
|
28889
|
+
var effectVariantMap2, DEFAULT_ENEMY_EFFECTS;
|
|
27886
28890
|
var init_EnemyPlate = __esm({
|
|
27887
28891
|
"components/game/molecules/EnemyPlate.tsx"() {
|
|
27888
28892
|
"use client";
|
|
@@ -27899,7 +28903,6 @@ var init_EnemyPlate = __esm({
|
|
|
27899
28903
|
DEFAULT_ENEMY_EFFECTS = [
|
|
27900
28904
|
{ icon: "flame", label: "Burn", variant: "debuff" }
|
|
27901
28905
|
];
|
|
27902
|
-
DEFAULT_ASSET_URL13 = "https://almadar-kflow-assets.web.app/shared/portraits/shadow-legion.png";
|
|
27903
28906
|
EnemyPlate.displayName = "EnemyPlate";
|
|
27904
28907
|
}
|
|
27905
28908
|
});
|
|
@@ -27909,7 +28912,7 @@ function UnitCommandBar({
|
|
|
27909
28912
|
className
|
|
27910
28913
|
}) {
|
|
27911
28914
|
const eventBus = useEventBus();
|
|
27912
|
-
const handleCommand =
|
|
28915
|
+
const handleCommand = React85.useCallback(
|
|
27913
28916
|
(event) => {
|
|
27914
28917
|
if (event) {
|
|
27915
28918
|
eventBus.emit(event, { unitId: selectedUnitId });
|
|
@@ -28050,6 +29053,9 @@ function DialogueBox({
|
|
|
28050
29053
|
completeEvent,
|
|
28051
29054
|
choiceEvent,
|
|
28052
29055
|
advanceEvent,
|
|
29056
|
+
backgroundImage,
|
|
29057
|
+
portraitUrl,
|
|
29058
|
+
portraitScale = 1,
|
|
28053
29059
|
className
|
|
28054
29060
|
}) {
|
|
28055
29061
|
const eventBus = useEventBus();
|
|
@@ -28165,64 +29171,98 @@ function DialogueBox({
|
|
|
28165
29171
|
}
|
|
28166
29172
|
}, [isTyping, skipTypewriter, dialogue.choices, selectedChoice, onChoice, onAdvance, choiceEvent, advanceEvent, eventBus]);
|
|
28167
29173
|
const enabledChoices = dialogue.choices?.filter((c) => !c.disabled) ?? [];
|
|
28168
|
-
return /* @__PURE__ */
|
|
28169
|
-
|
|
28170
|
-
|
|
28171
|
-
|
|
28172
|
-
"fixed
|
|
28173
|
-
|
|
28174
|
-
|
|
28175
|
-
|
|
28176
|
-
|
|
28177
|
-
|
|
28178
|
-
|
|
28179
|
-
|
|
28180
|
-
|
|
28181
|
-
|
|
28182
|
-
|
|
29174
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
29175
|
+
backgroundImage && /* @__PURE__ */ jsx(
|
|
29176
|
+
"div",
|
|
29177
|
+
{
|
|
29178
|
+
className: "fixed inset-0 z-20 bg-center bg-cover bg-no-repeat",
|
|
29179
|
+
style: { backgroundImage: `url(${backgroundImage})` },
|
|
29180
|
+
"aria-hidden": "true"
|
|
29181
|
+
}
|
|
29182
|
+
),
|
|
29183
|
+
portraitUrl && /* @__PURE__ */ jsx(
|
|
29184
|
+
"div",
|
|
29185
|
+
{
|
|
29186
|
+
className: cn(
|
|
29187
|
+
"fixed left-1/2 -translate-x-1/2 z-30 pointer-events-none flex items-end",
|
|
29188
|
+
position === "top" ? "top-0" : "bottom-0"
|
|
29189
|
+
),
|
|
29190
|
+
style: { height: `${60 * portraitScale}vh` },
|
|
29191
|
+
children: /* @__PURE__ */ jsx(
|
|
28183
29192
|
"img",
|
|
28184
29193
|
{
|
|
28185
|
-
src:
|
|
29194
|
+
src: portraitUrl,
|
|
28186
29195
|
alt: dialogue.speaker,
|
|
28187
|
-
className: "
|
|
28188
|
-
style: { imageRendering: "pixelated" }
|
|
29196
|
+
className: "h-full w-auto object-contain drop-shadow-2xl"
|
|
28189
29197
|
}
|
|
28190
|
-
)
|
|
28191
|
-
|
|
28192
|
-
|
|
28193
|
-
|
|
28194
|
-
|
|
28195
|
-
|
|
28196
|
-
|
|
28197
|
-
|
|
28198
|
-
|
|
29198
|
+
)
|
|
29199
|
+
}
|
|
29200
|
+
),
|
|
29201
|
+
/* @__PURE__ */ jsx(
|
|
29202
|
+
"div",
|
|
29203
|
+
{
|
|
29204
|
+
className: cn(
|
|
29205
|
+
"fixed left-0 right-0 z-40",
|
|
29206
|
+
position === "top" ? "top-0" : "bottom-0",
|
|
29207
|
+
className
|
|
29208
|
+
),
|
|
29209
|
+
onClick: handleClick,
|
|
29210
|
+
onKeyDown: handleKeyDown,
|
|
29211
|
+
tabIndex: 0,
|
|
29212
|
+
role: "dialog",
|
|
29213
|
+
"aria-label": "Dialogue",
|
|
29214
|
+
children: /* @__PURE__ */ jsx("div", { className: cn(
|
|
29215
|
+
"mx-4 my-4 border-2 rounded-container overflow-hidden",
|
|
29216
|
+
backgroundImage ? "bg-black/80 backdrop-blur-sm text-white border-white/20" : "bg-[var(--color-card)] bg-opacity-95 border-border"
|
|
29217
|
+
), children: /* @__PURE__ */ jsxs("div", { className: "flex", children: [
|
|
29218
|
+
dialogue.portrait && /* @__PURE__ */ jsx("div", { className: "flex-shrink-0 p-4 border-r border-border", children: /* @__PURE__ */ jsx(
|
|
29219
|
+
"img",
|
|
28199
29220
|
{
|
|
28200
|
-
|
|
28201
|
-
|
|
28202
|
-
|
|
28203
|
-
|
|
28204
|
-
|
|
28205
|
-
|
|
28206
|
-
|
|
28207
|
-
|
|
28208
|
-
|
|
28209
|
-
|
|
29221
|
+
src: dialogue.portrait,
|
|
29222
|
+
alt: dialogue.speaker,
|
|
29223
|
+
className: "w-24 h-24 object-contain",
|
|
29224
|
+
style: { imageRendering: "pixelated" }
|
|
29225
|
+
}
|
|
29226
|
+
) }),
|
|
29227
|
+
/* @__PURE__ */ jsxs("div", { className: "flex-1 p-4", children: [
|
|
29228
|
+
/* @__PURE__ */ jsx("div", { className: "text-warning font-bold mb-2", children: dialogue.speaker }),
|
|
29229
|
+
/* @__PURE__ */ jsxs("div", { className: cn(
|
|
29230
|
+
"text-lg leading-relaxed min-h-[60px]",
|
|
29231
|
+
backgroundImage ? "text-white" : "text-[var(--color-foreground)]"
|
|
29232
|
+
), children: [
|
|
29233
|
+
displayedText,
|
|
29234
|
+
isTyping && /* @__PURE__ */ jsx("span", { className: "animate-pulse", children: "\u258C" })
|
|
29235
|
+
] }),
|
|
29236
|
+
!isTyping && enabledChoices.length > 0 && /* @__PURE__ */ jsx("div", { className: "mt-4 space-y-2", children: enabledChoices.map((choice, index) => /* @__PURE__ */ jsxs(
|
|
29237
|
+
"button",
|
|
29238
|
+
{
|
|
29239
|
+
type: "button",
|
|
29240
|
+
className: cn(
|
|
29241
|
+
"block w-full text-left px-4 py-2 rounded-interactive transition-colors",
|
|
29242
|
+
"hover:bg-[var(--color-surface,#374151)] focus:outline-none focus:ring-2 focus:ring-warning",
|
|
29243
|
+
selectedChoice === index ? "bg-[var(--color-surface,#374151)] text-warning" : backgroundImage ? "bg-white/10 text-white hover:bg-white/20" : "bg-[var(--color-card)] text-[var(--color-foreground)]"
|
|
29244
|
+
),
|
|
29245
|
+
onClick: (e) => {
|
|
29246
|
+
e.stopPropagation();
|
|
29247
|
+
if (choiceEvent) eventBus.emit(`UI:${choiceEvent}`, { choice });
|
|
29248
|
+
onChoice?.(choice);
|
|
29249
|
+
},
|
|
29250
|
+
children: [
|
|
29251
|
+
/* @__PURE__ */ jsxs("span", { className: "text-muted-foreground mr-2", children: [
|
|
29252
|
+
index + 1,
|
|
29253
|
+
"."
|
|
29254
|
+
] }),
|
|
29255
|
+
choice.text
|
|
29256
|
+
]
|
|
28210
29257
|
},
|
|
28211
|
-
|
|
28212
|
-
|
|
28213
|
-
|
|
28214
|
-
|
|
28215
|
-
|
|
28216
|
-
|
|
28217
|
-
|
|
28218
|
-
|
|
28219
|
-
index
|
|
28220
|
-
)) }),
|
|
28221
|
-
!isTyping && !dialogue.choices?.length && /* @__PURE__ */ jsx("div", { className: "mt-4 text-muted-foreground text-sm animate-pulse", children: "Press SPACE or click to continue..." })
|
|
28222
|
-
] })
|
|
28223
|
-
] }) })
|
|
28224
|
-
}
|
|
28225
|
-
);
|
|
29258
|
+
index
|
|
29259
|
+
)) }),
|
|
29260
|
+
!isTyping && !dialogue.choices?.length && /* @__PURE__ */ jsx("div", { className: "mt-4 text-muted-foreground text-sm animate-pulse", children: "Press SPACE or click to continue..." })
|
|
29261
|
+
] })
|
|
29262
|
+
] }) })
|
|
29263
|
+
}
|
|
29264
|
+
)
|
|
29265
|
+
] });
|
|
28226
29266
|
}
|
|
28227
29267
|
var DEFAULT_DIALOGUE;
|
|
28228
29268
|
var init_DialogueBox = __esm({
|
|
@@ -28423,7 +29463,7 @@ function GameMenu({
|
|
|
28423
29463
|
} catch {
|
|
28424
29464
|
}
|
|
28425
29465
|
const eventBus = eventBusProp || eventBusFromHook;
|
|
28426
|
-
const handleOptionClick =
|
|
29466
|
+
const handleOptionClick = React85.useCallback(
|
|
28427
29467
|
(option) => {
|
|
28428
29468
|
if (option.event && eventBus) {
|
|
28429
29469
|
eventBus.emit(`UI:${option.event}`, { option });
|
|
@@ -28542,7 +29582,7 @@ function GameOverScreen({
|
|
|
28542
29582
|
} catch {
|
|
28543
29583
|
}
|
|
28544
29584
|
const eventBus = eventBusProp || eventBusFromHook;
|
|
28545
|
-
const handleActionClick =
|
|
29585
|
+
const handleActionClick = React85.useCallback(
|
|
28546
29586
|
(action) => {
|
|
28547
29587
|
if (action.event && eventBus) {
|
|
28548
29588
|
eventBus.emit(`UI:${action.event}`, { action });
|
|
@@ -28749,10 +29789,10 @@ function PlatformerCanvas({
|
|
|
28749
29789
|
canvasHeight = 400,
|
|
28750
29790
|
followCamera = true,
|
|
28751
29791
|
bgColor = "#5c94fc",
|
|
28752
|
-
playerSprite
|
|
29792
|
+
playerSprite,
|
|
28753
29793
|
tileSprites,
|
|
28754
29794
|
backgroundImage = "",
|
|
28755
|
-
assetBaseUrl
|
|
29795
|
+
assetBaseUrl,
|
|
28756
29796
|
leftEvent = "MOVE_LEFT",
|
|
28757
29797
|
rightEvent = "MOVE_RIGHT",
|
|
28758
29798
|
jumpEvent = "JUMP",
|
|
@@ -28766,6 +29806,7 @@ function PlatformerCanvas({
|
|
|
28766
29806
|
const imageCache = useRef(/* @__PURE__ */ new Map());
|
|
28767
29807
|
const [loadedImages, setLoadedImages] = useState(/* @__PURE__ */ new Set());
|
|
28768
29808
|
const loadImage = useCallback((url) => {
|
|
29809
|
+
if (!url.startsWith("http") && !assetBaseUrl) return null;
|
|
28769
29810
|
const fullUrl = url.startsWith("http") ? url : `${assetBaseUrl}${url}`;
|
|
28770
29811
|
const cached = imageCache.current.get(fullUrl);
|
|
28771
29812
|
if (cached?.complete && cached.naturalWidth > 0) {
|
|
@@ -29325,6 +30366,14 @@ var init_GraphView = __esm({
|
|
|
29325
30366
|
},
|
|
29326
30367
|
[onNodeClick]
|
|
29327
30368
|
);
|
|
30369
|
+
const handleNodePointerDown = useCallback(
|
|
30370
|
+
(e, node) => {
|
|
30371
|
+
if (e.pointerType === "mouse") return;
|
|
30372
|
+
handleNodeMouseEnter(node);
|
|
30373
|
+
handleNodeClickInternal(node);
|
|
30374
|
+
},
|
|
30375
|
+
[handleNodeMouseEnter, handleNodeClickInternal]
|
|
30376
|
+
);
|
|
29328
30377
|
if (nodes.length === 0) {
|
|
29329
30378
|
return /* @__PURE__ */ jsx(Box, { className: cn("flex items-center justify-center", className), style: { width: w, height: h }, children: /* @__PURE__ */ jsx(Box, { className: "text-muted-foreground text-sm", children: t("display.noGraphData") }) });
|
|
29330
30379
|
}
|
|
@@ -29384,6 +30433,7 @@ var init_GraphView = __esm({
|
|
|
29384
30433
|
onMouseEnter: () => handleNodeMouseEnter(node),
|
|
29385
30434
|
onMouseLeave: handleNodeMouseLeave,
|
|
29386
30435
|
onClick: () => handleNodeClickInternal(node),
|
|
30436
|
+
onPointerDown: (e) => handleNodePointerDown(e, node),
|
|
29387
30437
|
children: [
|
|
29388
30438
|
/* @__PURE__ */ jsx(
|
|
29389
30439
|
"circle",
|
|
@@ -29464,13 +30514,13 @@ var init_MapView = __esm({
|
|
|
29464
30514
|
shadowSize: [41, 41]
|
|
29465
30515
|
});
|
|
29466
30516
|
L.Marker.prototype.options.icon = defaultIcon;
|
|
29467
|
-
const { useEffect:
|
|
30517
|
+
const { useEffect: useEffect82, useRef: useRef80, useCallback: useCallback125, useState: useState111 } = React85__default;
|
|
29468
30518
|
const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
|
|
29469
30519
|
const { useEventBus: useEventBus3 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
|
|
29470
30520
|
function MapUpdater({ centerLat, centerLng, zoom }) {
|
|
29471
30521
|
const map = useMap();
|
|
29472
|
-
const prevRef =
|
|
29473
|
-
|
|
30522
|
+
const prevRef = useRef80({ centerLat, centerLng, zoom });
|
|
30523
|
+
useEffect82(() => {
|
|
29474
30524
|
const prev = prevRef.current;
|
|
29475
30525
|
if (prev.centerLat !== centerLat || prev.centerLng !== centerLng || prev.zoom !== zoom) {
|
|
29476
30526
|
map.setView([centerLat, centerLng], zoom);
|
|
@@ -29481,7 +30531,7 @@ var init_MapView = __esm({
|
|
|
29481
30531
|
}
|
|
29482
30532
|
function MapClickHandler({ onMapClick }) {
|
|
29483
30533
|
const map = useMap();
|
|
29484
|
-
|
|
30534
|
+
useEffect82(() => {
|
|
29485
30535
|
if (!onMapClick) return;
|
|
29486
30536
|
const handler = (e) => {
|
|
29487
30537
|
onMapClick(e.latlng.lat, e.latlng.lng);
|
|
@@ -29509,8 +30559,8 @@ var init_MapView = __esm({
|
|
|
29509
30559
|
showAttribution = true
|
|
29510
30560
|
}) {
|
|
29511
30561
|
const eventBus = useEventBus3();
|
|
29512
|
-
const [clickedPosition, setClickedPosition] =
|
|
29513
|
-
const handleMapClick =
|
|
30562
|
+
const [clickedPosition, setClickedPosition] = useState111(null);
|
|
30563
|
+
const handleMapClick = useCallback125((lat, lng) => {
|
|
29514
30564
|
if (showClickedPin) {
|
|
29515
30565
|
setClickedPosition({ lat, lng });
|
|
29516
30566
|
}
|
|
@@ -29519,7 +30569,7 @@ var init_MapView = __esm({
|
|
|
29519
30569
|
eventBus.emit(`UI:${mapClickEvent}`, { latitude: lat, longitude: lng });
|
|
29520
30570
|
}
|
|
29521
30571
|
}, [onMapClick, mapClickEvent, eventBus, showClickedPin]);
|
|
29522
|
-
const handleMarkerClick =
|
|
30572
|
+
const handleMarkerClick = useCallback125((marker) => {
|
|
29523
30573
|
onMarkerClick?.(marker);
|
|
29524
30574
|
if (markerClickEvent) {
|
|
29525
30575
|
eventBus.emit(`UI:${markerClickEvent}`, { ...marker });
|
|
@@ -29860,7 +30910,7 @@ var init_StarRating = __esm({
|
|
|
29860
30910
|
"aria-valuenow": value,
|
|
29861
30911
|
tabIndex: readOnly ? void 0 : 0,
|
|
29862
30912
|
onKeyDown: handleKeyDown,
|
|
29863
|
-
|
|
30913
|
+
onPointerLeave: () => setHoverValue(null),
|
|
29864
30914
|
children: Array.from({ length: max }, (_, i) => {
|
|
29865
30915
|
const fillLevel = Math.max(0, Math.min(1, displayValue - i));
|
|
29866
30916
|
const isFull = fillLevel >= 1;
|
|
@@ -29870,7 +30920,7 @@ var init_StarRating = __esm({
|
|
|
29870
30920
|
{
|
|
29871
30921
|
className: "relative inline-block",
|
|
29872
30922
|
onClick: () => handleStarClick(i, false),
|
|
29873
|
-
|
|
30923
|
+
onPointerMove: (e) => {
|
|
29874
30924
|
if (readOnly) return;
|
|
29875
30925
|
const rect = e.currentTarget.getBoundingClientRect();
|
|
29876
30926
|
const isLeftHalf = e.clientX - rect.left < rect.width / 2;
|
|
@@ -30370,8 +31420,8 @@ function TableView({
|
|
|
30370
31420
|
}) {
|
|
30371
31421
|
const eventBus = useEventBus();
|
|
30372
31422
|
const { t } = useTranslate();
|
|
30373
|
-
const [visibleCount, setVisibleCount] =
|
|
30374
|
-
const [localSelected, setLocalSelected] =
|
|
31423
|
+
const [visibleCount, setVisibleCount] = React85__default.useState(pageSize > 0 ? pageSize : Infinity);
|
|
31424
|
+
const [localSelected, setLocalSelected] = React85__default.useState(/* @__PURE__ */ new Set());
|
|
30375
31425
|
const colDefs = columns ?? fields ?? [];
|
|
30376
31426
|
const allDataRaw = Array.isArray(entity) ? entity : entity ? [entity] : [];
|
|
30377
31427
|
const dnd = useDataDnd({
|
|
@@ -30566,12 +31616,12 @@ function TableView({
|
|
|
30566
31616
|
]
|
|
30567
31617
|
}
|
|
30568
31618
|
);
|
|
30569
|
-
return dnd.isZone ? /* @__PURE__ */ jsx(dnd.SortableItem, { id: row[idField] ?? id, children: rowInner }, id) : /* @__PURE__ */ jsx(
|
|
31619
|
+
return dnd.isZone ? /* @__PURE__ */ jsx(dnd.SortableItem, { id: row[idField] ?? id, children: rowInner }, id) : /* @__PURE__ */ jsx(React85__default.Fragment, { children: rowInner }, id);
|
|
30570
31620
|
};
|
|
30571
31621
|
const items = data.map((row) => row);
|
|
30572
31622
|
const groups = groupBy ? groupData2(items, groupBy) : [{ label: "", items }];
|
|
30573
31623
|
let runningIndex = 0;
|
|
30574
|
-
const body = /* @__PURE__ */ jsx(Box, { role: "rowgroup", children: groups.map((group, gi) => /* @__PURE__ */ jsxs(
|
|
31624
|
+
const body = /* @__PURE__ */ jsx(Box, { role: "rowgroup", children: groups.map((group, gi) => /* @__PURE__ */ jsxs(React85__default.Fragment, { children: [
|
|
30575
31625
|
group.label && /* @__PURE__ */ jsx(Divider, { label: group.label, className: gi > 0 ? "mt-3" : "mt-0" }),
|
|
30576
31626
|
group.items.map((row) => renderRow(row, runningIndex++))
|
|
30577
31627
|
] }, gi)) });
|
|
@@ -31928,7 +32978,7 @@ var init_StepFlow = __esm({
|
|
|
31928
32978
|
className
|
|
31929
32979
|
}) => {
|
|
31930
32980
|
if (orientation === "vertical") {
|
|
31931
|
-
return /* @__PURE__ */ jsx(VStack, { gap: "none", className: cn("w-full", className), children: steps.map((step, index) => /* @__PURE__ */ jsx(
|
|
32981
|
+
return /* @__PURE__ */ jsx(VStack, { gap: "none", className: cn("w-full", className), children: steps.map((step, index) => /* @__PURE__ */ jsx(React85__default.Fragment, { children: /* @__PURE__ */ jsxs(HStack, { gap: "md", align: "start", className: "w-full", children: [
|
|
31932
32982
|
/* @__PURE__ */ jsxs(VStack, { gap: "none", align: "center", children: [
|
|
31933
32983
|
/* @__PURE__ */ jsx(StepCircle, { step, index }),
|
|
31934
32984
|
showConnectors && index < steps.length - 1 && /* @__PURE__ */ jsx(Box, { className: "w-px h-8 bg-border" })
|
|
@@ -31939,7 +32989,7 @@ var init_StepFlow = __esm({
|
|
|
31939
32989
|
] })
|
|
31940
32990
|
] }) }, index)) });
|
|
31941
32991
|
}
|
|
31942
|
-
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(
|
|
32992
|
+
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(React85__default.Fragment, { children: [
|
|
31943
32993
|
/* @__PURE__ */ jsxs(VStack, { gap: "sm", align: "center", className: "flex-1 w-full md:w-auto", children: [
|
|
31944
32994
|
/* @__PURE__ */ jsx(StepCircle, { step, index }),
|
|
31945
32995
|
/* @__PURE__ */ jsx(Typography, { variant: "h4", className: "text-center", children: step.title }),
|
|
@@ -32924,7 +33974,7 @@ var init_LikertScale = __esm({
|
|
|
32924
33974
|
md: "text-base",
|
|
32925
33975
|
lg: "text-lg"
|
|
32926
33976
|
};
|
|
32927
|
-
LikertScale =
|
|
33977
|
+
LikertScale = React85__default.forwardRef(
|
|
32928
33978
|
({
|
|
32929
33979
|
question,
|
|
32930
33980
|
options = DEFAULT_LIKERT_OPTIONS,
|
|
@@ -32936,7 +33986,7 @@ var init_LikertScale = __esm({
|
|
|
32936
33986
|
variant = "radios",
|
|
32937
33987
|
className
|
|
32938
33988
|
}, ref) => {
|
|
32939
|
-
const groupId =
|
|
33989
|
+
const groupId = React85__default.useId();
|
|
32940
33990
|
const eventBus = useEventBus();
|
|
32941
33991
|
const handleSelect = useCallback(
|
|
32942
33992
|
(next) => {
|
|
@@ -33760,7 +34810,7 @@ var init_PositionedCanvas = __esm({
|
|
|
33760
34810
|
{
|
|
33761
34811
|
ref: containerRef,
|
|
33762
34812
|
"data-testid": "positioned-canvas",
|
|
33763
|
-
className: "relative bg-background border border-border rounded-container overflow-hidden",
|
|
34813
|
+
className: "relative bg-background border border-border rounded-container overflow-hidden touch-none",
|
|
33764
34814
|
style: { width, height },
|
|
33765
34815
|
onClick: handleContainerClick,
|
|
33766
34816
|
children: items.map((item) => {
|
|
@@ -35218,7 +36268,7 @@ var init_DocBreadcrumb = __esm({
|
|
|
35218
36268
|
"aria-label": t("aria.breadcrumb"),
|
|
35219
36269
|
children: /* @__PURE__ */ jsx(HStack, { gap: "xs", align: "center", wrap: true, children: items.map((item, idx) => {
|
|
35220
36270
|
const isLast = idx === items.length - 1;
|
|
35221
|
-
return /* @__PURE__ */ jsxs(
|
|
36271
|
+
return /* @__PURE__ */ jsxs(React85__default.Fragment, { children: [
|
|
35222
36272
|
idx > 0 && /* @__PURE__ */ jsx(
|
|
35223
36273
|
Icon,
|
|
35224
36274
|
{
|
|
@@ -36087,7 +37137,7 @@ var init_MiniStateMachine = __esm({
|
|
|
36087
37137
|
const x = 2 + i * (NODE_W + GAP + ARROW_W + GAP);
|
|
36088
37138
|
const tc = transitionCounts[s.name] ?? 0;
|
|
36089
37139
|
const role = getStateRole(s.name, s.isInitial, s.isTerminal, tc, maxTC);
|
|
36090
|
-
return /* @__PURE__ */ jsxs(
|
|
37140
|
+
return /* @__PURE__ */ jsxs(React85__default.Fragment, { children: [
|
|
36091
37141
|
/* @__PURE__ */ jsx(
|
|
36092
37142
|
AvlState,
|
|
36093
37143
|
{
|
|
@@ -36291,7 +37341,7 @@ var init_PageHeader = __esm({
|
|
|
36291
37341
|
info: "bg-info/10 text-info"
|
|
36292
37342
|
};
|
|
36293
37343
|
return /* @__PURE__ */ jsxs(Box, { className: cn("mb-6", className), children: [
|
|
36294
|
-
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(
|
|
37344
|
+
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(React85__default.Fragment, { children: [
|
|
36295
37345
|
idx > 0 && /* @__PURE__ */ jsx(Typography, { variant: "small", color: "muted", children: "/" }),
|
|
36296
37346
|
crumb.href ? /* @__PURE__ */ jsx(
|
|
36297
37347
|
"a",
|
|
@@ -36973,8 +38023,8 @@ var init_WizardContainer = __esm({
|
|
|
36973
38023
|
return void 0;
|
|
36974
38024
|
if (typeof controlledStep === "number") return controlledStep;
|
|
36975
38025
|
if (typeof controlledStep === "string") return parseInt(controlledStep, 10);
|
|
36976
|
-
const
|
|
36977
|
-
return isNaN(
|
|
38026
|
+
const num3 = Number(controlledStep);
|
|
38027
|
+
return isNaN(num3) ? void 0 : num3;
|
|
36978
38028
|
})();
|
|
36979
38029
|
const currentStep = normalizedControlledStep !== void 0 ? normalizedControlledStep : internalStep;
|
|
36980
38030
|
const totalSteps = steps.length;
|
|
@@ -37020,7 +38070,7 @@ var init_WizardContainer = __esm({
|
|
|
37020
38070
|
const isCompleted = index < currentStep;
|
|
37021
38071
|
const stepKey = step.id ?? step.tabId ?? `step-${index}`;
|
|
37022
38072
|
const stepTitle = step.title ?? step.name ?? `Step ${index + 1}`;
|
|
37023
|
-
return /* @__PURE__ */ jsxs(
|
|
38073
|
+
return /* @__PURE__ */ jsxs(React85__default.Fragment, { children: [
|
|
37024
38074
|
/* @__PURE__ */ jsx(
|
|
37025
38075
|
Button,
|
|
37026
38076
|
{
|
|
@@ -37929,6 +38979,7 @@ var init_GraphCanvas = __esm({
|
|
|
37929
38979
|
init_ErrorState();
|
|
37930
38980
|
init_EmptyState();
|
|
37931
38981
|
init_useEventBus();
|
|
38982
|
+
init_useCanvasGestures();
|
|
37932
38983
|
GROUP_COLORS2 = [
|
|
37933
38984
|
"var(--color-primary)",
|
|
37934
38985
|
"var(--color-success)",
|
|
@@ -37952,6 +39003,8 @@ var init_GraphCanvas = __esm({
|
|
|
37952
39003
|
selectedNodeId,
|
|
37953
39004
|
repulsion = 800,
|
|
37954
39005
|
linkDistance = 100,
|
|
39006
|
+
nodeSpacing = 28,
|
|
39007
|
+
linkOpacity = 0.18,
|
|
37955
39008
|
layout = "force",
|
|
37956
39009
|
entity,
|
|
37957
39010
|
isLoading = false,
|
|
@@ -37964,6 +39017,10 @@ var init_GraphCanvas = __esm({
|
|
|
37964
39017
|
const animRef = useRef(0);
|
|
37965
39018
|
const [zoom, setZoom] = useState(1);
|
|
37966
39019
|
const [offset, setOffset] = useState({ x: 0, y: 0 });
|
|
39020
|
+
const zoomRef = useRef(zoom);
|
|
39021
|
+
zoomRef.current = zoom;
|
|
39022
|
+
const offsetRef = useRef(offset);
|
|
39023
|
+
offsetRef.current = offset;
|
|
37967
39024
|
const [hoveredNode, setHoveredNode] = useState(null);
|
|
37968
39025
|
const nodesRef = useRef([]);
|
|
37969
39026
|
const [, forceUpdate] = useState(0);
|
|
@@ -38111,6 +39168,25 @@ var init_GraphCanvas = __esm({
|
|
|
38111
39168
|
node.x = Math.max(30, Math.min(w - 30, node.x));
|
|
38112
39169
|
node.y = Math.max(30, Math.min(h - 30, node.y));
|
|
38113
39170
|
}
|
|
39171
|
+
for (let i = 0; i < nodes.length; i++) {
|
|
39172
|
+
for (let j = i + 1; j < nodes.length; j++) {
|
|
39173
|
+
const a = nodes[i];
|
|
39174
|
+
const b = nodes[j];
|
|
39175
|
+
const dx = b.x - a.x;
|
|
39176
|
+
const dy = b.y - a.y;
|
|
39177
|
+
const dist = Math.sqrt(dx * dx + dy * dy) || 1;
|
|
39178
|
+
const minDist = (a.size || 8) + (b.size || 8) + nodeSpacing;
|
|
39179
|
+
if (dist < minDist) {
|
|
39180
|
+
const push = (minDist - dist) / 2;
|
|
39181
|
+
const ux = dx / dist;
|
|
39182
|
+
const uy = dy / dist;
|
|
39183
|
+
a.x = Math.max(30, Math.min(w - 30, a.x - ux * push));
|
|
39184
|
+
a.y = Math.max(30, Math.min(h - 30, a.y - uy * push));
|
|
39185
|
+
b.x = Math.max(30, Math.min(w - 30, b.x + ux * push));
|
|
39186
|
+
b.y = Math.max(30, Math.min(h - 30, b.y + uy * push));
|
|
39187
|
+
}
|
|
39188
|
+
}
|
|
39189
|
+
}
|
|
38114
39190
|
iterations++;
|
|
38115
39191
|
forceUpdate((n) => n + 1);
|
|
38116
39192
|
if (iterations < maxIterations) {
|
|
@@ -38124,7 +39200,7 @@ var init_GraphCanvas = __esm({
|
|
|
38124
39200
|
return () => {
|
|
38125
39201
|
cancelAnimationFrame(animRef.current);
|
|
38126
39202
|
};
|
|
38127
|
-
}, [propNodes, propEdges, layout, repulsion, linkDistance, logicalW, height]);
|
|
39203
|
+
}, [propNodes, propEdges, layout, repulsion, linkDistance, nodeSpacing, logicalW, height]);
|
|
38128
39204
|
useEffect(() => {
|
|
38129
39205
|
const canvas = canvasRef.current;
|
|
38130
39206
|
if (!canvas) return;
|
|
@@ -38153,11 +39229,11 @@ var init_GraphCanvas = __esm({
|
|
|
38153
39229
|
const target = nodes.find((n) => n.id === edge.target);
|
|
38154
39230
|
if (!source || !target) continue;
|
|
38155
39231
|
const incident = !!hoveredNode && (edge.source === hoveredNode || edge.target === hoveredNode);
|
|
38156
|
-
ctx.globalAlpha = hoveredNode ? incident ? 1 : 0.
|
|
39232
|
+
ctx.globalAlpha = hoveredNode ? incident ? 1 : 0.05 : linkOpacity;
|
|
38157
39233
|
ctx.beginPath();
|
|
38158
39234
|
ctx.moveTo(source.x, source.y);
|
|
38159
39235
|
ctx.lineTo(target.x, target.y);
|
|
38160
|
-
ctx.strokeStyle = incident ? accentColor : edge.color || "#
|
|
39236
|
+
ctx.strokeStyle = incident ? accentColor : edge.color || "#888888";
|
|
38161
39237
|
ctx.lineWidth = incident ? 2 : edge.weight ? Math.max(1, edge.weight) : 1;
|
|
38162
39238
|
ctx.stroke();
|
|
38163
39239
|
if (edge.label && showLabels) {
|
|
@@ -38204,25 +39280,27 @@ var init_GraphCanvas = __esm({
|
|
|
38204
39280
|
setZoom(1);
|
|
38205
39281
|
setOffset({ x: 0, y: 0 });
|
|
38206
39282
|
}, []);
|
|
38207
|
-
const
|
|
38208
|
-
(
|
|
38209
|
-
|
|
38210
|
-
|
|
38211
|
-
|
|
38212
|
-
|
|
38213
|
-
|
|
38214
|
-
|
|
38215
|
-
|
|
38216
|
-
|
|
38217
|
-
|
|
38218
|
-
|
|
38219
|
-
|
|
38220
|
-
|
|
38221
|
-
|
|
38222
|
-
|
|
38223
|
-
|
|
38224
|
-
|
|
38225
|
-
|
|
39283
|
+
const applyZoom = useCallback((factor, cx, cy) => {
|
|
39284
|
+
if (!interactive) return;
|
|
39285
|
+
const oldZoom = zoomRef.current;
|
|
39286
|
+
const newZoom = Math.max(0.3, Math.min(3, oldZoom * factor));
|
|
39287
|
+
if (newZoom === oldZoom) return;
|
|
39288
|
+
const o = offsetRef.current;
|
|
39289
|
+
setOffset({
|
|
39290
|
+
x: cx - (cx - o.x) * (newZoom / oldZoom),
|
|
39291
|
+
y: cy - (cy - o.y) * (newZoom / oldZoom)
|
|
39292
|
+
});
|
|
39293
|
+
setZoom(newZoom);
|
|
39294
|
+
}, [interactive]);
|
|
39295
|
+
const applyPanDelta = useCallback((dx, dy) => {
|
|
39296
|
+
if (!interactive) return;
|
|
39297
|
+
setOffset((o) => ({ x: o.x + dx, y: o.y + dy }));
|
|
39298
|
+
}, [interactive]);
|
|
39299
|
+
const cancelSinglePointer = useCallback(() => {
|
|
39300
|
+
interactionRef.current.mode = "none";
|
|
39301
|
+
interactionRef.current.dragNodeId = null;
|
|
39302
|
+
}, []);
|
|
39303
|
+
const handlePointerDown = useCallback(
|
|
38226
39304
|
(e) => {
|
|
38227
39305
|
const coords = toCoords(e);
|
|
38228
39306
|
if (!coords) return;
|
|
@@ -38244,7 +39322,7 @@ var init_GraphCanvas = __esm({
|
|
|
38244
39322
|
},
|
|
38245
39323
|
[toCoords, nodeAt, draggable, interactive, offset]
|
|
38246
39324
|
);
|
|
38247
|
-
const
|
|
39325
|
+
const handlePointerMove = useCallback(
|
|
38248
39326
|
(e) => {
|
|
38249
39327
|
const state = interactionRef.current;
|
|
38250
39328
|
if (state.mode === "panning") {
|
|
@@ -38273,7 +39351,7 @@ var init_GraphCanvas = __esm({
|
|
|
38273
39351
|
},
|
|
38274
39352
|
[toCoords, nodeAt]
|
|
38275
39353
|
);
|
|
38276
|
-
const
|
|
39354
|
+
const handlePointerUp = useCallback(
|
|
38277
39355
|
(e) => {
|
|
38278
39356
|
const state = interactionRef.current;
|
|
38279
39357
|
const moved = Math.abs(e.clientX - state.downPos.x) + Math.abs(e.clientY - state.downPos.y);
|
|
@@ -38290,11 +39368,19 @@ var init_GraphCanvas = __esm({
|
|
|
38290
39368
|
},
|
|
38291
39369
|
[toCoords, nodeAt, handleNodeClick]
|
|
38292
39370
|
);
|
|
38293
|
-
const
|
|
38294
|
-
interactionRef.current.mode = "none";
|
|
38295
|
-
interactionRef.current.dragNodeId = null;
|
|
39371
|
+
const handlePointerLeave = useCallback(() => {
|
|
38296
39372
|
setHoveredNode(null);
|
|
38297
39373
|
}, []);
|
|
39374
|
+
const gestureHandlers = useCanvasGestures({
|
|
39375
|
+
canvasRef,
|
|
39376
|
+
enabled: interactive || draggable,
|
|
39377
|
+
onPointerDown: handlePointerDown,
|
|
39378
|
+
onPointerMove: handlePointerMove,
|
|
39379
|
+
onPointerUp: handlePointerUp,
|
|
39380
|
+
onZoom: applyZoom,
|
|
39381
|
+
onPanDelta: applyPanDelta,
|
|
39382
|
+
onMultiTouchStart: cancelSinglePointer
|
|
39383
|
+
});
|
|
38298
39384
|
const handleDoubleClick = useCallback(
|
|
38299
39385
|
(e) => {
|
|
38300
39386
|
const coords = toCoords(e);
|
|
@@ -38363,13 +39449,14 @@ var init_GraphCanvas = __esm({
|
|
|
38363
39449
|
ref: canvasRef,
|
|
38364
39450
|
width: Math.round(logicalW * (typeof window !== "undefined" && window.devicePixelRatio || 1)),
|
|
38365
39451
|
height: Math.round(height * (typeof window !== "undefined" && window.devicePixelRatio || 1)),
|
|
38366
|
-
className: "w-full cursor-grab active:cursor-grabbing",
|
|
39452
|
+
className: "w-full cursor-grab active:cursor-grabbing touch-none",
|
|
38367
39453
|
style: { height },
|
|
38368
|
-
|
|
38369
|
-
|
|
38370
|
-
|
|
38371
|
-
|
|
38372
|
-
|
|
39454
|
+
onPointerDown: gestureHandlers.onPointerDown,
|
|
39455
|
+
onPointerMove: gestureHandlers.onPointerMove,
|
|
39456
|
+
onPointerUp: gestureHandlers.onPointerUp,
|
|
39457
|
+
onPointerCancel: gestureHandlers.onPointerCancel,
|
|
39458
|
+
onPointerLeave: handlePointerLeave,
|
|
39459
|
+
onWheel: gestureHandlers.onWheel,
|
|
38373
39460
|
onDoubleClick: handleDoubleClick
|
|
38374
39461
|
}
|
|
38375
39462
|
) }),
|
|
@@ -39521,7 +40608,7 @@ var init_DetailPanel = __esm({
|
|
|
39521
40608
|
}
|
|
39522
40609
|
});
|
|
39523
40610
|
function extractTitle(children) {
|
|
39524
|
-
if (!
|
|
40611
|
+
if (!React85__default.isValidElement(children)) return void 0;
|
|
39525
40612
|
const props = children.props;
|
|
39526
40613
|
if (typeof props.title === "string") {
|
|
39527
40614
|
return props.title;
|
|
@@ -39576,7 +40663,7 @@ function LinearView({
|
|
|
39576
40663
|
/* @__PURE__ */ jsx(HStack, { className: "flex-wrap items-center", gap: "xs", children: trait.states.map((state, i) => {
|
|
39577
40664
|
const isDone = i < currentIdx;
|
|
39578
40665
|
const isCurrent = i === currentIdx;
|
|
39579
|
-
return /* @__PURE__ */ jsxs(
|
|
40666
|
+
return /* @__PURE__ */ jsxs(React85__default.Fragment, { children: [
|
|
39580
40667
|
i > 0 && /* @__PURE__ */ jsx(
|
|
39581
40668
|
Typography,
|
|
39582
40669
|
{
|
|
@@ -40526,12 +41613,12 @@ var init_Form = __esm({
|
|
|
40526
41613
|
const isSchemaEntity = isOrbitalEntitySchema(entity);
|
|
40527
41614
|
const resolvedEntity = isSchemaEntity ? entity : void 0;
|
|
40528
41615
|
const entityName = typeof entity === "string" ? entity : resolvedEntity?.name;
|
|
40529
|
-
const normalizedInitialData =
|
|
41616
|
+
const normalizedInitialData = React85__default.useMemo(() => {
|
|
40530
41617
|
const entityRowAsInitial = isPlainEntityRow(entity) ? entity : void 0;
|
|
40531
41618
|
const callerInitial = initialData !== null && typeof initialData === "object" && !Array.isArray(initialData) ? initialData : {};
|
|
40532
41619
|
return entityRowAsInitial !== void 0 ? { ...entityRowAsInitial, ...callerInitial } : callerInitial;
|
|
40533
41620
|
}, [entity, initialData]);
|
|
40534
|
-
const entityDerivedFields =
|
|
41621
|
+
const entityDerivedFields = React85__default.useMemo(() => {
|
|
40535
41622
|
if (fields && fields.length > 0) return void 0;
|
|
40536
41623
|
if (!resolvedEntity) return void 0;
|
|
40537
41624
|
return resolvedEntity.fields.map(
|
|
@@ -40551,16 +41638,16 @@ var init_Form = __esm({
|
|
|
40551
41638
|
const conditionalFields = typeof conditionalFieldsRaw === "boolean" ? {} : conditionalFieldsRaw;
|
|
40552
41639
|
const hiddenCalculations = typeof hiddenCalculationsRaw === "boolean" ? [] : hiddenCalculationsRaw;
|
|
40553
41640
|
const violationTriggers = typeof violationTriggersRaw === "boolean" ? [] : violationTriggersRaw;
|
|
40554
|
-
const [formData, setFormData] =
|
|
41641
|
+
const [formData, setFormData] = React85__default.useState(
|
|
40555
41642
|
normalizedInitialData
|
|
40556
41643
|
);
|
|
40557
|
-
const [collapsedSections, setCollapsedSections] =
|
|
41644
|
+
const [collapsedSections, setCollapsedSections] = React85__default.useState(
|
|
40558
41645
|
/* @__PURE__ */ new Set()
|
|
40559
41646
|
);
|
|
40560
|
-
const [submitError, setSubmitError] =
|
|
40561
|
-
const formRef =
|
|
41647
|
+
const [submitError, setSubmitError] = React85__default.useState(null);
|
|
41648
|
+
const formRef = React85__default.useRef(null);
|
|
40562
41649
|
const formMode = props.mode;
|
|
40563
|
-
const mountedRef =
|
|
41650
|
+
const mountedRef = React85__default.useRef(false);
|
|
40564
41651
|
if (!mountedRef.current) {
|
|
40565
41652
|
mountedRef.current = true;
|
|
40566
41653
|
debug("forms", "mount", {
|
|
@@ -40573,7 +41660,7 @@ var init_Form = __esm({
|
|
|
40573
41660
|
});
|
|
40574
41661
|
}
|
|
40575
41662
|
const shouldShowCancel = showCancel ?? (fields && fields.length > 0);
|
|
40576
|
-
const evalContext =
|
|
41663
|
+
const evalContext = React85__default.useMemo(
|
|
40577
41664
|
() => ({
|
|
40578
41665
|
formValues: formData,
|
|
40579
41666
|
globalVariables: externalContext?.globalVariables ?? {},
|
|
@@ -40582,7 +41669,7 @@ var init_Form = __esm({
|
|
|
40582
41669
|
}),
|
|
40583
41670
|
[formData, externalContext]
|
|
40584
41671
|
);
|
|
40585
|
-
|
|
41672
|
+
React85__default.useEffect(() => {
|
|
40586
41673
|
debug("forms", "initialData-sync", {
|
|
40587
41674
|
mode: formMode,
|
|
40588
41675
|
normalizedInitialData,
|
|
@@ -40593,7 +41680,7 @@ var init_Form = __esm({
|
|
|
40593
41680
|
setFormData(normalizedInitialData);
|
|
40594
41681
|
}
|
|
40595
41682
|
}, [normalizedInitialData]);
|
|
40596
|
-
const processCalculations =
|
|
41683
|
+
const processCalculations = React85__default.useCallback(
|
|
40597
41684
|
(changedFieldId, newFormData) => {
|
|
40598
41685
|
if (!hiddenCalculations.length) return;
|
|
40599
41686
|
const context = {
|
|
@@ -40618,7 +41705,7 @@ var init_Form = __esm({
|
|
|
40618
41705
|
},
|
|
40619
41706
|
[hiddenCalculations, externalContext, eventBus]
|
|
40620
41707
|
);
|
|
40621
|
-
const checkViolations =
|
|
41708
|
+
const checkViolations = React85__default.useCallback(
|
|
40622
41709
|
(changedFieldId, newFormData) => {
|
|
40623
41710
|
if (!violationTriggers.length) return;
|
|
40624
41711
|
const context = {
|
|
@@ -40656,7 +41743,7 @@ var init_Form = __esm({
|
|
|
40656
41743
|
processCalculations(name, newFormData);
|
|
40657
41744
|
checkViolations(name, newFormData);
|
|
40658
41745
|
};
|
|
40659
|
-
const isFieldVisible =
|
|
41746
|
+
const isFieldVisible = React85__default.useCallback(
|
|
40660
41747
|
(fieldName) => {
|
|
40661
41748
|
const condition = conditionalFields[fieldName];
|
|
40662
41749
|
if (!condition) return true;
|
|
@@ -40664,7 +41751,7 @@ var init_Form = __esm({
|
|
|
40664
41751
|
},
|
|
40665
41752
|
[conditionalFields, evalContext]
|
|
40666
41753
|
);
|
|
40667
|
-
const isSectionVisible =
|
|
41754
|
+
const isSectionVisible = React85__default.useCallback(
|
|
40668
41755
|
(section) => {
|
|
40669
41756
|
if (!section.condition) return true;
|
|
40670
41757
|
return Boolean(evaluateFormExpression(section.condition, evalContext));
|
|
@@ -40740,7 +41827,7 @@ var init_Form = __esm({
|
|
|
40740
41827
|
eventBus.emit(`UI:${onCancel}`);
|
|
40741
41828
|
}
|
|
40742
41829
|
};
|
|
40743
|
-
const renderField =
|
|
41830
|
+
const renderField = React85__default.useCallback(
|
|
40744
41831
|
(field) => {
|
|
40745
41832
|
const fieldName = field.name || field.field;
|
|
40746
41833
|
if (!fieldName) return null;
|
|
@@ -40761,7 +41848,7 @@ var init_Form = __esm({
|
|
|
40761
41848
|
[formData, isFieldVisible, relationsData, relationsLoading, isLoading]
|
|
40762
41849
|
);
|
|
40763
41850
|
const effectiveFields = entityDerivedFields ?? fields;
|
|
40764
|
-
const normalizedFields =
|
|
41851
|
+
const normalizedFields = React85__default.useMemo(() => {
|
|
40765
41852
|
if (!effectiveFields || effectiveFields.length === 0) return [];
|
|
40766
41853
|
return effectiveFields.map((field) => {
|
|
40767
41854
|
if (typeof field === "string") {
|
|
@@ -40784,7 +41871,7 @@ var init_Form = __esm({
|
|
|
40784
41871
|
return field;
|
|
40785
41872
|
});
|
|
40786
41873
|
}, [effectiveFields, resolvedEntity]);
|
|
40787
|
-
const schemaFields =
|
|
41874
|
+
const schemaFields = React85__default.useMemo(() => {
|
|
40788
41875
|
if (normalizedFields.length === 0) return null;
|
|
40789
41876
|
if (isDebugEnabled()) {
|
|
40790
41877
|
debugGroup(`Form: ${entityName || "unknown"}`);
|
|
@@ -40794,7 +41881,7 @@ var init_Form = __esm({
|
|
|
40794
41881
|
}
|
|
40795
41882
|
return normalizedFields.map(renderField).filter(Boolean);
|
|
40796
41883
|
}, [normalizedFields, renderField, entityName, conditionalFields]);
|
|
40797
|
-
const sectionElements =
|
|
41884
|
+
const sectionElements = React85__default.useMemo(() => {
|
|
40798
41885
|
if (!sections || sections.length === 0) return null;
|
|
40799
41886
|
return sections.map((section) => {
|
|
40800
41887
|
if (!isSectionVisible(section)) {
|
|
@@ -42114,12 +43201,18 @@ function ModelLoader({
|
|
|
42114
43201
|
});
|
|
42115
43202
|
return cloned;
|
|
42116
43203
|
}, [loadedModel, castShadow, receiveShadow]);
|
|
43204
|
+
const normFactor = useMemo(() => {
|
|
43205
|
+
if (!model) return 1;
|
|
43206
|
+
const box = new THREE3.Box3().setFromObject(model);
|
|
43207
|
+
const size = new THREE3.Vector3();
|
|
43208
|
+
box.getSize(size);
|
|
43209
|
+
const maxDim = Math.max(size.x, size.y, size.z);
|
|
43210
|
+
return maxDim > 0 && Number.isFinite(maxDim) ? 1 / maxDim : 1;
|
|
43211
|
+
}, [model]);
|
|
42117
43212
|
const scaleArray = useMemo(() => {
|
|
42118
|
-
|
|
42119
|
-
|
|
42120
|
-
|
|
42121
|
-
return scale;
|
|
42122
|
-
}, [scale]);
|
|
43213
|
+
const base = typeof scale === "number" ? [scale, scale, scale] : scale;
|
|
43214
|
+
return [base[0] * normFactor, base[1] * normFactor, base[2] * normFactor];
|
|
43215
|
+
}, [scale, normFactor]);
|
|
42123
43216
|
const rotationRad = useMemo(() => {
|
|
42124
43217
|
return [
|
|
42125
43218
|
rotation[0] * Math.PI / 180,
|
|
@@ -42330,6 +43423,29 @@ var init_GameCanvas3D2 = __esm({
|
|
|
42330
43423
|
const controlsRef = useRef(null);
|
|
42331
43424
|
const [hoveredTile, setHoveredTile] = useState(null);
|
|
42332
43425
|
const [internalError, setInternalError] = useState(null);
|
|
43426
|
+
useEffect(() => {
|
|
43427
|
+
const el = containerRef.current;
|
|
43428
|
+
if (!el) return;
|
|
43429
|
+
let node = el;
|
|
43430
|
+
let depth = 0;
|
|
43431
|
+
while (node && depth < 8) {
|
|
43432
|
+
const cs = window.getComputedStyle(node);
|
|
43433
|
+
const rect = node.getBoundingClientRect();
|
|
43434
|
+
console.log("[almadar:ui:game:3d-height]", {
|
|
43435
|
+
depth,
|
|
43436
|
+
tag: node.tagName,
|
|
43437
|
+
id: node.id || void 0,
|
|
43438
|
+
className: node.className?.slice?.(0, 60) || void 0,
|
|
43439
|
+
rectHeight: rect.height,
|
|
43440
|
+
computedHeight: cs.height,
|
|
43441
|
+
computedMinHeight: cs.minHeight,
|
|
43442
|
+
computedFlex: cs.flex,
|
|
43443
|
+
computedOverflow: cs.overflow
|
|
43444
|
+
});
|
|
43445
|
+
node = node.parentElement;
|
|
43446
|
+
depth++;
|
|
43447
|
+
}
|
|
43448
|
+
}, []);
|
|
42333
43449
|
const { sheetUrls: atlasSheetUrls, resolveUnitFrame } = useUnitSpriteAtlas(units);
|
|
42334
43450
|
const preloadUrls = useMemo(() => [...preloadAssets, ...atlasSheetUrls], [preloadAssets, atlasSheetUrls]);
|
|
42335
43451
|
const { isLoading: assetsLoading, progress, loaded, total } = useAssetLoader({
|
|
@@ -42719,7 +43835,7 @@ var init_GameCanvas3D2 = __esm({
|
|
|
42719
43835
|
{
|
|
42720
43836
|
ref: containerRef,
|
|
42721
43837
|
className: cn("game-canvas-3d relative w-full overflow-hidden", className),
|
|
42722
|
-
style: {
|
|
43838
|
+
style: { height: "85vh" },
|
|
42723
43839
|
"data-orientation": orientation,
|
|
42724
43840
|
"data-camera-mode": cameraMode,
|
|
42725
43841
|
"data-overlay": overlay,
|
|
@@ -42734,7 +43850,7 @@ var init_GameCanvas3D2 = __esm({
|
|
|
42734
43850
|
near: 0.1,
|
|
42735
43851
|
far: 1e3
|
|
42736
43852
|
},
|
|
42737
|
-
style: { background: backgroundColor,
|
|
43853
|
+
style: { background: backgroundColor, position: "absolute", inset: 0 },
|
|
42738
43854
|
onClick: (e) => {
|
|
42739
43855
|
if (e.target === e.currentTarget) {
|
|
42740
43856
|
eventHandlers.handleCanvasClick(e);
|
|
@@ -42812,6 +43928,9 @@ var init_GameCanvas3D2 = __esm({
|
|
|
42812
43928
|
target: cameraTarget,
|
|
42813
43929
|
enableDamping: true,
|
|
42814
43930
|
dampingFactor: 0.05,
|
|
43931
|
+
enableZoom: true,
|
|
43932
|
+
enablePan: true,
|
|
43933
|
+
touches: { ONE: THREE3.TOUCH.ROTATE, TWO: THREE3.TOUCH.DOLLY_PAN },
|
|
42815
43934
|
minDistance: 2,
|
|
42816
43935
|
maxDistance: 100,
|
|
42817
43936
|
maxPolarAngle: Math.PI / 2 - 0.1
|
|
@@ -43705,7 +44824,7 @@ var init_List = __esm({
|
|
|
43705
44824
|
if (entity && typeof entity === "object" && "id" in entity) return [entity];
|
|
43706
44825
|
return [];
|
|
43707
44826
|
}, [entity]);
|
|
43708
|
-
const getItemActions =
|
|
44827
|
+
const getItemActions = React85__default.useCallback(
|
|
43709
44828
|
(item) => {
|
|
43710
44829
|
if (!itemActions) return [];
|
|
43711
44830
|
if (typeof itemActions === "function") {
|
|
@@ -44181,7 +45300,7 @@ var init_MediaGallery = __esm({
|
|
|
44181
45300
|
[selectable, selectedItems, selectionEvent, eventBus]
|
|
44182
45301
|
);
|
|
44183
45302
|
const entityData = Array.isArray(entity) ? entity : [];
|
|
44184
|
-
const items =
|
|
45303
|
+
const items = React85__default.useMemo(() => {
|
|
44185
45304
|
if (propItems) return propItems;
|
|
44186
45305
|
if (entityData.length === 0) return [];
|
|
44187
45306
|
return entityData.map((record, idx) => ({
|
|
@@ -44342,7 +45461,7 @@ var init_MediaGallery = __esm({
|
|
|
44342
45461
|
}
|
|
44343
45462
|
});
|
|
44344
45463
|
function extractTitle2(children) {
|
|
44345
|
-
if (!
|
|
45464
|
+
if (!React85__default.isValidElement(children)) return void 0;
|
|
44346
45465
|
const props = children.props;
|
|
44347
45466
|
if (typeof props.title === "string") {
|
|
44348
45467
|
return props.title;
|
|
@@ -44918,31 +46037,33 @@ var init_PricingPageTemplate = __esm({
|
|
|
44918
46037
|
PricingPageTemplate.displayName = "PricingPageTemplate";
|
|
44919
46038
|
}
|
|
44920
46039
|
});
|
|
44921
|
-
function
|
|
46040
|
+
function resolveManifestUrl3(manifest, relative) {
|
|
46041
|
+
if (relative == null) return void 0;
|
|
46042
|
+
if (/^https?:\/\//.test(relative)) return relative;
|
|
46043
|
+
const base = manifest?.baseUrl;
|
|
46044
|
+
if (base == null) return relative;
|
|
46045
|
+
const cleanBase = base.replace(/\/$/, "");
|
|
46046
|
+
const cleanRel = relative.replace(/^\//, "");
|
|
46047
|
+
return `${cleanBase}/${cleanRel}`;
|
|
46048
|
+
}
|
|
46049
|
+
function dungeonTerrain(x, y, stairsX, stairsY, manifest) {
|
|
44922
46050
|
const isBorder = x === 0 || y === 0 || x === DUNGEON_GRID_W - 1 || y === DUNGEON_GRID_H - 1;
|
|
44923
46051
|
const isPillar = x % 4 === 0 && y % 4 === 0 && !isBorder;
|
|
44924
46052
|
const isWall = isBorder || isPillar;
|
|
46053
|
+
const terrains = manifest?.terrains;
|
|
44925
46054
|
if (x === stairsX && y === stairsY) {
|
|
44926
|
-
return { terrain: "stairs", passable: true, terrainSprite:
|
|
46055
|
+
return { terrain: "stairs", passable: true, terrainSprite: resolveManifestUrl3(manifest, terrains?.stairs) };
|
|
44927
46056
|
}
|
|
44928
46057
|
if (isWall) {
|
|
44929
|
-
return { terrain: "wall", passable: false, terrainSprite:
|
|
44930
|
-
}
|
|
44931
|
-
|
|
44932
|
-
const sprites = [
|
|
44933
|
-
`${CDN4}/isometric-dungeon/Isometric/dirt_E.png`,
|
|
44934
|
-
`${CDN4}/isometric-dungeon/Isometric/dirtTiles_E.png`,
|
|
44935
|
-
`${CDN4}/isometric-dungeon/Isometric/planks_E.png`,
|
|
44936
|
-
`${CDN4}/isometric-dungeon/Isometric/stoneTile_E.png`,
|
|
44937
|
-
`${CDN4}/isometric-dungeon/Isometric/dirt_E.png`
|
|
44938
|
-
];
|
|
44939
|
-
return { terrain: "floor", passable: true, terrainSprite: sprites[variant] };
|
|
46058
|
+
return { terrain: "wall", passable: false, terrainSprite: resolveManifestUrl3(manifest, terrains?.wall) };
|
|
46059
|
+
}
|
|
46060
|
+
return { terrain: "floor", passable: true, terrainSprite: resolveManifestUrl3(manifest, terrains?.floor) };
|
|
44940
46061
|
}
|
|
44941
|
-
function buildDefaultDungeonTiles(stairsX, stairsY) {
|
|
46062
|
+
function buildDefaultDungeonTiles(stairsX, stairsY, manifest) {
|
|
44942
46063
|
const tiles = [];
|
|
44943
46064
|
for (let y = 0; y < DUNGEON_GRID_H; y++) {
|
|
44944
46065
|
for (let x = 0; x < DUNGEON_GRID_W; x++) {
|
|
44945
|
-
tiles.push({ x, y, ...dungeonTerrain(x, y, stairsX, stairsY) });
|
|
46066
|
+
tiles.push({ x, y, ...dungeonTerrain(x, y, stairsX, stairsY, manifest) });
|
|
44946
46067
|
}
|
|
44947
46068
|
}
|
|
44948
46069
|
return tiles;
|
|
@@ -44972,20 +46093,48 @@ function RoguelikeBoard({
|
|
|
44972
46093
|
className
|
|
44973
46094
|
}) {
|
|
44974
46095
|
const board = boardEntity(entity) ?? {};
|
|
44975
|
-
const
|
|
44976
|
-
const
|
|
44977
|
-
const
|
|
44978
|
-
const
|
|
44979
|
-
|
|
44980
|
-
|
|
46096
|
+
const assetManifest = propAssetManifest ?? board.assetManifest;
|
|
46097
|
+
const stairsX = propStairsX ?? num(board.stairsX, 14);
|
|
46098
|
+
const stairsY = propStairsY ?? num(board.stairsY, 14);
|
|
46099
|
+
const entityTiles = useMemo(
|
|
46100
|
+
() => rows(board.tiles).map((r) => ({
|
|
46101
|
+
x: num(r.x),
|
|
46102
|
+
y: num(r.y),
|
|
46103
|
+
terrain: r.terrain == null ? void 0 : str(r.terrain),
|
|
46104
|
+
terrainSprite: r.terrainSprite == null ? void 0 : str(r.terrainSprite),
|
|
46105
|
+
passable: r.passable !== false
|
|
46106
|
+
})),
|
|
46107
|
+
[board.tiles]
|
|
46108
|
+
);
|
|
46109
|
+
const tiles = propTiles ?? (entityTiles.length >= DUNGEON_GRID_W * DUNGEON_GRID_H ? entityTiles : buildDefaultDungeonTiles(stairsX, stairsY, assetManifest));
|
|
46110
|
+
const entityEnemies = useMemo(
|
|
46111
|
+
() => rows(board.enemies).map((r) => ({
|
|
46112
|
+
id: str(r.id),
|
|
46113
|
+
x: num(r.x),
|
|
46114
|
+
y: num(r.y),
|
|
46115
|
+
hp: num(r.hp),
|
|
46116
|
+
attack: num(r.attack)
|
|
46117
|
+
})),
|
|
46118
|
+
[board.enemies]
|
|
46119
|
+
);
|
|
46120
|
+
const enemies = propEnemies ?? (entityEnemies.length > 0 ? entityEnemies : DEFAULT_ENEMIES);
|
|
46121
|
+
const entityItems = useMemo(
|
|
46122
|
+
() => rows(board.items).map((r) => ({
|
|
46123
|
+
id: str(r.id),
|
|
46124
|
+
x: num(r.x),
|
|
46125
|
+
y: num(r.y),
|
|
46126
|
+
kind: str(r.kind) || "health_potion"
|
|
46127
|
+
})),
|
|
46128
|
+
[board.items]
|
|
46129
|
+
);
|
|
46130
|
+
const items = propItems ?? (entityItems.length > 0 ? entityItems : DEFAULT_ITEMS);
|
|
46131
|
+
const player = propPlayer ?? (board.player == null ? { x: 1, y: 1 } : vec2(board.player));
|
|
44981
46132
|
const playerHp = propPlayerHp ?? num(board.playerHp, 10);
|
|
44982
46133
|
const playerMaxHp = propPlayerMaxHp ?? num(board.playerMaxHp, 10);
|
|
44983
46134
|
const playerAttack = propPlayerAttack ?? num(board.playerAttack, 3);
|
|
44984
46135
|
const depth = propDepth ?? num(board.depth, 1);
|
|
44985
46136
|
const result = propResult ?? (str(board.result) || "none");
|
|
44986
46137
|
const phase = propPhase ?? (str(board.phase) || "player_turn");
|
|
44987
|
-
propStairsX ?? num(board.stairsX, 14);
|
|
44988
|
-
propStairsY ?? num(board.stairsY, 14);
|
|
44989
46138
|
const eventBus = useEventBus();
|
|
44990
46139
|
const { t } = useTranslate();
|
|
44991
46140
|
const [hoveredTile, setHoveredTile] = useState(null);
|
|
@@ -45032,7 +46181,7 @@ function RoguelikeBoard({
|
|
|
45032
46181
|
health: playerHp,
|
|
45033
46182
|
maxHealth: playerMaxHp,
|
|
45034
46183
|
unitType: "player",
|
|
45035
|
-
sprite:
|
|
46184
|
+
sprite: resolveManifestUrl3(assetManifest, assetManifest?.units?.player)
|
|
45036
46185
|
},
|
|
45037
46186
|
...liveEnemies.map((e) => ({
|
|
45038
46187
|
id: e.id,
|
|
@@ -45042,19 +46191,19 @@ function RoguelikeBoard({
|
|
|
45042
46191
|
health: e.hp,
|
|
45043
46192
|
maxHealth: 6,
|
|
45044
46193
|
unitType: "enemy",
|
|
45045
|
-
sprite:
|
|
46194
|
+
sprite: resolveManifestUrl3(assetManifest, assetManifest?.units?.enemy)
|
|
45046
46195
|
}))
|
|
45047
46196
|
];
|
|
45048
|
-
}, [player, enemies, playerHp, playerMaxHp, t]);
|
|
46197
|
+
}, [player, enemies, playerHp, playerMaxHp, assetManifest, t]);
|
|
45049
46198
|
const isoFeatures = useMemo(
|
|
45050
46199
|
() => items.map((it) => ({
|
|
45051
46200
|
id: it.id,
|
|
45052
46201
|
x: it.x,
|
|
45053
46202
|
y: it.y,
|
|
45054
46203
|
type: it.kind,
|
|
45055
|
-
sprite:
|
|
46204
|
+
sprite: resolveManifestUrl3(assetManifest, assetManifest?.features?.[it.kind])
|
|
45056
46205
|
})),
|
|
45057
|
-
[items]
|
|
46206
|
+
[items, assetManifest]
|
|
45058
46207
|
);
|
|
45059
46208
|
const validMoves = useMemo(() => {
|
|
45060
46209
|
if (result !== "none" || phase !== "player_turn") return [];
|
|
@@ -45113,8 +46262,8 @@ function RoguelikeBoard({
|
|
|
45113
46262
|
onTileHover: (x, y) => setHoveredTile({ x, y }),
|
|
45114
46263
|
onTileLeave: () => setHoveredTile(null),
|
|
45115
46264
|
scale,
|
|
45116
|
-
assetBaseUrl:
|
|
45117
|
-
assetManifest
|
|
46265
|
+
assetBaseUrl: assetManifest?.baseUrl,
|
|
46266
|
+
assetManifest,
|
|
45118
46267
|
unitScale,
|
|
45119
46268
|
spriteHeightRatio,
|
|
45120
46269
|
spriteMaxWidthRatio
|
|
@@ -45161,7 +46310,7 @@ function RoguelikeBoard({
|
|
|
45161
46310
|
] }) })
|
|
45162
46311
|
] });
|
|
45163
46312
|
}
|
|
45164
|
-
var
|
|
46313
|
+
var DUNGEON_GRID_W, DUNGEON_GRID_H, DEFAULT_ENEMIES, DEFAULT_ITEMS;
|
|
45165
46314
|
var init_RoguelikeBoard = __esm({
|
|
45166
46315
|
"components/game/organisms/RoguelikeBoard.tsx"() {
|
|
45167
46316
|
"use client";
|
|
@@ -45173,10 +46322,8 @@ var init_RoguelikeBoard = __esm({
|
|
|
45173
46322
|
init_Stack();
|
|
45174
46323
|
init_IsometricCanvas();
|
|
45175
46324
|
init_boardEntity();
|
|
45176
|
-
CDN4 = "https://almadar-kflow-assets.web.app/shared";
|
|
45177
46325
|
DUNGEON_GRID_W = 16;
|
|
45178
46326
|
DUNGEON_GRID_H = 16;
|
|
45179
|
-
buildDefaultDungeonTiles(14, 14);
|
|
45180
46327
|
DEFAULT_ENEMIES = [
|
|
45181
46328
|
{ id: "e1", x: 5, y: 2, hp: 5, attack: 2 },
|
|
45182
46329
|
{ id: "e2", x: 9, y: 6, hp: 4, attack: 1 },
|
|
@@ -45188,11 +46335,6 @@ var init_RoguelikeBoard = __esm({
|
|
|
45188
46335
|
{ id: "i2", x: 7, y: 9, kind: "sword" },
|
|
45189
46336
|
{ id: "i3", x: 11, y: 5, kind: "shield" }
|
|
45190
46337
|
];
|
|
45191
|
-
FEATURE_SPRITE = {
|
|
45192
|
-
health_potion: `${CDN4}/isometric-dungeon/Isometric/chestClosed_E.png`,
|
|
45193
|
-
sword: `${CDN4}/isometric-dungeon/Isometric/barrel_E.png`,
|
|
45194
|
-
shield: `${CDN4}/isometric-dungeon/Isometric/barrel_E.png`
|
|
45195
|
-
};
|
|
45196
46338
|
RoguelikeBoard.displayName = "RoguelikeBoard";
|
|
45197
46339
|
}
|
|
45198
46340
|
});
|
|
@@ -45230,40 +46372,40 @@ function RoguelikeTemplate({
|
|
|
45230
46372
|
}
|
|
45231
46373
|
);
|
|
45232
46374
|
}
|
|
45233
|
-
var
|
|
46375
|
+
var CDN4, DEFAULT_ROGUELIKE_TILES, DEFAULT_ROGUELIKE_MANIFEST;
|
|
45234
46376
|
var init_RoguelikeTemplate = __esm({
|
|
45235
46377
|
"components/game/templates/RoguelikeTemplate.tsx"() {
|
|
45236
46378
|
init_RoguelikeBoard();
|
|
45237
|
-
|
|
46379
|
+
CDN4 = "https://almadar-kflow-assets.web.app/shared";
|
|
45238
46380
|
DEFAULT_ROGUELIKE_TILES = [
|
|
45239
|
-
{ x: 0, y: 0, terrain: "wall", passable: false, terrainSprite: `${
|
|
45240
|
-
{ x: 1, y: 0, terrain: "wall", passable: false, terrainSprite: `${
|
|
45241
|
-
{ x: 2, y: 0, terrain: "wall", passable: false, terrainSprite: `${
|
|
45242
|
-
{ x: 3, y: 0, terrain: "wall", passable: false, terrainSprite: `${
|
|
45243
|
-
{ x: 4, y: 0, terrain: "wall", passable: false, terrainSprite: `${
|
|
45244
|
-
{ x: 0, y: 1, terrain: "wall", passable: false, terrainSprite: `${
|
|
45245
|
-
{ x: 1, y: 1, terrain: "floor", passable: true, terrainSprite: `${
|
|
45246
|
-
{ x: 2, y: 1, terrain: "floor", passable: true, terrainSprite: `${
|
|
45247
|
-
{ x: 3, y: 1, terrain: "floor", passable: true, terrainSprite: `${
|
|
45248
|
-
{ x: 4, y: 1, terrain: "wall", passable: false, terrainSprite: `${
|
|
45249
|
-
{ x: 0, y: 2, terrain: "wall", passable: false, terrainSprite: `${
|
|
45250
|
-
{ x: 1, y: 2, terrain: "floor", passable: true, terrainSprite: `${
|
|
45251
|
-
{ x: 2, y: 2, terrain: "floor", passable: true, terrainSprite: `${
|
|
45252
|
-
{ x: 3, y: 2, terrain: "floor", passable: true, terrainSprite: `${
|
|
45253
|
-
{ x: 4, y: 2, terrain: "wall", passable: false, terrainSprite: `${
|
|
45254
|
-
{ x: 0, y: 3, terrain: "wall", passable: false, terrainSprite: `${
|
|
45255
|
-
{ x: 1, y: 3, terrain: "floor", passable: true, terrainSprite: `${
|
|
45256
|
-
{ x: 2, y: 3, terrain: "floor", passable: true, terrainSprite: `${
|
|
45257
|
-
{ x: 3, y: 3, terrain: "stairs", passable: true, terrainSprite: `${
|
|
45258
|
-
{ x: 4, y: 3, terrain: "wall", passable: false, terrainSprite: `${
|
|
45259
|
-
{ x: 0, y: 4, terrain: "wall", passable: false, terrainSprite: `${
|
|
45260
|
-
{ x: 1, y: 4, terrain: "wall", passable: false, terrainSprite: `${
|
|
45261
|
-
{ x: 2, y: 4, terrain: "wall", passable: false, terrainSprite: `${
|
|
45262
|
-
{ x: 3, y: 4, terrain: "wall", passable: false, terrainSprite: `${
|
|
45263
|
-
{ x: 4, y: 4, terrain: "wall", passable: false, terrainSprite: `${
|
|
46381
|
+
{ x: 0, y: 0, terrain: "wall", passable: false, terrainSprite: `${CDN4}/isometric-dungeon/Isometric/stoneInset_E.png` },
|
|
46382
|
+
{ x: 1, y: 0, terrain: "wall", passable: false, terrainSprite: `${CDN4}/isometric-dungeon/Isometric/stoneInset_E.png` },
|
|
46383
|
+
{ x: 2, y: 0, terrain: "wall", passable: false, terrainSprite: `${CDN4}/isometric-dungeon/Isometric/stoneInset_E.png` },
|
|
46384
|
+
{ x: 3, y: 0, terrain: "wall", passable: false, terrainSprite: `${CDN4}/isometric-dungeon/Isometric/stoneInset_E.png` },
|
|
46385
|
+
{ x: 4, y: 0, terrain: "wall", passable: false, terrainSprite: `${CDN4}/isometric-dungeon/Isometric/stoneInset_E.png` },
|
|
46386
|
+
{ x: 0, y: 1, terrain: "wall", passable: false, terrainSprite: `${CDN4}/isometric-dungeon/Isometric/stoneInset_E.png` },
|
|
46387
|
+
{ x: 1, y: 1, terrain: "floor", passable: true, terrainSprite: `${CDN4}/isometric-dungeon/Isometric/dirt_E.png` },
|
|
46388
|
+
{ x: 2, y: 1, terrain: "floor", passable: true, terrainSprite: `${CDN4}/isometric-dungeon/Isometric/dirt_E.png` },
|
|
46389
|
+
{ x: 3, y: 1, terrain: "floor", passable: true, terrainSprite: `${CDN4}/isometric-dungeon/Isometric/dirt_E.png` },
|
|
46390
|
+
{ x: 4, y: 1, terrain: "wall", passable: false, terrainSprite: `${CDN4}/isometric-dungeon/Isometric/stoneInset_E.png` },
|
|
46391
|
+
{ x: 0, y: 2, terrain: "wall", passable: false, terrainSprite: `${CDN4}/isometric-dungeon/Isometric/stoneInset_E.png` },
|
|
46392
|
+
{ x: 1, y: 2, terrain: "floor", passable: true, terrainSprite: `${CDN4}/isometric-dungeon/Isometric/dirtTiles_E.png` },
|
|
46393
|
+
{ x: 2, y: 2, terrain: "floor", passable: true, terrainSprite: `${CDN4}/isometric-dungeon/Isometric/dirtTiles_E.png` },
|
|
46394
|
+
{ x: 3, y: 2, terrain: "floor", passable: true, terrainSprite: `${CDN4}/isometric-dungeon/Isometric/dirt_E.png` },
|
|
46395
|
+
{ x: 4, y: 2, terrain: "wall", passable: false, terrainSprite: `${CDN4}/isometric-dungeon/Isometric/stoneInset_E.png` },
|
|
46396
|
+
{ x: 0, y: 3, terrain: "wall", passable: false, terrainSprite: `${CDN4}/isometric-dungeon/Isometric/stoneInset_E.png` },
|
|
46397
|
+
{ x: 1, y: 3, terrain: "floor", passable: true, terrainSprite: `${CDN4}/isometric-dungeon/Isometric/dirt_E.png` },
|
|
46398
|
+
{ x: 2, y: 3, terrain: "floor", passable: true, terrainSprite: `${CDN4}/isometric-dungeon/Isometric/dirtTiles_E.png` },
|
|
46399
|
+
{ x: 3, y: 3, terrain: "stairs", passable: true, terrainSprite: `${CDN4}/isometric-dungeon/Isometric/stairs_E.png` },
|
|
46400
|
+
{ x: 4, y: 3, terrain: "wall", passable: false, terrainSprite: `${CDN4}/isometric-dungeon/Isometric/stoneInset_E.png` },
|
|
46401
|
+
{ x: 0, y: 4, terrain: "wall", passable: false, terrainSprite: `${CDN4}/isometric-dungeon/Isometric/stoneInset_E.png` },
|
|
46402
|
+
{ x: 1, y: 4, terrain: "wall", passable: false, terrainSprite: `${CDN4}/isometric-dungeon/Isometric/stoneInset_E.png` },
|
|
46403
|
+
{ x: 2, y: 4, terrain: "wall", passable: false, terrainSprite: `${CDN4}/isometric-dungeon/Isometric/stoneInset_E.png` },
|
|
46404
|
+
{ x: 3, y: 4, terrain: "wall", passable: false, terrainSprite: `${CDN4}/isometric-dungeon/Isometric/stoneInset_E.png` },
|
|
46405
|
+
{ x: 4, y: 4, terrain: "wall", passable: false, terrainSprite: `${CDN4}/isometric-dungeon/Isometric/stoneInset_E.png` }
|
|
45264
46406
|
];
|
|
45265
46407
|
DEFAULT_ROGUELIKE_MANIFEST = {
|
|
45266
|
-
baseUrl:
|
|
46408
|
+
baseUrl: CDN4,
|
|
45267
46409
|
terrains: {
|
|
45268
46410
|
floor: "/isometric-dungeon/Isometric/dirt_E.png",
|
|
45269
46411
|
wall: "/isometric-dungeon/Isometric/stoneInset_E.png",
|
|
@@ -45370,7 +46512,7 @@ var init_debugRegistry = __esm({
|
|
|
45370
46512
|
}
|
|
45371
46513
|
});
|
|
45372
46514
|
function useDebugData() {
|
|
45373
|
-
const [data, setData] =
|
|
46515
|
+
const [data, setData] = React85.useState(() => ({
|
|
45374
46516
|
traits: [],
|
|
45375
46517
|
ticks: [],
|
|
45376
46518
|
guards: [],
|
|
@@ -45384,7 +46526,7 @@ function useDebugData() {
|
|
|
45384
46526
|
},
|
|
45385
46527
|
lastUpdate: Date.now()
|
|
45386
46528
|
}));
|
|
45387
|
-
|
|
46529
|
+
React85.useEffect(() => {
|
|
45388
46530
|
const updateData = () => {
|
|
45389
46531
|
setData({
|
|
45390
46532
|
traits: getAllTraits(),
|
|
@@ -45493,12 +46635,12 @@ function layoutGraph(states, transitions, initialState, width, height) {
|
|
|
45493
46635
|
return positions;
|
|
45494
46636
|
}
|
|
45495
46637
|
function WalkMinimap() {
|
|
45496
|
-
const [walkStep, setWalkStep] =
|
|
45497
|
-
const [traits2, setTraits] =
|
|
45498
|
-
const [coveredEdges, setCoveredEdges] =
|
|
45499
|
-
const [completedTraits, setCompletedTraits] =
|
|
45500
|
-
const prevTraitRef =
|
|
45501
|
-
|
|
46638
|
+
const [walkStep, setWalkStep] = React85.useState(null);
|
|
46639
|
+
const [traits2, setTraits] = React85.useState([]);
|
|
46640
|
+
const [coveredEdges, setCoveredEdges] = React85.useState([]);
|
|
46641
|
+
const [completedTraits, setCompletedTraits] = React85.useState(/* @__PURE__ */ new Set());
|
|
46642
|
+
const prevTraitRef = React85.useRef(null);
|
|
46643
|
+
React85.useEffect(() => {
|
|
45502
46644
|
const interval = setInterval(() => {
|
|
45503
46645
|
const w = window;
|
|
45504
46646
|
const step = w.__orbitalWalkStep;
|
|
@@ -45934,15 +47076,15 @@ var init_EntitiesTab = __esm({
|
|
|
45934
47076
|
});
|
|
45935
47077
|
function EventFlowTab({ events: events2 }) {
|
|
45936
47078
|
const { t } = useTranslate();
|
|
45937
|
-
const [filter, setFilter] =
|
|
45938
|
-
const containerRef =
|
|
45939
|
-
const [autoScroll, setAutoScroll] =
|
|
45940
|
-
|
|
47079
|
+
const [filter, setFilter] = React85.useState("all");
|
|
47080
|
+
const containerRef = React85.useRef(null);
|
|
47081
|
+
const [autoScroll, setAutoScroll] = React85.useState(true);
|
|
47082
|
+
React85.useEffect(() => {
|
|
45941
47083
|
if (autoScroll && containerRef.current) {
|
|
45942
47084
|
containerRef.current.scrollTop = containerRef.current.scrollHeight;
|
|
45943
47085
|
}
|
|
45944
47086
|
}, [events2.length, autoScroll]);
|
|
45945
|
-
const filteredEvents =
|
|
47087
|
+
const filteredEvents = React85.useMemo(() => {
|
|
45946
47088
|
if (filter === "all") return events2;
|
|
45947
47089
|
return events2.filter((e) => e.type === filter);
|
|
45948
47090
|
}, [events2, filter]);
|
|
@@ -46058,7 +47200,7 @@ var init_EventFlowTab = __esm({
|
|
|
46058
47200
|
});
|
|
46059
47201
|
function GuardsPanel({ guards }) {
|
|
46060
47202
|
const { t } = useTranslate();
|
|
46061
|
-
const [filter, setFilter] =
|
|
47203
|
+
const [filter, setFilter] = React85.useState("all");
|
|
46062
47204
|
if (guards.length === 0) {
|
|
46063
47205
|
return /* @__PURE__ */ jsx(
|
|
46064
47206
|
EmptyState,
|
|
@@ -46071,7 +47213,7 @@ function GuardsPanel({ guards }) {
|
|
|
46071
47213
|
}
|
|
46072
47214
|
const passedCount = guards.filter((g) => g.result).length;
|
|
46073
47215
|
const failedCount = guards.length - passedCount;
|
|
46074
|
-
const filteredGuards =
|
|
47216
|
+
const filteredGuards = React85.useMemo(() => {
|
|
46075
47217
|
if (filter === "all") return guards;
|
|
46076
47218
|
if (filter === "passed") return guards.filter((g) => g.result);
|
|
46077
47219
|
return guards.filter((g) => !g.result);
|
|
@@ -46234,10 +47376,10 @@ function EffectBadge({ effect }) {
|
|
|
46234
47376
|
}
|
|
46235
47377
|
function TransitionTimeline({ transitions }) {
|
|
46236
47378
|
const { t } = useTranslate();
|
|
46237
|
-
const containerRef =
|
|
46238
|
-
const [autoScroll, setAutoScroll] =
|
|
46239
|
-
const [expandedId, setExpandedId] =
|
|
46240
|
-
|
|
47379
|
+
const containerRef = React85.useRef(null);
|
|
47380
|
+
const [autoScroll, setAutoScroll] = React85.useState(true);
|
|
47381
|
+
const [expandedId, setExpandedId] = React85.useState(null);
|
|
47382
|
+
React85.useEffect(() => {
|
|
46241
47383
|
if (autoScroll && containerRef.current) {
|
|
46242
47384
|
containerRef.current.scrollTop = containerRef.current.scrollHeight;
|
|
46243
47385
|
}
|
|
@@ -46517,9 +47659,9 @@ function getAllEvents(traits2) {
|
|
|
46517
47659
|
function EventDispatcherTab({ traits: traits2, schema }) {
|
|
46518
47660
|
const eventBus = useEventBus();
|
|
46519
47661
|
const { t } = useTranslate();
|
|
46520
|
-
const [log13, setLog] =
|
|
46521
|
-
const prevStatesRef =
|
|
46522
|
-
|
|
47662
|
+
const [log13, setLog] = React85.useState([]);
|
|
47663
|
+
const prevStatesRef = React85.useRef(/* @__PURE__ */ new Map());
|
|
47664
|
+
React85.useEffect(() => {
|
|
46523
47665
|
for (const trait of traits2) {
|
|
46524
47666
|
const prev = prevStatesRef.current.get(trait.id);
|
|
46525
47667
|
if (prev && prev !== trait.currentState) {
|
|
@@ -46688,10 +47830,10 @@ function VerifyModePanel({
|
|
|
46688
47830
|
localCount
|
|
46689
47831
|
}) {
|
|
46690
47832
|
const { t } = useTranslate();
|
|
46691
|
-
const [expanded, setExpanded] =
|
|
46692
|
-
const scrollRef =
|
|
46693
|
-
const prevCountRef =
|
|
46694
|
-
|
|
47833
|
+
const [expanded, setExpanded] = React85.useState(true);
|
|
47834
|
+
const scrollRef = React85.useRef(null);
|
|
47835
|
+
const prevCountRef = React85.useRef(0);
|
|
47836
|
+
React85.useEffect(() => {
|
|
46695
47837
|
if (expanded && transitions.length > prevCountRef.current && scrollRef.current) {
|
|
46696
47838
|
scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
|
|
46697
47839
|
}
|
|
@@ -46748,10 +47890,10 @@ function RuntimeDebugger({
|
|
|
46748
47890
|
schema
|
|
46749
47891
|
}) {
|
|
46750
47892
|
const { t } = useTranslate();
|
|
46751
|
-
const [isCollapsed, setIsCollapsed] =
|
|
46752
|
-
const [isVisible, setIsVisible] =
|
|
47893
|
+
const [isCollapsed, setIsCollapsed] = React85.useState(mode === "verify" ? true : defaultCollapsed);
|
|
47894
|
+
const [isVisible, setIsVisible] = React85.useState(mode === "inline" || mode === "verify" || isDebugEnabled2());
|
|
46753
47895
|
const debugData = useDebugData();
|
|
46754
|
-
|
|
47896
|
+
React85.useEffect(() => {
|
|
46755
47897
|
if (mode === "inline") return;
|
|
46756
47898
|
return onDebugToggle((enabled) => {
|
|
46757
47899
|
setIsVisible(enabled);
|
|
@@ -46760,7 +47902,7 @@ function RuntimeDebugger({
|
|
|
46760
47902
|
}
|
|
46761
47903
|
});
|
|
46762
47904
|
}, [mode]);
|
|
46763
|
-
|
|
47905
|
+
React85.useEffect(() => {
|
|
46764
47906
|
if (mode === "inline") return;
|
|
46765
47907
|
const handleKeyDown = (e) => {
|
|
46766
47908
|
if (e.key === "`" && isVisible) {
|
|
@@ -47320,7 +48462,7 @@ function SequenceBar({
|
|
|
47320
48462
|
onSlotRemove(index);
|
|
47321
48463
|
}, [onSlotRemove, playing]);
|
|
47322
48464
|
const paddedSlots = Array.from({ length: maxSlots }, (_, i) => slots[i]);
|
|
47323
|
-
return /* @__PURE__ */ jsx(HStack, { className: cn("items-center", className), gap: "sm", children: paddedSlots.map((slot, i) => /* @__PURE__ */ jsxs(
|
|
48465
|
+
return /* @__PURE__ */ jsx(HStack, { className: cn("items-center", className), gap: "sm", children: paddedSlots.map((slot, i) => /* @__PURE__ */ jsxs(React85__default.Fragment, { children: [
|
|
47324
48466
|
i > 0 && /* @__PURE__ */ jsx(
|
|
47325
48467
|
Typography,
|
|
47326
48468
|
{
|
|
@@ -48100,20 +49242,21 @@ var init_SplitPane = __esm({
|
|
|
48100
49242
|
const [ratio, setRatio] = useState(initialRatio);
|
|
48101
49243
|
const containerRef = useRef(null);
|
|
48102
49244
|
const isDragging = useRef(false);
|
|
48103
|
-
const
|
|
49245
|
+
const handlePointerDown = useCallback(
|
|
48104
49246
|
(e) => {
|
|
48105
49247
|
if (!resizable) return;
|
|
48106
49248
|
e.preventDefault();
|
|
48107
49249
|
isDragging.current = true;
|
|
48108
|
-
|
|
49250
|
+
e.currentTarget.setPointerCapture(e.pointerId);
|
|
49251
|
+
const handlePointerMove = (ev) => {
|
|
48109
49252
|
if (!isDragging.current || !containerRef.current) return;
|
|
48110
49253
|
const rect = containerRef.current.getBoundingClientRect();
|
|
48111
49254
|
let newRatio;
|
|
48112
49255
|
if (direction === "horizontal") {
|
|
48113
|
-
const x =
|
|
49256
|
+
const x = ev.clientX - rect.left;
|
|
48114
49257
|
newRatio = x / rect.width * 100;
|
|
48115
49258
|
} else {
|
|
48116
|
-
const y =
|
|
49259
|
+
const y = ev.clientY - rect.top;
|
|
48117
49260
|
newRatio = y / rect.height * 100;
|
|
48118
49261
|
}
|
|
48119
49262
|
const minRatio = minSize / (direction === "horizontal" ? rect.width : rect.height) * 100;
|
|
@@ -48121,13 +49264,15 @@ var init_SplitPane = __esm({
|
|
|
48121
49264
|
newRatio = Math.max(minRatio, Math.min(maxRatio, newRatio));
|
|
48122
49265
|
setRatio(newRatio);
|
|
48123
49266
|
};
|
|
48124
|
-
const
|
|
49267
|
+
const handlePointerUp = () => {
|
|
48125
49268
|
isDragging.current = false;
|
|
48126
|
-
document.removeEventListener("
|
|
48127
|
-
document.removeEventListener("
|
|
49269
|
+
document.removeEventListener("pointermove", handlePointerMove);
|
|
49270
|
+
document.removeEventListener("pointerup", handlePointerUp);
|
|
49271
|
+
document.removeEventListener("pointercancel", handlePointerUp);
|
|
48128
49272
|
};
|
|
48129
|
-
document.addEventListener("
|
|
48130
|
-
document.addEventListener("
|
|
49273
|
+
document.addEventListener("pointermove", handlePointerMove);
|
|
49274
|
+
document.addEventListener("pointerup", handlePointerUp);
|
|
49275
|
+
document.addEventListener("pointercancel", handlePointerUp);
|
|
48131
49276
|
},
|
|
48132
49277
|
[direction, minSize, resizable]
|
|
48133
49278
|
);
|
|
@@ -48156,9 +49301,9 @@ var init_SplitPane = __esm({
|
|
|
48156
49301
|
resizable && /* @__PURE__ */ jsx(
|
|
48157
49302
|
"div",
|
|
48158
49303
|
{
|
|
48159
|
-
|
|
49304
|
+
onPointerDown: handlePointerDown,
|
|
48160
49305
|
className: cn(
|
|
48161
|
-
"flex-shrink-0 bg-border transition-colors",
|
|
49306
|
+
"flex-shrink-0 bg-border transition-colors touch-none",
|
|
48162
49307
|
isHorizontal ? "w-1 cursor-col-resize hover:w-1.5 hover:bg-muted-foreground" : "h-1 cursor-row-resize hover:h-1.5 hover:bg-muted-foreground"
|
|
48163
49308
|
)
|
|
48164
49309
|
}
|
|
@@ -48209,7 +49354,7 @@ var init_StatCard = __esm({
|
|
|
48209
49354
|
const labelToUse = propLabel ?? propTitle;
|
|
48210
49355
|
const eventBus = useEventBus();
|
|
48211
49356
|
const { t } = useTranslate();
|
|
48212
|
-
const handleActionClick =
|
|
49357
|
+
const handleActionClick = React85__default.useCallback(() => {
|
|
48213
49358
|
if (action?.event) {
|
|
48214
49359
|
eventBus.emit(`UI:${action.event}`, {});
|
|
48215
49360
|
}
|
|
@@ -48220,7 +49365,7 @@ var init_StatCard = __esm({
|
|
|
48220
49365
|
const data = Array.isArray(entity) ? entity : entity ? [entity] : [];
|
|
48221
49366
|
const isLoading = externalLoading ?? false;
|
|
48222
49367
|
const error = externalError;
|
|
48223
|
-
const computeMetricValue =
|
|
49368
|
+
const computeMetricValue = React85__default.useCallback(
|
|
48224
49369
|
(metric, items) => {
|
|
48225
49370
|
if (metric.value !== void 0) {
|
|
48226
49371
|
return metric.value;
|
|
@@ -48259,7 +49404,7 @@ var init_StatCard = __esm({
|
|
|
48259
49404
|
},
|
|
48260
49405
|
[]
|
|
48261
49406
|
);
|
|
48262
|
-
const schemaStats =
|
|
49407
|
+
const schemaStats = React85__default.useMemo(() => {
|
|
48263
49408
|
if (!metrics || metrics.length === 0) return null;
|
|
48264
49409
|
return metrics.map((metric) => ({
|
|
48265
49410
|
label: metric.label,
|
|
@@ -48267,7 +49412,7 @@ var init_StatCard = __esm({
|
|
|
48267
49412
|
format: metric.format
|
|
48268
49413
|
}));
|
|
48269
49414
|
}, [metrics, data, computeMetricValue]);
|
|
48270
|
-
const calculatedTrend =
|
|
49415
|
+
const calculatedTrend = React85__default.useMemo(() => {
|
|
48271
49416
|
if (manualTrend !== void 0) return manualTrend;
|
|
48272
49417
|
if (previousValue === void 0 || currentValue === void 0)
|
|
48273
49418
|
return void 0;
|
|
@@ -49233,7 +50378,7 @@ var init_Timeline = __esm({
|
|
|
49233
50378
|
}) => {
|
|
49234
50379
|
const { t } = useTranslate();
|
|
49235
50380
|
const entityData = Array.isArray(entity) ? entity : [];
|
|
49236
|
-
const items =
|
|
50381
|
+
const items = React85__default.useMemo(() => {
|
|
49237
50382
|
if (propItems) return propItems;
|
|
49238
50383
|
if (entityData.length === 0) return [];
|
|
49239
50384
|
return entityData.map((record, idx) => {
|
|
@@ -49340,7 +50485,7 @@ var init_Timeline = __esm({
|
|
|
49340
50485
|
}
|
|
49341
50486
|
});
|
|
49342
50487
|
function extractToastProps(children) {
|
|
49343
|
-
if (!
|
|
50488
|
+
if (!React85__default.isValidElement(children)) {
|
|
49344
50489
|
if (typeof children === "string") {
|
|
49345
50490
|
return { message: children };
|
|
49346
50491
|
}
|
|
@@ -49378,7 +50523,7 @@ var init_ToastSlot = __esm({
|
|
|
49378
50523
|
eventBus.emit("UI:CLOSE");
|
|
49379
50524
|
};
|
|
49380
50525
|
if (!isVisible) return null;
|
|
49381
|
-
const isCustomContent =
|
|
50526
|
+
const isCustomContent = React85__default.isValidElement(children) && !message;
|
|
49382
50527
|
return /* @__PURE__ */ jsx(Box, { className: "fixed bottom-4 right-4 z-50", children: isCustomContent ? children : /* @__PURE__ */ jsx(
|
|
49383
50528
|
Toast,
|
|
49384
50529
|
{
|
|
@@ -49394,82 +50539,442 @@ var init_ToastSlot = __esm({
|
|
|
49394
50539
|
ToastSlot.displayName = "ToastSlot";
|
|
49395
50540
|
}
|
|
49396
50541
|
});
|
|
50542
|
+
function resolveManifestUrl4(manifest, relative) {
|
|
50543
|
+
if (relative == null || relative === "") return void 0;
|
|
50544
|
+
if (/^https?:\/\//.test(relative)) return relative;
|
|
50545
|
+
const base = manifest?.baseUrl;
|
|
50546
|
+
if (base == null) return relative;
|
|
50547
|
+
const cleanBase = base.replace(/\/$/, "");
|
|
50548
|
+
const cleanRel = relative.replace(/^\//, "");
|
|
50549
|
+
return `${cleanBase}/${cleanRel}`;
|
|
50550
|
+
}
|
|
50551
|
+
function readPlayer(v) {
|
|
50552
|
+
if (v == null || typeof v !== "object") return void 0;
|
|
50553
|
+
const o = v;
|
|
50554
|
+
return { x: num(o.x), y: num(o.y) };
|
|
50555
|
+
}
|
|
50556
|
+
function TopDownShooterBoard({
|
|
50557
|
+
entity,
|
|
50558
|
+
player: propPlayer,
|
|
50559
|
+
enemies: propEnemies,
|
|
50560
|
+
projectiles: propProjectiles,
|
|
50561
|
+
score: propScore,
|
|
50562
|
+
wave: propWave,
|
|
50563
|
+
lives: propLives,
|
|
50564
|
+
result: propResult,
|
|
50565
|
+
assetManifest: propAssetManifest,
|
|
50566
|
+
width = DEFAULT_WIDTH,
|
|
50567
|
+
height = DEFAULT_HEIGHT,
|
|
50568
|
+
spriteSize = 32,
|
|
50569
|
+
moveEvent = "MOVE",
|
|
50570
|
+
fireEvent = "FIRE",
|
|
50571
|
+
playAgainEvent = "PLAY_AGAIN",
|
|
50572
|
+
gameEndEvent = "GAME_END",
|
|
50573
|
+
className
|
|
50574
|
+
}) {
|
|
50575
|
+
const board = boardEntity(entity) ?? {};
|
|
50576
|
+
const eventBus = useEventBus();
|
|
50577
|
+
const { t } = useTranslate();
|
|
50578
|
+
const assetManifest = propAssetManifest ?? board.assetManifest;
|
|
50579
|
+
const player = propPlayer ?? readPlayer(board.player) ?? { x: width / 2, y: height - spriteSize };
|
|
50580
|
+
const enemies = useMemo(
|
|
50581
|
+
() => propEnemies ?? rows(board.enemies).map((r) => ({
|
|
50582
|
+
id: str(r.id),
|
|
50583
|
+
x: num(r.x),
|
|
50584
|
+
y: num(r.y),
|
|
50585
|
+
hp: num(r.hp, 1)
|
|
50586
|
+
})),
|
|
50587
|
+
[propEnemies, board.enemies]
|
|
50588
|
+
);
|
|
50589
|
+
const projectiles = useMemo(
|
|
50590
|
+
() => propProjectiles ?? rows(board.projectiles).map((r) => ({
|
|
50591
|
+
id: str(r.id),
|
|
50592
|
+
x: num(r.x),
|
|
50593
|
+
y: num(r.y),
|
|
50594
|
+
vx: num(r.vx),
|
|
50595
|
+
vy: num(r.vy)
|
|
50596
|
+
})),
|
|
50597
|
+
[propProjectiles, board.projectiles]
|
|
50598
|
+
);
|
|
50599
|
+
const score = propScore ?? num(board.score, 0);
|
|
50600
|
+
const wave = propWave ?? num(board.wave, 1);
|
|
50601
|
+
const lives = propLives ?? num(board.lives, 3);
|
|
50602
|
+
const result = propResult ?? (str(board.result) || "none");
|
|
50603
|
+
const playerSprite = resolveManifestUrl4(assetManifest, assetManifest?.units?.player);
|
|
50604
|
+
const enemySprite = resolveManifestUrl4(assetManifest, assetManifest?.units?.enemy);
|
|
50605
|
+
const projectileSprite = resolveManifestUrl4(assetManifest, assetManifest?.features?.projectile);
|
|
50606
|
+
const backgroundSprite = resolveManifestUrl4(assetManifest, assetManifest?.background);
|
|
50607
|
+
const spriteUrls = useMemo(
|
|
50608
|
+
() => [playerSprite, enemySprite, projectileSprite].filter((u) => u != null),
|
|
50609
|
+
[playerSprite, enemySprite, projectileSprite]
|
|
50610
|
+
);
|
|
50611
|
+
const { getImage } = useImageCache(spriteUrls);
|
|
50612
|
+
const sceneRef = useRef({ player, enemies, projectiles, playerSprite, enemySprite, projectileSprite });
|
|
50613
|
+
sceneRef.current = { player, enemies, projectiles, playerSprite, enemySprite, projectileSprite };
|
|
50614
|
+
boardLog2.debug("shooter-resolve", {
|
|
50615
|
+
player: { x: player.x, y: player.y },
|
|
50616
|
+
enemyCount: enemies.length,
|
|
50617
|
+
projectileCount: projectiles.length,
|
|
50618
|
+
wave,
|
|
50619
|
+
lives,
|
|
50620
|
+
result,
|
|
50621
|
+
hasPlayerSprite: playerSprite != null
|
|
50622
|
+
});
|
|
50623
|
+
const onDraw = useCallback(
|
|
50624
|
+
(ctx, _frame) => {
|
|
50625
|
+
const scene = sceneRef.current;
|
|
50626
|
+
ctx.fillStyle = "#10141c";
|
|
50627
|
+
ctx.fillRect(0, 0, width, height);
|
|
50628
|
+
const half = spriteSize / 2;
|
|
50629
|
+
for (const p2 of scene.projectiles) {
|
|
50630
|
+
const img = scene.projectileSprite ? getImage(scene.projectileSprite) : void 0;
|
|
50631
|
+
if (img) {
|
|
50632
|
+
ctx.drawImage(img, p2.x - half / 2, p2.y - half / 2, spriteSize / 2, spriteSize / 2);
|
|
50633
|
+
} else {
|
|
50634
|
+
ctx.fillStyle = "#ffd34d";
|
|
50635
|
+
ctx.beginPath();
|
|
50636
|
+
ctx.arc(p2.x, p2.y, spriteSize / 6, 0, Math.PI * 2);
|
|
50637
|
+
ctx.fill();
|
|
50638
|
+
}
|
|
50639
|
+
}
|
|
50640
|
+
for (const e of scene.enemies) {
|
|
50641
|
+
const img = scene.enemySprite ? getImage(scene.enemySprite) : void 0;
|
|
50642
|
+
if (img) {
|
|
50643
|
+
ctx.drawImage(img, e.x - half, e.y - half, spriteSize, spriteSize);
|
|
50644
|
+
} else {
|
|
50645
|
+
ctx.fillStyle = "#e0524d";
|
|
50646
|
+
ctx.fillRect(e.x - half, e.y - half, spriteSize, spriteSize);
|
|
50647
|
+
}
|
|
50648
|
+
}
|
|
50649
|
+
const pImg = scene.playerSprite ? getImage(scene.playerSprite) : void 0;
|
|
50650
|
+
if (pImg) {
|
|
50651
|
+
ctx.drawImage(pImg, scene.player.x - half, scene.player.y - half, spriteSize, spriteSize);
|
|
50652
|
+
} else {
|
|
50653
|
+
ctx.fillStyle = "#4da3ff";
|
|
50654
|
+
ctx.beginPath();
|
|
50655
|
+
ctx.moveTo(scene.player.x, scene.player.y - half);
|
|
50656
|
+
ctx.lineTo(scene.player.x + half, scene.player.y + half);
|
|
50657
|
+
ctx.lineTo(scene.player.x - half, scene.player.y + half);
|
|
50658
|
+
ctx.closePath();
|
|
50659
|
+
ctx.fill();
|
|
50660
|
+
}
|
|
50661
|
+
},
|
|
50662
|
+
[getImage, width, height, spriteSize]
|
|
50663
|
+
);
|
|
50664
|
+
const moveEventRef = useRef(moveEvent);
|
|
50665
|
+
moveEventRef.current = moveEvent;
|
|
50666
|
+
const fireEventRef = useRef(fireEvent);
|
|
50667
|
+
fireEventRef.current = fireEvent;
|
|
50668
|
+
const resultRef = useRef(result);
|
|
50669
|
+
resultRef.current = result;
|
|
50670
|
+
const playerRef = useRef(player);
|
|
50671
|
+
playerRef.current = player;
|
|
50672
|
+
useEffect(() => {
|
|
50673
|
+
function onKeyDown(e) {
|
|
50674
|
+
if (resultRef.current !== "none") return;
|
|
50675
|
+
let dx = 0;
|
|
50676
|
+
let dy = 0;
|
|
50677
|
+
switch (e.key) {
|
|
50678
|
+
case "ArrowUp":
|
|
50679
|
+
case "w":
|
|
50680
|
+
dy = -1;
|
|
50681
|
+
break;
|
|
50682
|
+
case "ArrowDown":
|
|
50683
|
+
case "s":
|
|
50684
|
+
dy = 1;
|
|
50685
|
+
break;
|
|
50686
|
+
case "ArrowLeft":
|
|
50687
|
+
case "a":
|
|
50688
|
+
dx = -1;
|
|
50689
|
+
break;
|
|
50690
|
+
case "ArrowRight":
|
|
50691
|
+
case "d":
|
|
50692
|
+
dx = 1;
|
|
50693
|
+
break;
|
|
50694
|
+
case " ": {
|
|
50695
|
+
e.preventDefault();
|
|
50696
|
+
const evt = fireEventRef.current;
|
|
50697
|
+
if (evt) {
|
|
50698
|
+
eventBus.emit(`UI:${evt}`, { tx: playerRef.current.x, ty: 0 });
|
|
50699
|
+
}
|
|
50700
|
+
return;
|
|
50701
|
+
}
|
|
50702
|
+
default:
|
|
50703
|
+
return;
|
|
50704
|
+
}
|
|
50705
|
+
e.preventDefault();
|
|
50706
|
+
const moveEvt = moveEventRef.current;
|
|
50707
|
+
if (moveEvt) {
|
|
50708
|
+
eventBus.emit(`UI:${moveEvt}`, { dx, dy });
|
|
50709
|
+
}
|
|
50710
|
+
}
|
|
50711
|
+
window.addEventListener("keydown", onKeyDown);
|
|
50712
|
+
return () => window.removeEventListener("keydown", onKeyDown);
|
|
50713
|
+
}, [eventBus]);
|
|
50714
|
+
const handleFireClick = useCallback(
|
|
50715
|
+
(e) => {
|
|
50716
|
+
if (result !== "none") return;
|
|
50717
|
+
const evt = fireEventRef.current;
|
|
50718
|
+
if (!evt) return;
|
|
50719
|
+
const rect = e.currentTarget.getBoundingClientRect();
|
|
50720
|
+
const tx = e.clientX - rect.left;
|
|
50721
|
+
const ty = e.clientY - rect.top;
|
|
50722
|
+
eventBus.emit(`UI:${evt}`, { tx, ty });
|
|
50723
|
+
},
|
|
50724
|
+
[result, eventBus]
|
|
50725
|
+
);
|
|
50726
|
+
const handlePlayAgain = useCallback(() => {
|
|
50727
|
+
if (playAgainEvent) {
|
|
50728
|
+
eventBus.emit(`UI:${playAgainEvent}`, {});
|
|
50729
|
+
}
|
|
50730
|
+
}, [playAgainEvent, eventBus]);
|
|
50731
|
+
const gameEndEmittedRef = useRef(false);
|
|
50732
|
+
useEffect(() => {
|
|
50733
|
+
if ((result === "won" || result === "lost") && gameEndEvent) {
|
|
50734
|
+
if (!gameEndEmittedRef.current) {
|
|
50735
|
+
gameEndEmittedRef.current = true;
|
|
50736
|
+
eventBus.emit(`UI:${gameEndEvent}`, { result });
|
|
50737
|
+
}
|
|
50738
|
+
} else {
|
|
50739
|
+
gameEndEmittedRef.current = false;
|
|
50740
|
+
}
|
|
50741
|
+
}, [result, gameEndEvent, eventBus]);
|
|
50742
|
+
const isGameOver = result === "won" || result === "lost";
|
|
50743
|
+
return /* @__PURE__ */ jsxs(VStack, { className: cn("top-down-shooter-board relative bg-background", className), gap: "none", children: [
|
|
50744
|
+
/* @__PURE__ */ jsxs(HStack, { className: "px-4 py-2 border-b border-border bg-surface", gap: "lg", align: "center", children: [
|
|
50745
|
+
/* @__PURE__ */ jsxs(HStack, { gap: "xs", align: "center", children: [
|
|
50746
|
+
/* @__PURE__ */ jsx(Typography, { variant: "small", color: "muted", children: t("shooter.score") ?? "Score" }),
|
|
50747
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body2", weight: "bold", className: "text-warning", children: score })
|
|
50748
|
+
] }),
|
|
50749
|
+
/* @__PURE__ */ jsxs(HStack, { gap: "xs", align: "center", children: [
|
|
50750
|
+
/* @__PURE__ */ jsx(Typography, { variant: "small", color: "muted", children: t("shooter.wave") ?? "Wave" }),
|
|
50751
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body2", weight: "bold", children: wave })
|
|
50752
|
+
] }),
|
|
50753
|
+
/* @__PURE__ */ jsxs(HStack, { gap: "xs", align: "center", children: [
|
|
50754
|
+
/* @__PURE__ */ jsx(Typography, { variant: "small", color: "muted", children: t("shooter.lives") ?? "Lives" }),
|
|
50755
|
+
/* @__PURE__ */ jsx(
|
|
50756
|
+
Typography,
|
|
50757
|
+
{
|
|
50758
|
+
variant: "body2",
|
|
50759
|
+
weight: "bold",
|
|
50760
|
+
className: lives <= 1 ? "text-error" : "text-success",
|
|
50761
|
+
children: lives
|
|
50762
|
+
}
|
|
50763
|
+
)
|
|
50764
|
+
] })
|
|
50765
|
+
] }),
|
|
50766
|
+
/* @__PURE__ */ jsxs(Box, { className: "relative", onClick: handleFireClick, children: [
|
|
50767
|
+
/* @__PURE__ */ jsx(
|
|
50768
|
+
GameCanvas2D,
|
|
50769
|
+
{
|
|
50770
|
+
width,
|
|
50771
|
+
height,
|
|
50772
|
+
backgroundImage: backgroundSprite,
|
|
50773
|
+
assetBaseUrl: assetManifest?.baseUrl,
|
|
50774
|
+
onDraw
|
|
50775
|
+
}
|
|
50776
|
+
),
|
|
50777
|
+
isGameOver && /* @__PURE__ */ jsx(Box, { className: "absolute inset-0 z-50 flex items-center justify-center bg-background/70 backdrop-blur-sm rounded-container", children: /* @__PURE__ */ jsxs(VStack, { className: "text-center p-8", gap: "lg", children: [
|
|
50778
|
+
/* @__PURE__ */ jsx(
|
|
50779
|
+
Typography,
|
|
50780
|
+
{
|
|
50781
|
+
variant: "h2",
|
|
50782
|
+
className: cn(
|
|
50783
|
+
"text-4xl font-black tracking-widest uppercase",
|
|
50784
|
+
result === "won" ? "text-warning" : "text-error"
|
|
50785
|
+
),
|
|
50786
|
+
children: result === "won" ? t("shooter.victory") ?? "Victory!" : t("shooter.defeat") ?? "Defeat!"
|
|
50787
|
+
}
|
|
50788
|
+
),
|
|
50789
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body1", className: "text-muted-foreground", children: result === "won" ? t("shooter.cleared") ?? `Cleared wave ${wave} \u2014 score ${score}` : t("shooter.overrun") ?? "You were overrun." }),
|
|
50790
|
+
/* @__PURE__ */ jsx(
|
|
50791
|
+
Button,
|
|
50792
|
+
{
|
|
50793
|
+
variant: "primary",
|
|
50794
|
+
className: "px-8 py-3 font-semibold",
|
|
50795
|
+
onClick: handlePlayAgain,
|
|
50796
|
+
children: t("shooter.playAgain") ?? "Play Again"
|
|
50797
|
+
}
|
|
50798
|
+
)
|
|
50799
|
+
] }) })
|
|
50800
|
+
] })
|
|
50801
|
+
] });
|
|
50802
|
+
}
|
|
50803
|
+
var boardLog2, DEFAULT_WIDTH, DEFAULT_HEIGHT;
|
|
50804
|
+
var init_TopDownShooterBoard = __esm({
|
|
50805
|
+
"components/game/organisms/TopDownShooterBoard.tsx"() {
|
|
50806
|
+
"use client";
|
|
50807
|
+
init_cn();
|
|
50808
|
+
init_useEventBus();
|
|
50809
|
+
init_Box();
|
|
50810
|
+
init_Button();
|
|
50811
|
+
init_Typography();
|
|
50812
|
+
init_Stack();
|
|
50813
|
+
init_GameCanvas2D();
|
|
50814
|
+
init_useImageCache();
|
|
50815
|
+
init_boardEntity();
|
|
50816
|
+
boardLog2 = createLogger("almadar:ui:game:top-down-shooter-board");
|
|
50817
|
+
DEFAULT_WIDTH = 640;
|
|
50818
|
+
DEFAULT_HEIGHT = 480;
|
|
50819
|
+
TopDownShooterBoard.displayName = "TopDownShooterBoard";
|
|
50820
|
+
}
|
|
50821
|
+
});
|
|
50822
|
+
function isEntityRow3(value) {
|
|
50823
|
+
return value != null && typeof value === "object" && !Array.isArray(value);
|
|
50824
|
+
}
|
|
50825
|
+
function TopDownShooterTemplate({
|
|
50826
|
+
entity,
|
|
50827
|
+
title = "Arena Shooter",
|
|
50828
|
+
player,
|
|
50829
|
+
enemies,
|
|
50830
|
+
projectiles,
|
|
50831
|
+
score,
|
|
50832
|
+
wave,
|
|
50833
|
+
lives,
|
|
50834
|
+
result,
|
|
50835
|
+
assetManifest,
|
|
50836
|
+
width,
|
|
50837
|
+
height,
|
|
50838
|
+
spriteSize,
|
|
50839
|
+
moveEvent,
|
|
50840
|
+
fireEvent,
|
|
50841
|
+
playAgainEvent,
|
|
50842
|
+
gameEndEvent,
|
|
50843
|
+
className
|
|
50844
|
+
}) {
|
|
50845
|
+
const resolved = isEntityRow3(entity) ? entity : void 0;
|
|
50846
|
+
return /* @__PURE__ */ jsxs(
|
|
50847
|
+
Box,
|
|
50848
|
+
{
|
|
50849
|
+
display: "flex",
|
|
50850
|
+
fullHeight: true,
|
|
50851
|
+
className: cn("top-down-shooter-template flex-col", className),
|
|
50852
|
+
children: [
|
|
50853
|
+
/* @__PURE__ */ jsx(
|
|
50854
|
+
HStack,
|
|
50855
|
+
{
|
|
50856
|
+
gap: "sm",
|
|
50857
|
+
align: "center",
|
|
50858
|
+
className: "px-4 py-3 border-b-2 border-border bg-surface shrink-0",
|
|
50859
|
+
children: /* @__PURE__ */ jsx(Typography, { variant: "h4", children: title })
|
|
50860
|
+
}
|
|
50861
|
+
),
|
|
50862
|
+
/* @__PURE__ */ jsx(Box, { className: "flex-1 relative overflow-hidden", children: /* @__PURE__ */ jsx(
|
|
50863
|
+
TopDownShooterBoard,
|
|
50864
|
+
{
|
|
50865
|
+
entity: resolved,
|
|
50866
|
+
player,
|
|
50867
|
+
enemies,
|
|
50868
|
+
projectiles,
|
|
50869
|
+
score,
|
|
50870
|
+
wave,
|
|
50871
|
+
lives,
|
|
50872
|
+
result,
|
|
50873
|
+
assetManifest,
|
|
50874
|
+
width,
|
|
50875
|
+
height,
|
|
50876
|
+
spriteSize,
|
|
50877
|
+
moveEvent,
|
|
50878
|
+
fireEvent,
|
|
50879
|
+
playAgainEvent,
|
|
50880
|
+
gameEndEvent,
|
|
50881
|
+
className: "h-full"
|
|
50882
|
+
}
|
|
50883
|
+
) })
|
|
50884
|
+
]
|
|
50885
|
+
}
|
|
50886
|
+
);
|
|
50887
|
+
}
|
|
50888
|
+
var init_TopDownShooterTemplate = __esm({
|
|
50889
|
+
"components/game/templates/TopDownShooterTemplate.tsx"() {
|
|
50890
|
+
init_cn();
|
|
50891
|
+
init_Box();
|
|
50892
|
+
init_Stack();
|
|
50893
|
+
init_Typography();
|
|
50894
|
+
init_TopDownShooterBoard();
|
|
50895
|
+
TopDownShooterTemplate.displayName = "TopDownShooterTemplate";
|
|
50896
|
+
}
|
|
50897
|
+
});
|
|
50898
|
+
function resolveManifestUrl5(manifest, relative) {
|
|
50899
|
+
if (relative == null) return void 0;
|
|
50900
|
+
if (/^https?:\/\//.test(relative)) return relative;
|
|
50901
|
+
const base = manifest?.baseUrl;
|
|
50902
|
+
if (base == null) return relative;
|
|
50903
|
+
const cleanBase = base.replace(/\/$/, "");
|
|
50904
|
+
const cleanRel = relative.replace(/^\//, "");
|
|
50905
|
+
return `${cleanBase}/${cleanRel}`;
|
|
50906
|
+
}
|
|
49397
50907
|
function buildDefaultTDTiles() {
|
|
49398
50908
|
const pathSet = new Set(DEFAULT_TD_PATH.map((p2) => `${p2.x},${p2.y}`));
|
|
49399
50909
|
const tiles = [];
|
|
49400
50910
|
for (let y = 0; y < TD_GRID_H; y++) {
|
|
49401
50911
|
for (let x = 0; x < TD_GRID_W; x++) {
|
|
49402
50912
|
if (pathSet.has(`${x},${y}`)) {
|
|
49403
|
-
tiles.push({ x, y, terrain: "path", passable: false
|
|
50913
|
+
tiles.push({ x, y, terrain: "path", passable: false });
|
|
49404
50914
|
} else {
|
|
49405
50915
|
const variant = (x * 3 + y * 5 + (x ^ y)) % 3;
|
|
49406
|
-
const terrainKey = ["ground", "grass", "
|
|
49407
|
-
tiles.push({ x, y, terrain: terrainKey, passable: true
|
|
50916
|
+
const terrainKey = ["ground", "grass", "stone"][variant];
|
|
50917
|
+
tiles.push({ x, y, terrain: terrainKey, passable: true });
|
|
49408
50918
|
}
|
|
49409
50919
|
}
|
|
49410
50920
|
}
|
|
49411
50921
|
return tiles;
|
|
49412
50922
|
}
|
|
49413
|
-
function
|
|
49414
|
-
return tiles.map((t) =>
|
|
49415
|
-
|
|
49416
|
-
|
|
49417
|
-
|
|
49418
|
-
|
|
49419
|
-
|
|
49420
|
-
|
|
49421
|
-
|
|
49422
|
-
|
|
49423
|
-
|
|
49424
|
-
|
|
49425
|
-
position: { x: t.x, y: t.y },
|
|
49426
|
-
name: "Tower",
|
|
49427
|
-
team: "player",
|
|
49428
|
-
sprite: TOWER_SPRITE,
|
|
49429
|
-
unitType: "guardian",
|
|
49430
|
-
health: 1,
|
|
49431
|
-
maxHealth: 1
|
|
49432
|
-
}));
|
|
50923
|
+
function tilesToIso2(tiles, manifest) {
|
|
50924
|
+
return tiles.map((t) => {
|
|
50925
|
+
const key = t.terrain ?? "ground";
|
|
50926
|
+
const sprite = t.terrainSprite ?? resolveManifestUrl5(manifest, manifest?.terrains?.[key]) ?? resolveManifestUrl5(manifest, manifest?.terrains?.ground);
|
|
50927
|
+
return {
|
|
50928
|
+
x: t.x,
|
|
50929
|
+
y: t.y,
|
|
50930
|
+
terrain: t.terrain,
|
|
50931
|
+
terrainSprite: sprite,
|
|
50932
|
+
passable: t.passable
|
|
50933
|
+
};
|
|
50934
|
+
});
|
|
49433
50935
|
}
|
|
49434
|
-
function creepsToUnits(creeps) {
|
|
50936
|
+
function creepsToUnits(creeps, manifest) {
|
|
50937
|
+
const sprite = resolveManifestUrl5(manifest, manifest?.units?.creep);
|
|
49435
50938
|
return creeps.map((c) => ({
|
|
49436
50939
|
id: c.id,
|
|
49437
50940
|
position: { x: c.x, y: c.y },
|
|
49438
50941
|
name: "Creep",
|
|
49439
50942
|
team: "enemy",
|
|
49440
|
-
sprite
|
|
49441
|
-
unitType: "
|
|
50943
|
+
sprite,
|
|
50944
|
+
unitType: "creep",
|
|
49442
50945
|
health: c.hp,
|
|
49443
50946
|
maxHealth: c.maxHp
|
|
49444
50947
|
}));
|
|
49445
50948
|
}
|
|
49446
|
-
function
|
|
49447
|
-
return path.map((p2, i) => ({
|
|
49448
|
-
id: `path-${i}`,
|
|
49449
|
-
x: p2.x,
|
|
49450
|
-
y: p2.y,
|
|
49451
|
-
type: "path-marker",
|
|
49452
|
-
sprite: `${CDN6}world-map/road_straight.png`
|
|
49453
|
-
}));
|
|
49454
|
-
}
|
|
49455
|
-
function heroToUnit(hero) {
|
|
50949
|
+
function heroToUnit(hero, manifest) {
|
|
49456
50950
|
return {
|
|
49457
50951
|
id: hero.id,
|
|
49458
50952
|
position: { x: hero.x, y: hero.y },
|
|
49459
50953
|
name: "Hero",
|
|
49460
50954
|
team: "player",
|
|
49461
|
-
sprite:
|
|
49462
|
-
unitType: "
|
|
50955
|
+
sprite: resolveManifestUrl5(manifest, manifest?.units?.hero),
|
|
50956
|
+
unitType: "hero",
|
|
49463
50957
|
health: 1,
|
|
49464
50958
|
maxHealth: 1
|
|
49465
50959
|
};
|
|
49466
50960
|
}
|
|
50961
|
+
function towersToFeatures(towers, manifest) {
|
|
50962
|
+
const sprite = resolveManifestUrl5(manifest, manifest?.features?.tower);
|
|
50963
|
+
return towers.map((t) => ({
|
|
50964
|
+
id: t.id,
|
|
50965
|
+
x: t.x,
|
|
50966
|
+
y: t.y,
|
|
50967
|
+
type: "tower",
|
|
50968
|
+
sprite
|
|
50969
|
+
}));
|
|
50970
|
+
}
|
|
49467
50971
|
function TowerDefenseBoard({
|
|
49468
50972
|
entity,
|
|
49469
50973
|
tiles: propTiles,
|
|
49470
50974
|
path: propPath,
|
|
49471
50975
|
towers: propTowers,
|
|
49472
50976
|
creeps: propCreeps,
|
|
50977
|
+
assetManifest: propAssetManifest,
|
|
49473
50978
|
hero: propHero,
|
|
49474
50979
|
gold: propGold,
|
|
49475
50980
|
lives: propLives,
|
|
@@ -49492,12 +50997,51 @@ function TowerDefenseBoard({
|
|
|
49492
50997
|
const board = boardEntity(entity) ?? {};
|
|
49493
50998
|
const eventBus = useEventBus();
|
|
49494
50999
|
const { t } = useTranslate();
|
|
49495
|
-
const
|
|
51000
|
+
const assetManifest = propAssetManifest ?? board.assetManifest;
|
|
51001
|
+
const entityTiles = useMemo(
|
|
51002
|
+
() => rows(board.tiles).map((r) => ({
|
|
51003
|
+
x: num(r.x),
|
|
51004
|
+
y: num(r.y),
|
|
51005
|
+
terrain: r.terrain == null ? void 0 : str(r.terrain),
|
|
51006
|
+
terrainSprite: r.terrainSprite == null ? void 0 : str(r.terrainSprite),
|
|
51007
|
+
passable: r.passable !== false
|
|
51008
|
+
})),
|
|
51009
|
+
[board.tiles]
|
|
51010
|
+
);
|
|
51011
|
+
const rawTiles = propTiles ?? entityTiles;
|
|
49496
51012
|
const tiles = rawTiles.length >= TD_GRID_W * TD_GRID_H ? rawTiles : DEFAULT_TD_TILES;
|
|
49497
|
-
const
|
|
51013
|
+
const entityPath = useMemo(
|
|
51014
|
+
() => rows(board.path).map((r) => ({ x: num(r.x), y: num(r.y) })),
|
|
51015
|
+
[board.path]
|
|
51016
|
+
);
|
|
51017
|
+
const rawPath = propPath ?? entityPath;
|
|
49498
51018
|
const path = rawPath.length > 0 ? rawPath : DEFAULT_TD_PATH;
|
|
49499
|
-
const
|
|
49500
|
-
|
|
51019
|
+
const entityTowers = useMemo(
|
|
51020
|
+
() => rows(board.towers).map((r) => ({
|
|
51021
|
+
id: str(r.id),
|
|
51022
|
+
x: num(r.x),
|
|
51023
|
+
y: num(r.y),
|
|
51024
|
+
range: num(r.range),
|
|
51025
|
+
damage: num(r.damage),
|
|
51026
|
+
cooldown: num(r.cooldown),
|
|
51027
|
+
lastFiredAt: r.lastFiredAt == null ? void 0 : num(r.lastFiredAt)
|
|
51028
|
+
})),
|
|
51029
|
+
[board.towers]
|
|
51030
|
+
);
|
|
51031
|
+
const towers = propTowers ?? entityTowers;
|
|
51032
|
+
const entityCreeps = useMemo(
|
|
51033
|
+
() => rows(board.creeps).map((r) => ({
|
|
51034
|
+
id: str(r.id),
|
|
51035
|
+
x: num(r.x),
|
|
51036
|
+
y: num(r.y),
|
|
51037
|
+
hp: num(r.hp),
|
|
51038
|
+
maxHp: num(r.maxHp),
|
|
51039
|
+
pathIndex: num(r.pathIndex),
|
|
51040
|
+
speed: num(r.speed)
|
|
51041
|
+
})),
|
|
51042
|
+
[board.creeps]
|
|
51043
|
+
);
|
|
51044
|
+
const creeps = propCreeps ?? entityCreeps;
|
|
49501
51045
|
const hero = propHero ?? { id: "hero", x: 8, y: 8 };
|
|
49502
51046
|
const gold = propGold ?? num(board.gold, 100);
|
|
49503
51047
|
const lives = propLives ?? num(board.lives, 20);
|
|
@@ -49549,12 +51093,11 @@ function TowerDefenseBoard({
|
|
|
49549
51093
|
(t2) => t2.passable !== false && !towerPositions.has(`${t2.x},${t2.y}`) && !pathPositions.has(`${t2.x},${t2.y}`)
|
|
49550
51094
|
).map((t2) => ({ x: t2.x, y: t2.y }));
|
|
49551
51095
|
}, [tiles, towerPositions, pathPositions, result, gold, towerCost]);
|
|
49552
|
-
const isoTiles = useMemo(() =>
|
|
49553
|
-
const
|
|
49554
|
-
const
|
|
49555
|
-
const
|
|
49556
|
-
const
|
|
49557
|
-
const pathFeatures = useMemo(() => pathToFeatures(path), [path]);
|
|
51096
|
+
const isoTiles = useMemo(() => tilesToIso2(tiles, assetManifest), [tiles, assetManifest]);
|
|
51097
|
+
const creepUnits = useMemo(() => creepsToUnits(creeps, assetManifest), [creeps, assetManifest]);
|
|
51098
|
+
const heroUnit = useMemo(() => heroToUnit(hero, assetManifest), [hero, assetManifest]);
|
|
51099
|
+
const isoUnits = useMemo(() => [...creepUnits, heroUnit], [creepUnits, heroUnit]);
|
|
51100
|
+
const towerFeatures = useMemo(() => towersToFeatures(towers, assetManifest), [towers, assetManifest]);
|
|
49558
51101
|
const handleTileClick = useCallback((x, y) => {
|
|
49559
51102
|
if (result !== "none") return;
|
|
49560
51103
|
if (pathPositions.has(`${x},${y}`)) return;
|
|
@@ -49613,7 +51156,9 @@ function TowerDefenseBoard({
|
|
|
49613
51156
|
{
|
|
49614
51157
|
tiles: isoTiles,
|
|
49615
51158
|
units: isoUnits,
|
|
49616
|
-
features:
|
|
51159
|
+
features: towerFeatures,
|
|
51160
|
+
assetBaseUrl: assetManifest?.baseUrl,
|
|
51161
|
+
assetManifest,
|
|
49617
51162
|
validMoves,
|
|
49618
51163
|
hoveredTile,
|
|
49619
51164
|
onTileClick: handleTileClick,
|
|
@@ -49652,7 +51197,7 @@ function TowerDefenseBoard({
|
|
|
49652
51197
|
] }) })
|
|
49653
51198
|
] });
|
|
49654
51199
|
}
|
|
49655
|
-
var
|
|
51200
|
+
var TD_GRID_W, TD_GRID_H, DEFAULT_TD_PATH, DEFAULT_TD_TILES;
|
|
49656
51201
|
var init_TowerDefenseBoard = __esm({
|
|
49657
51202
|
"components/game/organisms/TowerDefenseBoard.tsx"() {
|
|
49658
51203
|
"use client";
|
|
@@ -49664,16 +51209,8 @@ var init_TowerDefenseBoard = __esm({
|
|
|
49664
51209
|
init_Stack();
|
|
49665
51210
|
init_IsometricCanvas();
|
|
49666
51211
|
init_boardEntity();
|
|
49667
|
-
CDN6 = "https://almadar-kflow-assets.web.app/shared/";
|
|
49668
51212
|
TD_GRID_W = 16;
|
|
49669
51213
|
TD_GRID_H = 16;
|
|
49670
|
-
TERRAIN_SPRITES = {
|
|
49671
|
-
ground: `${CDN6}isometric-blocks/PNG/Platformer tiles/platformerTile_01.png`,
|
|
49672
|
-
path: `${CDN6}isometric-blocks/PNG/Platformer tiles/platformerTile_09.png`,
|
|
49673
|
-
wall: `${CDN6}isometric-blocks/PNG/Platformer tiles/platformerTile_05.png`,
|
|
49674
|
-
grass: `${CDN6}isometric-dungeon/Isometric/dirt_E.png`,
|
|
49675
|
-
dirt: `${CDN6}isometric-dungeon/Isometric/dirtTiles_E.png`
|
|
49676
|
-
};
|
|
49677
51214
|
DEFAULT_TD_PATH = [
|
|
49678
51215
|
{ x: 2, y: 0 },
|
|
49679
51216
|
{ x: 2, y: 1 },
|
|
@@ -49726,9 +51263,6 @@ var init_TowerDefenseBoard = __esm({
|
|
|
49726
51263
|
{ x: 13, y: 15 }
|
|
49727
51264
|
];
|
|
49728
51265
|
DEFAULT_TD_TILES = buildDefaultTDTiles();
|
|
49729
|
-
TOWER_SPRITE = `${CDN6}sprite-sheets/guardian-sprite-sheet-se.png`;
|
|
49730
|
-
CREEP_SPRITE = `${CDN6}sprite-sheets/scrapper-sprite-sheet-se.png`;
|
|
49731
|
-
HERO_SPRITE = `${CDN6}sprite-sheets/amir-sprite-sheet-se.png`;
|
|
49732
51266
|
TowerDefenseBoard.displayName = "TowerDefenseBoard";
|
|
49733
51267
|
}
|
|
49734
51268
|
});
|
|
@@ -49996,6 +51530,214 @@ var init_UncontrolledBattleBoard = __esm({
|
|
|
49996
51530
|
UncontrolledBattleBoard.displayName = "UncontrolledBattleBoard";
|
|
49997
51531
|
}
|
|
49998
51532
|
});
|
|
51533
|
+
function resolveManifestUrl6(manifest, relative) {
|
|
51534
|
+
if (relative == null) return void 0;
|
|
51535
|
+
if (/^https?:\/\//.test(relative)) return relative;
|
|
51536
|
+
const base = manifest?.baseUrl;
|
|
51537
|
+
if (base == null) return relative;
|
|
51538
|
+
const cleanBase = base.replace(/\/$/, "");
|
|
51539
|
+
const cleanRel = relative.replace(/^\//, "");
|
|
51540
|
+
return `${cleanBase}/${cleanRel}`;
|
|
51541
|
+
}
|
|
51542
|
+
function VisualNovelBoard({
|
|
51543
|
+
entity,
|
|
51544
|
+
nodes: propNodes,
|
|
51545
|
+
currentNodeId: propCurrentNodeId,
|
|
51546
|
+
assetManifest: propAssetManifest,
|
|
51547
|
+
typewriterSpeed = 30,
|
|
51548
|
+
portraitScale = 1,
|
|
51549
|
+
chooseEvent,
|
|
51550
|
+
advanceEvent,
|
|
51551
|
+
restartEvent,
|
|
51552
|
+
className
|
|
51553
|
+
}) {
|
|
51554
|
+
const board = boardEntity(entity) ?? {};
|
|
51555
|
+
const eventBus = useEventBus();
|
|
51556
|
+
const assetManifest = propAssetManifest ?? board.assetManifest;
|
|
51557
|
+
const entityNodes = useMemo(
|
|
51558
|
+
() => rows(board.nodes).map((r) => ({
|
|
51559
|
+
id: str(r.id),
|
|
51560
|
+
speaker: str(r.speaker),
|
|
51561
|
+
text: str(r.text),
|
|
51562
|
+
backgroundKey: r.backgroundKey == null ? void 0 : str(r.backgroundKey),
|
|
51563
|
+
portraitKey: r.portraitKey == null ? void 0 : str(r.portraitKey),
|
|
51564
|
+
choices: rows(r.choices).map((c) => ({
|
|
51565
|
+
label: str(c.label),
|
|
51566
|
+
nextId: str(c.nextId)
|
|
51567
|
+
}))
|
|
51568
|
+
})),
|
|
51569
|
+
[board.nodes]
|
|
51570
|
+
);
|
|
51571
|
+
const rawNodes = propNodes ?? entityNodes;
|
|
51572
|
+
const nodes = rawNodes.length > 0 ? rawNodes : DEFAULT_NODES;
|
|
51573
|
+
const currentNodeId = propCurrentNodeId ?? (str(board.currentNodeId) || nodes[0]?.id);
|
|
51574
|
+
const currentNode = nodes.find((n) => n.id === currentNodeId) ?? nodes[0];
|
|
51575
|
+
const backgroundImage = useMemo(
|
|
51576
|
+
() => resolveManifestUrl6(assetManifest, assetManifest?.backgrounds?.[currentNode?.backgroundKey ?? ""]),
|
|
51577
|
+
[assetManifest, currentNode?.backgroundKey]
|
|
51578
|
+
);
|
|
51579
|
+
const portraitUrl = useMemo(
|
|
51580
|
+
() => resolveManifestUrl6(assetManifest, assetManifest?.portraits?.[currentNode?.portraitKey ?? ""]),
|
|
51581
|
+
[assetManifest, currentNode?.portraitKey]
|
|
51582
|
+
);
|
|
51583
|
+
const dialogueChoices = useMemo(
|
|
51584
|
+
() => (currentNode?.choices ?? []).map((c) => ({ text: c.label, next: c.nextId })),
|
|
51585
|
+
[currentNode?.choices]
|
|
51586
|
+
);
|
|
51587
|
+
const handleChoice = useCallback(
|
|
51588
|
+
(choice) => {
|
|
51589
|
+
const index = dialogueChoices.findIndex((c) => c.next === choice.next && c.text === choice.text);
|
|
51590
|
+
if (chooseEvent) {
|
|
51591
|
+
eventBus.emit(`UI:${chooseEvent}`, { choiceIndex: index });
|
|
51592
|
+
}
|
|
51593
|
+
},
|
|
51594
|
+
[dialogueChoices, chooseEvent, eventBus]
|
|
51595
|
+
);
|
|
51596
|
+
const handleAdvance = useCallback(() => {
|
|
51597
|
+
if (advanceEvent) {
|
|
51598
|
+
eventBus.emit(`UI:${advanceEvent}`, {});
|
|
51599
|
+
}
|
|
51600
|
+
}, [advanceEvent, eventBus]);
|
|
51601
|
+
const handleRestart = useCallback(() => {
|
|
51602
|
+
if (restartEvent) {
|
|
51603
|
+
eventBus.emit(`UI:${restartEvent}`, {});
|
|
51604
|
+
}
|
|
51605
|
+
}, [restartEvent, eventBus]);
|
|
51606
|
+
if (!currentNode) {
|
|
51607
|
+
return /* @__PURE__ */ jsxs(VStack, { className: cn("visual-novel-board relative min-h-[600px] bg-background items-center justify-center", className), gap: "lg", children: [
|
|
51608
|
+
/* @__PURE__ */ jsx(Typography, { variant: "h3", color: "muted", children: "No dialogue nodes" }),
|
|
51609
|
+
/* @__PURE__ */ jsx(Button, { variant: "primary", onClick: handleRestart, children: "Restart" })
|
|
51610
|
+
] });
|
|
51611
|
+
}
|
|
51612
|
+
return /* @__PURE__ */ jsx(Box, { className: cn("visual-novel-board relative min-h-[600px] bg-background overflow-hidden", className), children: /* @__PURE__ */ jsx(
|
|
51613
|
+
DialogueBox,
|
|
51614
|
+
{
|
|
51615
|
+
dialogue: {
|
|
51616
|
+
speaker: currentNode.speaker,
|
|
51617
|
+
text: currentNode.text,
|
|
51618
|
+
choices: dialogueChoices
|
|
51619
|
+
},
|
|
51620
|
+
typewriterSpeed,
|
|
51621
|
+
position: "bottom",
|
|
51622
|
+
backgroundImage,
|
|
51623
|
+
portraitUrl,
|
|
51624
|
+
portraitScale,
|
|
51625
|
+
onChoice: handleChoice,
|
|
51626
|
+
onAdvance: handleAdvance
|
|
51627
|
+
}
|
|
51628
|
+
) });
|
|
51629
|
+
}
|
|
51630
|
+
var DEFAULT_NODES;
|
|
51631
|
+
var init_VisualNovelBoard = __esm({
|
|
51632
|
+
"components/game/organisms/VisualNovelBoard.tsx"() {
|
|
51633
|
+
"use client";
|
|
51634
|
+
init_cn();
|
|
51635
|
+
init_useEventBus();
|
|
51636
|
+
init_Box();
|
|
51637
|
+
init_Typography();
|
|
51638
|
+
init_Stack();
|
|
51639
|
+
init_Button();
|
|
51640
|
+
init_DialogueBox();
|
|
51641
|
+
init_boardEntity();
|
|
51642
|
+
DEFAULT_NODES = [
|
|
51643
|
+
{
|
|
51644
|
+
id: "start",
|
|
51645
|
+
speaker: "Narrator",
|
|
51646
|
+
text: "The corridor stretches into shadow. A lone sentinel blocks your path.",
|
|
51647
|
+
backgroundKey: "corridor",
|
|
51648
|
+
portraitKey: "guide",
|
|
51649
|
+
choices: [
|
|
51650
|
+
{ label: "Approach the sentinel.", nextId: "meet" },
|
|
51651
|
+
{ label: "Turn back.", nextId: "retreat" }
|
|
51652
|
+
]
|
|
51653
|
+
},
|
|
51654
|
+
{
|
|
51655
|
+
id: "meet",
|
|
51656
|
+
speaker: "Sentinel",
|
|
51657
|
+
text: "You carry the old marks. Speak your purpose, traveler.",
|
|
51658
|
+
backgroundKey: "forge",
|
|
51659
|
+
portraitKey: "rival",
|
|
51660
|
+
choices: [
|
|
51661
|
+
{ label: "I seek the core.", nextId: "end" },
|
|
51662
|
+
{ label: "I am only passing through.", nextId: "retreat" }
|
|
51663
|
+
]
|
|
51664
|
+
},
|
|
51665
|
+
{
|
|
51666
|
+
id: "retreat",
|
|
51667
|
+
speaker: "Narrator",
|
|
51668
|
+
text: "You withdraw into the dark. The path will wait for braver feet.",
|
|
51669
|
+
backgroundKey: "corridor",
|
|
51670
|
+
choices: [{ label: "Begin again.", nextId: "start" }]
|
|
51671
|
+
},
|
|
51672
|
+
{
|
|
51673
|
+
id: "end",
|
|
51674
|
+
speaker: "Sentinel",
|
|
51675
|
+
text: "Then the way is open. Walk it well.",
|
|
51676
|
+
backgroundKey: "core",
|
|
51677
|
+
portraitKey: "rival",
|
|
51678
|
+
choices: [{ label: "Begin again.", nextId: "start" }]
|
|
51679
|
+
}
|
|
51680
|
+
];
|
|
51681
|
+
VisualNovelBoard.displayName = "VisualNovelBoard";
|
|
51682
|
+
}
|
|
51683
|
+
});
|
|
51684
|
+
function VisualNovelTemplate({
|
|
51685
|
+
entity,
|
|
51686
|
+
title = "Visual Novel",
|
|
51687
|
+
nodes,
|
|
51688
|
+
currentNodeId,
|
|
51689
|
+
typewriterSpeed,
|
|
51690
|
+
portraitScale,
|
|
51691
|
+
chooseEvent,
|
|
51692
|
+
advanceEvent,
|
|
51693
|
+
restartEvent,
|
|
51694
|
+
className
|
|
51695
|
+
}) {
|
|
51696
|
+
const resolved = entity && typeof entity === "object" && !Array.isArray(entity) ? entity : void 0;
|
|
51697
|
+
return /* @__PURE__ */ jsxs(
|
|
51698
|
+
Box,
|
|
51699
|
+
{
|
|
51700
|
+
display: "flex",
|
|
51701
|
+
fullHeight: true,
|
|
51702
|
+
className: cn("visual-novel-template flex-col", className),
|
|
51703
|
+
children: [
|
|
51704
|
+
/* @__PURE__ */ jsx(
|
|
51705
|
+
HStack,
|
|
51706
|
+
{
|
|
51707
|
+
gap: "sm",
|
|
51708
|
+
align: "center",
|
|
51709
|
+
className: "px-4 py-3 border-b-2 border-border bg-surface shrink-0",
|
|
51710
|
+
children: /* @__PURE__ */ jsx(Typography, { variant: "h4", children: title })
|
|
51711
|
+
}
|
|
51712
|
+
),
|
|
51713
|
+
/* @__PURE__ */ jsx(Box, { className: "flex-1 relative overflow-hidden", children: /* @__PURE__ */ jsx(
|
|
51714
|
+
VisualNovelBoard,
|
|
51715
|
+
{
|
|
51716
|
+
entity: resolved,
|
|
51717
|
+
nodes,
|
|
51718
|
+
currentNodeId,
|
|
51719
|
+
typewriterSpeed,
|
|
51720
|
+
portraitScale,
|
|
51721
|
+
chooseEvent,
|
|
51722
|
+
advanceEvent,
|
|
51723
|
+
restartEvent,
|
|
51724
|
+
className: "h-full"
|
|
51725
|
+
}
|
|
51726
|
+
) })
|
|
51727
|
+
]
|
|
51728
|
+
}
|
|
51729
|
+
);
|
|
51730
|
+
}
|
|
51731
|
+
var init_VisualNovelTemplate = __esm({
|
|
51732
|
+
"components/game/templates/VisualNovelTemplate.tsx"() {
|
|
51733
|
+
init_cn();
|
|
51734
|
+
init_Box();
|
|
51735
|
+
init_Stack();
|
|
51736
|
+
init_Typography();
|
|
51737
|
+
init_VisualNovelBoard();
|
|
51738
|
+
VisualNovelTemplate.displayName = "VisualNovelTemplate";
|
|
51739
|
+
}
|
|
51740
|
+
});
|
|
49999
51741
|
function heroPosition(h) {
|
|
50000
51742
|
if ("position" in h && h.position != null) return h.position;
|
|
50001
51743
|
return vec2(h.position);
|
|
@@ -50336,48 +52078,48 @@ function WorldMapTemplate({
|
|
|
50336
52078
|
}
|
|
50337
52079
|
);
|
|
50338
52080
|
}
|
|
50339
|
-
var
|
|
52081
|
+
var CDN5, DEFAULT_WORLDMAP_TILES, DEFAULT_WORLDMAP_UNITS, DEFAULT_WORLDMAP_FEATURES, DEFAULT_WORLDMAP_MANIFEST;
|
|
50340
52082
|
var init_WorldMapTemplate = __esm({
|
|
50341
52083
|
"components/game/templates/WorldMapTemplate.tsx"() {
|
|
50342
52084
|
init_WorldMapBoard();
|
|
50343
|
-
|
|
52085
|
+
CDN5 = "https://almadar-kflow-assets.web.app/shared";
|
|
50344
52086
|
DEFAULT_WORLDMAP_TILES = [
|
|
50345
|
-
{ x: 0, y: 0, terrain: "mountain", passable: false, terrainSprite: `${
|
|
50346
|
-
{ x: 1, y: 0, terrain: "mountain", passable: false, terrainSprite: `${
|
|
50347
|
-
{ x: 2, y: 0, terrain: "water", passable: false, terrainSprite: `${
|
|
50348
|
-
{ x: 3, y: 0, terrain: "mountain", passable: false, terrainSprite: `${
|
|
50349
|
-
{ x: 4, y: 0, terrain: "mountain", passable: false, terrainSprite: `${
|
|
50350
|
-
{ x: 0, y: 1, terrain: "mountain", passable: false, terrainSprite: `${
|
|
50351
|
-
{ x: 1, y: 1, terrain: "grass", passable: true, terrainSprite: `${
|
|
50352
|
-
{ x: 2, y: 1, terrain: "grass", passable: true, terrainSprite: `${
|
|
50353
|
-
{ x: 3, y: 1, terrain: "grass", passable: true, terrainSprite: `${
|
|
50354
|
-
{ x: 4, y: 1, terrain: "water", passable: false, terrainSprite: `${
|
|
50355
|
-
{ x: 0, y: 2, terrain: "water", passable: false, terrainSprite: `${
|
|
50356
|
-
{ x: 1, y: 2, terrain: "grass", passable: true, terrainSprite: `${
|
|
50357
|
-
{ x: 2, y: 2, terrain: "grass", passable: true, terrainSprite: `${
|
|
50358
|
-
{ x: 3, y: 2, terrain: "grass", passable: true, terrainSprite: `${
|
|
50359
|
-
{ x: 4, y: 2, terrain: "mountain", passable: false, terrainSprite: `${
|
|
50360
|
-
{ x: 0, y: 3, terrain: "mountain", passable: false, terrainSprite: `${
|
|
50361
|
-
{ x: 1, y: 3, terrain: "grass", passable: true, terrainSprite: `${
|
|
50362
|
-
{ x: 2, y: 3, terrain: "grass", passable: true, terrainSprite: `${
|
|
50363
|
-
{ x: 3, y: 3, terrain: "grass", passable: true, terrainSprite: `${
|
|
50364
|
-
{ x: 4, y: 3, terrain: "mountain", passable: false, terrainSprite: `${
|
|
50365
|
-
{ x: 0, y: 4, terrain: "mountain", passable: false, terrainSprite: `${
|
|
50366
|
-
{ x: 1, y: 4, terrain: "water", passable: false, terrainSprite: `${
|
|
50367
|
-
{ x: 2, y: 4, terrain: "grass", passable: true, terrainSprite: `${
|
|
50368
|
-
{ x: 3, y: 4, terrain: "mountain", passable: false, terrainSprite: `${
|
|
50369
|
-
{ x: 4, y: 4, terrain: "mountain", passable: false, terrainSprite: `${
|
|
52087
|
+
{ x: 0, y: 0, terrain: "mountain", passable: false, terrainSprite: `${CDN5}/isometric-blocks/PNG/Platformer tiles/platformerTile_13.png` },
|
|
52088
|
+
{ x: 1, y: 0, terrain: "mountain", passable: false, terrainSprite: `${CDN5}/isometric-blocks/PNG/Platformer tiles/platformerTile_13.png` },
|
|
52089
|
+
{ x: 2, y: 0, terrain: "water", passable: false, terrainSprite: `${CDN5}/isometric-blocks/PNG/Platformer tiles/platformerTile_11.png` },
|
|
52090
|
+
{ x: 3, y: 0, terrain: "mountain", passable: false, terrainSprite: `${CDN5}/isometric-blocks/PNG/Platformer tiles/platformerTile_13.png` },
|
|
52091
|
+
{ x: 4, y: 0, terrain: "mountain", passable: false, terrainSprite: `${CDN5}/isometric-blocks/PNG/Platformer tiles/platformerTile_13.png` },
|
|
52092
|
+
{ x: 0, y: 1, terrain: "mountain", passable: false, terrainSprite: `${CDN5}/isometric-blocks/PNG/Platformer tiles/platformerTile_13.png` },
|
|
52093
|
+
{ x: 1, y: 1, terrain: "grass", passable: true, terrainSprite: `${CDN5}/isometric-blocks/PNG/Platformer tiles/platformerTile_01.png` },
|
|
52094
|
+
{ x: 2, y: 1, terrain: "grass", passable: true, terrainSprite: `${CDN5}/isometric-blocks/PNG/Platformer tiles/platformerTile_01.png` },
|
|
52095
|
+
{ x: 3, y: 1, terrain: "grass", passable: true, terrainSprite: `${CDN5}/isometric-blocks/PNG/Platformer tiles/platformerTile_01.png` },
|
|
52096
|
+
{ x: 4, y: 1, terrain: "water", passable: false, terrainSprite: `${CDN5}/isometric-blocks/PNG/Platformer tiles/platformerTile_11.png` },
|
|
52097
|
+
{ x: 0, y: 2, terrain: "water", passable: false, terrainSprite: `${CDN5}/isometric-blocks/PNG/Platformer tiles/platformerTile_11.png` },
|
|
52098
|
+
{ x: 1, y: 2, terrain: "grass", passable: true, terrainSprite: `${CDN5}/isometric-blocks/PNG/Platformer tiles/platformerTile_01.png` },
|
|
52099
|
+
{ x: 2, y: 2, terrain: "grass", passable: true, terrainSprite: `${CDN5}/isometric-blocks/PNG/Platformer tiles/platformerTile_03.png` },
|
|
52100
|
+
{ x: 3, y: 2, terrain: "grass", passable: true, terrainSprite: `${CDN5}/isometric-blocks/PNG/Platformer tiles/platformerTile_01.png` },
|
|
52101
|
+
{ x: 4, y: 2, terrain: "mountain", passable: false, terrainSprite: `${CDN5}/isometric-blocks/PNG/Platformer tiles/platformerTile_13.png` },
|
|
52102
|
+
{ x: 0, y: 3, terrain: "mountain", passable: false, terrainSprite: `${CDN5}/isometric-blocks/PNG/Platformer tiles/platformerTile_13.png` },
|
|
52103
|
+
{ x: 1, y: 3, terrain: "grass", passable: true, terrainSprite: `${CDN5}/isometric-blocks/PNG/Platformer tiles/platformerTile_01.png` },
|
|
52104
|
+
{ x: 2, y: 3, terrain: "grass", passable: true, terrainSprite: `${CDN5}/isometric-blocks/PNG/Platformer tiles/platformerTile_01.png` },
|
|
52105
|
+
{ x: 3, y: 3, terrain: "grass", passable: true, terrainSprite: `${CDN5}/isometric-blocks/PNG/Platformer tiles/platformerTile_03.png` },
|
|
52106
|
+
{ x: 4, y: 3, terrain: "mountain", passable: false, terrainSprite: `${CDN5}/isometric-blocks/PNG/Platformer tiles/platformerTile_13.png` },
|
|
52107
|
+
{ x: 0, y: 4, terrain: "mountain", passable: false, terrainSprite: `${CDN5}/isometric-blocks/PNG/Platformer tiles/platformerTile_13.png` },
|
|
52108
|
+
{ x: 1, y: 4, terrain: "water", passable: false, terrainSprite: `${CDN5}/isometric-blocks/PNG/Platformer tiles/platformerTile_11.png` },
|
|
52109
|
+
{ x: 2, y: 4, terrain: "grass", passable: true, terrainSprite: `${CDN5}/isometric-blocks/PNG/Platformer tiles/platformerTile_01.png` },
|
|
52110
|
+
{ x: 3, y: 4, terrain: "mountain", passable: false, terrainSprite: `${CDN5}/isometric-blocks/PNG/Platformer tiles/platformerTile_13.png` },
|
|
52111
|
+
{ x: 4, y: 4, terrain: "mountain", passable: false, terrainSprite: `${CDN5}/isometric-blocks/PNG/Platformer tiles/platformerTile_13.png` }
|
|
50370
52112
|
];
|
|
50371
52113
|
DEFAULT_WORLDMAP_UNITS = [
|
|
50372
|
-
{ id: "h1", position: { x: 1, y: 1 }, unitType: "hero", name: "Amir", team: "player", health: 10, maxHealth: 10, sprite: `${
|
|
50373
|
-
{ id: "h2", position: { x: 3, y: 3 }, unitType: "scout", name: "Archivist", team: "player", health: 10, maxHealth: 10, sprite: `${
|
|
52114
|
+
{ id: "h1", position: { x: 1, y: 1 }, unitType: "hero", name: "Amir", team: "player", health: 10, maxHealth: 10, sprite: `${CDN5}/sprite-sheets/amir-sprite-sheet-se.png` },
|
|
52115
|
+
{ id: "h2", position: { x: 3, y: 3 }, unitType: "scout", name: "Archivist", team: "player", health: 10, maxHealth: 10, sprite: `${CDN5}/sprite-sheets/archivist-sprite-sheet-se.png` }
|
|
50374
52116
|
];
|
|
50375
52117
|
DEFAULT_WORLDMAP_FEATURES = [
|
|
50376
|
-
{ id: "f1", x: 2, y: 2, type: "capital", sprite: `${
|
|
50377
|
-
{ id: "f2", x: 4, y: 2, type: "power_node", sprite: `${
|
|
52118
|
+
{ id: "f1", x: 2, y: 2, type: "capital", sprite: `${CDN5}/scenes/world/capital.png` },
|
|
52119
|
+
{ id: "f2", x: 4, y: 2, type: "power_node", sprite: `${CDN5}/world-map/power_node.png` }
|
|
50378
52120
|
];
|
|
50379
52121
|
DEFAULT_WORLDMAP_MANIFEST = {
|
|
50380
|
-
baseUrl:
|
|
52122
|
+
baseUrl: CDN5,
|
|
50381
52123
|
terrains: {
|
|
50382
52124
|
grass: "/isometric-blocks/PNG/Platformer tiles/platformerTile_01.png",
|
|
50383
52125
|
water: "/isometric-blocks/PNG/Platformer tiles/platformerTile_11.png",
|
|
@@ -50397,7 +52139,7 @@ var init_WorldMapTemplate = __esm({
|
|
|
50397
52139
|
}
|
|
50398
52140
|
});
|
|
50399
52141
|
function lazyThree(name, loader) {
|
|
50400
|
-
const Lazy =
|
|
52142
|
+
const Lazy = React85__default.lazy(
|
|
50401
52143
|
() => loader().then((m) => {
|
|
50402
52144
|
const Resolved = m[name];
|
|
50403
52145
|
if (!Resolved) {
|
|
@@ -50409,13 +52151,13 @@ function lazyThree(name, loader) {
|
|
|
50409
52151
|
})
|
|
50410
52152
|
);
|
|
50411
52153
|
function ThreeWrapper(props) {
|
|
50412
|
-
return
|
|
52154
|
+
return React85__default.createElement(
|
|
50413
52155
|
ThreeBoundary,
|
|
50414
52156
|
{ name },
|
|
50415
|
-
|
|
50416
|
-
|
|
52157
|
+
React85__default.createElement(
|
|
52158
|
+
React85__default.Suspense,
|
|
50417
52159
|
{ fallback: null },
|
|
50418
|
-
|
|
52160
|
+
React85__default.createElement(Lazy, props)
|
|
50419
52161
|
)
|
|
50420
52162
|
);
|
|
50421
52163
|
}
|
|
@@ -50459,7 +52201,10 @@ var init_component_registry_generated = __esm({
|
|
|
50459
52201
|
init_CalendarGrid();
|
|
50460
52202
|
init_CanvasEffect();
|
|
50461
52203
|
init_Card();
|
|
52204
|
+
init_CardBattlerBoard();
|
|
52205
|
+
init_CardBattlerTemplate();
|
|
50462
52206
|
init_CardGrid();
|
|
52207
|
+
init_CardHand();
|
|
50463
52208
|
init_Carousel();
|
|
50464
52209
|
init_CaseStudyCard();
|
|
50465
52210
|
init_CaseStudyOrganism();
|
|
@@ -50470,6 +52215,8 @@ var init_component_registry_generated = __esm({
|
|
|
50470
52215
|
init_ChartLegend();
|
|
50471
52216
|
init_Checkbox();
|
|
50472
52217
|
init_ChoiceButton();
|
|
52218
|
+
init_CityBuilderBoard();
|
|
52219
|
+
init_CityBuilderTemplate();
|
|
50473
52220
|
init_ClassifierBoard();
|
|
50474
52221
|
init_CodeBlock();
|
|
50475
52222
|
init_CodeRunnerPanel();
|
|
@@ -50690,6 +52437,8 @@ var init_component_registry_generated = __esm({
|
|
|
50690
52437
|
init_Toast();
|
|
50691
52438
|
init_ToastSlot();
|
|
50692
52439
|
init_Tooltip();
|
|
52440
|
+
init_TopDownShooterBoard();
|
|
52441
|
+
init_TopDownShooterTemplate();
|
|
50693
52442
|
init_TowerDefenseBoard();
|
|
50694
52443
|
init_TowerDefenseTemplate();
|
|
50695
52444
|
init_TraitFrame();
|
|
@@ -50705,6 +52454,8 @@ var init_component_registry_generated = __esm({
|
|
|
50705
52454
|
init_UploadDropZone();
|
|
50706
52455
|
init_VersionDiff();
|
|
50707
52456
|
init_ViolationAlert();
|
|
52457
|
+
init_VisualNovelBoard();
|
|
52458
|
+
init_VisualNovelTemplate();
|
|
50708
52459
|
init_VoteStack();
|
|
50709
52460
|
init_WaypointMarker();
|
|
50710
52461
|
init_WizardContainer();
|
|
@@ -50713,7 +52464,7 @@ var init_component_registry_generated = __esm({
|
|
|
50713
52464
|
init_WorldMapBoard();
|
|
50714
52465
|
init_WorldMapTemplate();
|
|
50715
52466
|
init_XPBar();
|
|
50716
|
-
ThreeBoundary = class extends
|
|
52467
|
+
ThreeBoundary = class extends React85__default.Component {
|
|
50717
52468
|
constructor() {
|
|
50718
52469
|
super(...arguments);
|
|
50719
52470
|
__publicField(this, "state", { failed: false });
|
|
@@ -50723,7 +52474,7 @@ var init_component_registry_generated = __esm({
|
|
|
50723
52474
|
}
|
|
50724
52475
|
render() {
|
|
50725
52476
|
if (this.state.failed) {
|
|
50726
|
-
return
|
|
52477
|
+
return React85__default.createElement(
|
|
50727
52478
|
"div",
|
|
50728
52479
|
{
|
|
50729
52480
|
"data-testid": "three-unavailable",
|
|
@@ -50779,7 +52530,10 @@ var init_component_registry_generated = __esm({
|
|
|
50779
52530
|
"CalendarGrid": CalendarGrid,
|
|
50780
52531
|
"CanvasEffect": CanvasEffect,
|
|
50781
52532
|
"Card": Card,
|
|
52533
|
+
"CardBattlerBoard": CardBattlerBoard,
|
|
52534
|
+
"CardBattlerTemplate": CardBattlerTemplate,
|
|
50782
52535
|
"CardGrid": CardGrid,
|
|
52536
|
+
"CardHand": CardHand,
|
|
50783
52537
|
"Carousel": Carousel,
|
|
50784
52538
|
"CaseStudyCard": CaseStudyCard,
|
|
50785
52539
|
"CaseStudyOrganism": CaseStudyOrganism,
|
|
@@ -50790,6 +52544,8 @@ var init_component_registry_generated = __esm({
|
|
|
50790
52544
|
"ChartLegend": ChartLegend,
|
|
50791
52545
|
"Checkbox": Checkbox,
|
|
50792
52546
|
"ChoiceButton": ChoiceButton,
|
|
52547
|
+
"CityBuilderBoard": CityBuilderBoard,
|
|
52548
|
+
"CityBuilderTemplate": CityBuilderTemplate,
|
|
50793
52549
|
"ClassifierBoard": ClassifierBoard,
|
|
50794
52550
|
"CodeBlock": CodeBlock,
|
|
50795
52551
|
"CodeRunnerPanel": CodeRunnerPanel,
|
|
@@ -51022,6 +52778,8 @@ var init_component_registry_generated = __esm({
|
|
|
51022
52778
|
"Toast": Toast,
|
|
51023
52779
|
"ToastSlot": ToastSlot,
|
|
51024
52780
|
"Tooltip": Tooltip,
|
|
52781
|
+
"TopDownShooterBoard": TopDownShooterBoard,
|
|
52782
|
+
"TopDownShooterTemplate": TopDownShooterTemplate,
|
|
51025
52783
|
"TowerDefenseBoard": TowerDefenseBoard,
|
|
51026
52784
|
"TowerDefenseTemplate": TowerDefenseTemplate,
|
|
51027
52785
|
"TraitFrame": TraitFrame,
|
|
@@ -51038,6 +52796,8 @@ var init_component_registry_generated = __esm({
|
|
|
51038
52796
|
"VStack": VStack,
|
|
51039
52797
|
"VersionDiff": VersionDiff,
|
|
51040
52798
|
"ViolationAlert": ViolationAlert,
|
|
52799
|
+
"VisualNovelBoard": VisualNovelBoard,
|
|
52800
|
+
"VisualNovelTemplate": VisualNovelTemplate,
|
|
51041
52801
|
"VoteStack": VoteStack,
|
|
51042
52802
|
"WaypointMarker": WaypointMarker,
|
|
51043
52803
|
"WizardContainer": WizardContainer,
|
|
@@ -51064,7 +52824,7 @@ function SuspenseConfigProvider({
|
|
|
51064
52824
|
config,
|
|
51065
52825
|
children
|
|
51066
52826
|
}) {
|
|
51067
|
-
return
|
|
52827
|
+
return React85__default.createElement(
|
|
51068
52828
|
SuspenseConfigContext.Provider,
|
|
51069
52829
|
{ value: config },
|
|
51070
52830
|
children
|
|
@@ -51554,7 +53314,7 @@ function renderPatternChildren(children, onDismiss, parentId = "root", parentPat
|
|
|
51554
53314
|
const key = `${parentId}-${index}-trait:${traitName}`;
|
|
51555
53315
|
return /* @__PURE__ */ jsx(TraitFrame, { traitName }, key);
|
|
51556
53316
|
}
|
|
51557
|
-
return /* @__PURE__ */ jsx(
|
|
53317
|
+
return /* @__PURE__ */ jsx(React85__default.Fragment, { children: child }, `${parentId}-${index}`);
|
|
51558
53318
|
}
|
|
51559
53319
|
if (!child || typeof child !== "object") return null;
|
|
51560
53320
|
const childId = `${parentId}-${index}`;
|
|
@@ -51594,14 +53354,14 @@ function isPatternConfig(value) {
|
|
|
51594
53354
|
if (value === null || value === void 0) return false;
|
|
51595
53355
|
if (typeof value !== "object") return false;
|
|
51596
53356
|
if (Array.isArray(value)) return false;
|
|
51597
|
-
if (
|
|
53357
|
+
if (React85__default.isValidElement(value)) return false;
|
|
51598
53358
|
if (value instanceof Date) return false;
|
|
51599
53359
|
if (typeof value === "function") return false;
|
|
51600
53360
|
const record = value;
|
|
51601
53361
|
return "type" in record && typeof record.type === "string" && getComponentForPattern$1(record.type) !== null;
|
|
51602
53362
|
}
|
|
51603
53363
|
function isPlainConfigObject(value) {
|
|
51604
|
-
if (
|
|
53364
|
+
if (React85__default.isValidElement(value)) return false;
|
|
51605
53365
|
if (value instanceof Date) return false;
|
|
51606
53366
|
const proto = Object.getPrototypeOf(value);
|
|
51607
53367
|
return proto === Object.prototype || proto === null;
|
|
@@ -51722,6 +53482,22 @@ function SlotContentRenderer({
|
|
|
51722
53482
|
const childrenIsRenderFn = typeof incomingChildren === "function";
|
|
51723
53483
|
const { children: _childrenConfig, ...restPropsNoChildren } = content.props;
|
|
51724
53484
|
const restProps = childrenIsRenderFn ? { ...restPropsNoChildren, children: incomingChildren } : restPropsNoChildren;
|
|
53485
|
+
const nodeSlotOverrides = {};
|
|
53486
|
+
for (const slotKey of CONTENT_NODE_SLOTS) {
|
|
53487
|
+
const slotVal = restProps[slotKey];
|
|
53488
|
+
if (slotVal === void 0 || slotVal === null) continue;
|
|
53489
|
+
if (React85__default.isValidElement(slotVal) || typeof slotVal === "string" || typeof slotVal === "number" || typeof slotVal === "boolean") continue;
|
|
53490
|
+
if (Array.isArray(slotVal) || typeof slotVal === "object" && "type" in slotVal) {
|
|
53491
|
+
nodeSlotOverrides[slotKey] = renderPatternChildren(
|
|
53492
|
+
slotVal,
|
|
53493
|
+
onDismiss,
|
|
53494
|
+
`${content.id}-${slotKey}`,
|
|
53495
|
+
`${myPath}.${slotKey}`,
|
|
53496
|
+
content.sourceTrait,
|
|
53497
|
+
{ slot: content.slot, transitionEvent: content.transitionEvent, fromState: content.fromState, entity: content.entity }
|
|
53498
|
+
);
|
|
53499
|
+
}
|
|
53500
|
+
}
|
|
51725
53501
|
const renderedProps = renderPatternProps(restProps, onDismiss);
|
|
51726
53502
|
const patternDef = getPatternDefinition(content.pattern);
|
|
51727
53503
|
const propsSchema = patternDef?.propsSchema;
|
|
@@ -51752,6 +53528,9 @@ function SlotContentRenderer({
|
|
|
51752
53528
|
}
|
|
51753
53529
|
}
|
|
51754
53530
|
const finalProps = renderedProps;
|
|
53531
|
+
for (const [k, v] of Object.entries(nodeSlotOverrides)) {
|
|
53532
|
+
finalProps[k] = v;
|
|
53533
|
+
}
|
|
51755
53534
|
const resolvedItems = Array.isArray(
|
|
51756
53535
|
finalProps.entity
|
|
51757
53536
|
) ? finalProps.entity : null;
|
|
@@ -51872,7 +53651,7 @@ function UISlotRenderer({
|
|
|
51872
53651
|
}
|
|
51873
53652
|
return wrapped;
|
|
51874
53653
|
}
|
|
51875
|
-
var scopeWrapLog, TRAIT_BINDING_RE, SuspenseConfigContext, SlotContainedContext, SLOT_SKELETON_MAP, FORM_PATTERNS, SELF_OVERLAY_PATTERNS, PATTERNS_WITH_CHILDREN;
|
|
53654
|
+
var scopeWrapLog, TRAIT_BINDING_RE, SuspenseConfigContext, SlotContainedContext, SLOT_SKELETON_MAP, FORM_PATTERNS, SELF_OVERLAY_PATTERNS, CONTENT_NODE_SLOTS, PATTERNS_WITH_CHILDREN;
|
|
51876
53655
|
var init_UISlotRenderer = __esm({
|
|
51877
53656
|
"components/core/organisms/UISlotRenderer.tsx"() {
|
|
51878
53657
|
"use client";
|
|
@@ -51909,6 +53688,16 @@ var init_UISlotRenderer = __esm({
|
|
|
51909
53688
|
"wizard-step"
|
|
51910
53689
|
]);
|
|
51911
53690
|
SELF_OVERLAY_PATTERNS = /* @__PURE__ */ new Set(["modal", "confirm-dialog"]);
|
|
53691
|
+
CONTENT_NODE_SLOTS = /* @__PURE__ */ new Set([
|
|
53692
|
+
"logo",
|
|
53693
|
+
"master",
|
|
53694
|
+
"detail",
|
|
53695
|
+
"trigger",
|
|
53696
|
+
"content",
|
|
53697
|
+
"addons",
|
|
53698
|
+
"hud",
|
|
53699
|
+
"fallback"
|
|
53700
|
+
]);
|
|
51912
53701
|
PATTERNS_WITH_CHILDREN = /* @__PURE__ */ new Set([
|
|
51913
53702
|
"stack",
|
|
51914
53703
|
"vstack",
|