@almadar/ui 5.134.0 → 5.136.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{TraitProvider-Ch79cUcb.d.cts → EntityBindingContext-CD9ZoXb4.d.cts} +30 -2
- package/dist/{TraitProvider-Ch79cUcb.d.ts → EntityBindingContext-CD9ZoXb4.d.ts} +30 -2
- package/dist/avl/index.cjs +819 -429
- package/dist/avl/index.js +820 -430
- package/dist/{cn-Dm0VrLRG.d.ts → cn-CCaph5o9.d.ts} +1 -1
- package/dist/{cn-D3H9UzCW.d.cts → cn-CL0kdshO.d.cts} +1 -1
- package/dist/components/index.cjs +1649 -1482
- package/dist/components/index.d.cts +105 -202
- package/dist/components/index.d.ts +105 -202
- package/dist/components/index.js +705 -533
- package/dist/lib/drawable/three/index.cjs +16 -0
- package/dist/lib/drawable/three/index.d.cts +1 -1
- package/dist/lib/drawable/three/index.d.ts +1 -1
- package/dist/lib/drawable/three/index.js +16 -0
- package/dist/lib/index.cjs +28 -0
- package/dist/lib/index.d.cts +21 -3
- package/dist/lib/index.d.ts +21 -3
- package/dist/lib/index.js +27 -1
- package/dist/marketing/index.cjs +1 -0
- package/dist/marketing/index.js +1 -0
- package/dist/{paintDispatch-BXJgISot.d.cts → paintDispatch-DXygiK7M.d.cts} +39 -10
- package/dist/{paintDispatch-BXJgISot.d.ts → paintDispatch-DXygiK7M.d.ts} +39 -10
- package/dist/providers/index.cjs +701 -323
- package/dist/providers/index.d.cts +3 -3
- package/dist/providers/index.d.ts +3 -3
- package/dist/providers/index.js +698 -322
- package/dist/runtime/index.cjs +819 -429
- package/dist/runtime/index.d.cts +5 -2
- package/dist/runtime/index.d.ts +5 -2
- package/dist/runtime/index.js +820 -430
- package/package.json +6 -5
package/dist/runtime/index.cjs
CHANGED
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
var React83 = require('react');
|
|
4
4
|
var providers = require('@almadar/ui/providers');
|
|
5
5
|
var logger = require('@almadar/logger');
|
|
6
|
+
var runtime = require('@almadar/runtime');
|
|
7
|
+
var core = require('@almadar/core');
|
|
6
8
|
var clsx = require('clsx');
|
|
7
9
|
var tailwindMerge = require('tailwind-merge');
|
|
8
10
|
var LucideIcons2 = require('lucide-react');
|
|
@@ -67,14 +69,13 @@ var ReactMarkdown = require('react-markdown');
|
|
|
67
69
|
var remarkGfm = require('remark-gfm');
|
|
68
70
|
var remarkMath = require('remark-math');
|
|
69
71
|
var rehypeKatex = require('rehype-katex');
|
|
70
|
-
var core = require('@almadar/core');
|
|
71
72
|
var core$1 = require('@dnd-kit/core');
|
|
72
73
|
var sortable = require('@dnd-kit/sortable');
|
|
73
74
|
var utilities = require('@dnd-kit/utilities');
|
|
75
|
+
var emojilib = require('emojilib');
|
|
74
76
|
var react = require('@xyflow/react');
|
|
75
77
|
var d3Force = require('d3-force');
|
|
76
78
|
var patterns = require('@almadar/core/patterns');
|
|
77
|
-
var runtime = require('@almadar/runtime');
|
|
78
79
|
var registry = require('@almadar/std/registry');
|
|
79
80
|
var OrbitalServerRuntime = require('@almadar/runtime/OrbitalServerRuntime');
|
|
80
81
|
|
|
@@ -886,6 +887,75 @@ var init_useTapReveal = __esm({
|
|
|
886
887
|
"hooks/useTapReveal.ts"() {
|
|
887
888
|
}
|
|
888
889
|
});
|
|
890
|
+
function resolveMarkerExpression(expression, entity, config, state) {
|
|
891
|
+
const ctx = runtime.createContextFromBindings({
|
|
892
|
+
entity,
|
|
893
|
+
payload: {},
|
|
894
|
+
state,
|
|
895
|
+
...config !== void 0 ? { config } : {}
|
|
896
|
+
});
|
|
897
|
+
return runtime.interpolateValue(expression, ctx);
|
|
898
|
+
}
|
|
899
|
+
function isPlainObject(value) {
|
|
900
|
+
if (value === null || value === void 0 || typeof value !== "object") return false;
|
|
901
|
+
if (Array.isArray(value)) return false;
|
|
902
|
+
if (React83__namespace.default.isValidElement(value)) return false;
|
|
903
|
+
if (value instanceof Date) return false;
|
|
904
|
+
if (typeof value === "function") return false;
|
|
905
|
+
return true;
|
|
906
|
+
}
|
|
907
|
+
function walkValue(value, scopeTrait, entity, config, state) {
|
|
908
|
+
if (core.isRenderBindingMarker(value)) {
|
|
909
|
+
return { resolved: resolveMarkerExpression(value.expression, entity, config, state), changed: true };
|
|
910
|
+
}
|
|
911
|
+
if (Array.isArray(value)) {
|
|
912
|
+
const out = [];
|
|
913
|
+
let changed = false;
|
|
914
|
+
for (const item of value) {
|
|
915
|
+
const element = item;
|
|
916
|
+
const wasMarker = core.isRenderBindingMarker(element);
|
|
917
|
+
const { resolved, changed: itemChanged } = walkValue(element, scopeTrait, entity, config, state);
|
|
918
|
+
if (wasMarker && Array.isArray(resolved)) {
|
|
919
|
+
out.push(...resolved);
|
|
920
|
+
changed = true;
|
|
921
|
+
continue;
|
|
922
|
+
}
|
|
923
|
+
out.push(resolved);
|
|
924
|
+
if (itemChanged) changed = true;
|
|
925
|
+
}
|
|
926
|
+
return changed ? { resolved: out, changed: true } : { resolved: value, changed: false };
|
|
927
|
+
}
|
|
928
|
+
if (isPlainObject(value)) {
|
|
929
|
+
const sourceTrait = value._sourceTrait;
|
|
930
|
+
if (typeof sourceTrait === "string" && sourceTrait !== scopeTrait) {
|
|
931
|
+
return { resolved: value, changed: false };
|
|
932
|
+
}
|
|
933
|
+
const out = {};
|
|
934
|
+
let changed = false;
|
|
935
|
+
for (const [key, item] of Object.entries(value)) {
|
|
936
|
+
const { resolved, changed: itemChanged } = walkValue(item, scopeTrait, entity, config, state);
|
|
937
|
+
out[key] = resolved;
|
|
938
|
+
if (itemChanged) changed = true;
|
|
939
|
+
}
|
|
940
|
+
return changed ? { resolved: out, changed: true } : { resolved: value, changed: false };
|
|
941
|
+
}
|
|
942
|
+
return { resolved: value, changed: false };
|
|
943
|
+
}
|
|
944
|
+
function resolveRenderBindingMarkers(props, scopeTrait, entity, config, state) {
|
|
945
|
+
const out = {};
|
|
946
|
+
let changed = false;
|
|
947
|
+
for (const [key, value] of Object.entries(props)) {
|
|
948
|
+
const { resolved, changed: propChanged } = walkValue(value, scopeTrait, entity, config, state);
|
|
949
|
+
out[key] = resolved;
|
|
950
|
+
if (propChanged) changed = true;
|
|
951
|
+
}
|
|
952
|
+
return changed ? out : props;
|
|
953
|
+
}
|
|
954
|
+
var init_resolve_render_bindings = __esm({
|
|
955
|
+
"lib/resolve-render-bindings.ts"() {
|
|
956
|
+
"use client";
|
|
957
|
+
}
|
|
958
|
+
});
|
|
889
959
|
function cn(...inputs) {
|
|
890
960
|
return tailwindMerge.twMerge(clsx.clsx(inputs));
|
|
891
961
|
}
|
|
@@ -1346,9 +1416,13 @@ function getAtlas(url, onReady) {
|
|
|
1346
1416
|
onReady();
|
|
1347
1417
|
}).catch(() => {
|
|
1348
1418
|
atlasCache.set(url, null);
|
|
1419
|
+
onReady();
|
|
1349
1420
|
});
|
|
1350
1421
|
return void 0;
|
|
1351
1422
|
}
|
|
1423
|
+
function atlasFailed(url) {
|
|
1424
|
+
return atlasCache.get(url) === null;
|
|
1425
|
+
}
|
|
1352
1426
|
function subRectFor(atlas, sprite) {
|
|
1353
1427
|
if (isTilesheet(atlas)) {
|
|
1354
1428
|
let col;
|
|
@@ -1769,6 +1843,32 @@ function formatValue(value, format) {
|
|
|
1769
1843
|
return String(value);
|
|
1770
1844
|
}
|
|
1771
1845
|
}
|
|
1846
|
+
function compareCellValues(a, b) {
|
|
1847
|
+
const aEmpty = a === null || a === void 0 || a === "";
|
|
1848
|
+
const bEmpty = b === null || b === void 0 || b === "";
|
|
1849
|
+
if (aEmpty || bEmpty) return aEmpty && bEmpty ? 0 : aEmpty ? 1 : -1;
|
|
1850
|
+
if (typeof a === "number" && typeof b === "number") return a - b;
|
|
1851
|
+
if (typeof a === "boolean" && typeof b === "boolean") return Number(a) - Number(b);
|
|
1852
|
+
const aNum = Number(a);
|
|
1853
|
+
const bNum = Number(b);
|
|
1854
|
+
if (Number.isFinite(aNum) && Number.isFinite(bNum)) return aNum - bNum;
|
|
1855
|
+
const aTime = dateLikeTime(a);
|
|
1856
|
+
const bTime = dateLikeTime(b);
|
|
1857
|
+
if (aTime !== null && bTime !== null) return aTime - bTime;
|
|
1858
|
+
return String(a).localeCompare(String(b));
|
|
1859
|
+
}
|
|
1860
|
+
function dateLikeTime(value) {
|
|
1861
|
+
if (value instanceof Date) return value.getTime();
|
|
1862
|
+
const text = String(value);
|
|
1863
|
+
if (!/\d/.test(text) || !/[-/:T]/.test(text)) return null;
|
|
1864
|
+
const time = Date.parse(text);
|
|
1865
|
+
return Number.isNaN(time) ? null : time;
|
|
1866
|
+
}
|
|
1867
|
+
function sortRows(rows, field, direction = "asc") {
|
|
1868
|
+
if (!field) return rows;
|
|
1869
|
+
const dir = direction === "desc" ? -1 : 1;
|
|
1870
|
+
return [...rows].sort((a, b) => dir * compareCellValues(a?.[field], b?.[field]));
|
|
1871
|
+
}
|
|
1772
1872
|
var init_format = __esm({
|
|
1773
1873
|
"lib/format.ts"() {
|
|
1774
1874
|
}
|
|
@@ -3591,6 +3691,20 @@ var init_Input = __esm({
|
|
|
3591
3691
|
const { t } = hooks.useTranslate();
|
|
3592
3692
|
const eventBus = useEventBus();
|
|
3593
3693
|
const type = inputType || htmlType || "text";
|
|
3694
|
+
const isDeclarative = typeof onChange === "string";
|
|
3695
|
+
const [localValue, setLocalValue] = React83__namespace.default.useState(value);
|
|
3696
|
+
const pendingEchoRef = React83__namespace.default.useRef(/* @__PURE__ */ new Set());
|
|
3697
|
+
React83__namespace.default.useEffect(() => {
|
|
3698
|
+
if (!isDeclarative) return;
|
|
3699
|
+
const incoming = value == null ? "" : String(value);
|
|
3700
|
+
if (pendingEchoRef.current.has(incoming)) {
|
|
3701
|
+
pendingEchoRef.current.delete(incoming);
|
|
3702
|
+
return;
|
|
3703
|
+
}
|
|
3704
|
+
pendingEchoRef.current.clear();
|
|
3705
|
+
setLocalValue(value);
|
|
3706
|
+
}, [value, isDeclarative]);
|
|
3707
|
+
const displayValue = isDeclarative ? localValue : value;
|
|
3594
3708
|
const resolveIconNode = (i, cls) => {
|
|
3595
3709
|
if (!i) return null;
|
|
3596
3710
|
if (typeof i === "string") return /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: i, className: cls });
|
|
@@ -3600,7 +3714,7 @@ var init_Input = __esm({
|
|
|
3600
3714
|
const iconCls = "h-icon-default w-icon-default";
|
|
3601
3715
|
const IconComponent = typeof iconProp === "string" ? resolveIcon(iconProp) : iconProp;
|
|
3602
3716
|
const resolvedLeftIcon = (leftIcon ? resolveIconNode(leftIcon, iconCls) : null) || IconComponent && /* @__PURE__ */ jsxRuntime.jsx(IconComponent, { className: iconCls });
|
|
3603
|
-
const showClearButton = clearable &&
|
|
3717
|
+
const showClearButton = clearable && displayValue && String(displayValue).length > 0;
|
|
3604
3718
|
const isMultiline = type === "textarea";
|
|
3605
3719
|
const baseClassName = cn(
|
|
3606
3720
|
"block w-full rounded-sm transition-all duration-fast",
|
|
@@ -3619,6 +3733,10 @@ var init_Input = __esm({
|
|
|
3619
3733
|
if (typeof onChange === "string") {
|
|
3620
3734
|
const target = e.target;
|
|
3621
3735
|
const payload = type === "checkbox" ? { checked: target.checked } : { value: target.value };
|
|
3736
|
+
if (type !== "checkbox") {
|
|
3737
|
+
pendingEchoRef.current.add(target.value);
|
|
3738
|
+
setLocalValue(target.value);
|
|
3739
|
+
}
|
|
3622
3740
|
eventBus.emit(`UI:${onChange}`, payload);
|
|
3623
3741
|
} else {
|
|
3624
3742
|
onChange?.(e);
|
|
@@ -3649,7 +3767,7 @@ var init_Input = __esm({
|
|
|
3649
3767
|
"select",
|
|
3650
3768
|
{
|
|
3651
3769
|
ref,
|
|
3652
|
-
value,
|
|
3770
|
+
value: displayValue,
|
|
3653
3771
|
onChange: handleChange,
|
|
3654
3772
|
className: cn(baseClassName, "appearance-none pr-10", className),
|
|
3655
3773
|
...props,
|
|
@@ -3669,7 +3787,7 @@ var init_Input = __esm({
|
|
|
3669
3787
|
"textarea",
|
|
3670
3788
|
{
|
|
3671
3789
|
ref,
|
|
3672
|
-
value,
|
|
3790
|
+
value: displayValue,
|
|
3673
3791
|
onChange: handleChange,
|
|
3674
3792
|
rows,
|
|
3675
3793
|
className: baseClassName,
|
|
@@ -3708,7 +3826,7 @@ var init_Input = __esm({
|
|
|
3708
3826
|
{
|
|
3709
3827
|
ref,
|
|
3710
3828
|
type,
|
|
3711
|
-
value,
|
|
3829
|
+
value: displayValue,
|
|
3712
3830
|
onChange: handleChange,
|
|
3713
3831
|
onKeyDown: handleKeyDown,
|
|
3714
3832
|
className: baseClassName,
|
|
@@ -7595,46 +7713,45 @@ var init_useImageCache = __esm({
|
|
|
7595
7713
|
});
|
|
7596
7714
|
|
|
7597
7715
|
// lib/isometric.ts
|
|
7598
|
-
function isoToScreen(tileX, tileY,
|
|
7599
|
-
const
|
|
7600
|
-
const
|
|
7716
|
+
function isoToScreen(tileX, tileY, cellWidth, baseOffsetX, layout = "isometric") {
|
|
7717
|
+
const w = cellWidth;
|
|
7718
|
+
const fh = cellWidth / 2;
|
|
7601
7719
|
if (layout === "hex") {
|
|
7602
|
-
const screenX2 = tileX *
|
|
7603
|
-
const screenY2 = tileY * (
|
|
7720
|
+
const screenX2 = tileX * w + (tileY & 1) * (w / 2) + baseOffsetX;
|
|
7721
|
+
const screenY2 = tileY * (fh * 0.75);
|
|
7604
7722
|
return { x: screenX2, y: screenY2 };
|
|
7605
7723
|
}
|
|
7606
7724
|
if (layout === "flat") {
|
|
7607
|
-
const screenX2 = tileX *
|
|
7608
|
-
const screenY2 = tileY *
|
|
7725
|
+
const screenX2 = tileX * w + baseOffsetX;
|
|
7726
|
+
const screenY2 = tileY * w;
|
|
7609
7727
|
return { x: screenX2, y: screenY2 };
|
|
7610
7728
|
}
|
|
7611
|
-
const screenX = (tileX - tileY) * (
|
|
7612
|
-
const screenY = (tileX + tileY) * (
|
|
7729
|
+
const screenX = (tileX - tileY) * (w / 2) + baseOffsetX;
|
|
7730
|
+
const screenY = (tileX + tileY) * (fh / 2);
|
|
7613
7731
|
return { x: screenX, y: screenY };
|
|
7614
7732
|
}
|
|
7615
|
-
function screenToIso(screenX, screenY,
|
|
7616
|
-
const
|
|
7617
|
-
const
|
|
7733
|
+
function screenToIso(screenX, screenY, cellWidth, baseOffsetX, layout = "isometric") {
|
|
7734
|
+
const w = cellWidth;
|
|
7735
|
+
const fh = cellWidth / 2;
|
|
7618
7736
|
if (layout === "hex") {
|
|
7619
|
-
const row = Math.round(screenY / (
|
|
7620
|
-
const col = Math.round((screenX - (row & 1) * (
|
|
7737
|
+
const row = Math.round(screenY / (fh * 0.75));
|
|
7738
|
+
const col = Math.round((screenX - (row & 1) * (w / 2) - baseOffsetX) / w);
|
|
7621
7739
|
return { x: col, y: row };
|
|
7622
7740
|
}
|
|
7623
7741
|
if (layout === "flat") {
|
|
7624
|
-
const col = Math.round((screenX - baseOffsetX) /
|
|
7625
|
-
const row = Math.round(screenY /
|
|
7742
|
+
const col = Math.round((screenX - baseOffsetX) / w);
|
|
7743
|
+
const row = Math.round(screenY / w);
|
|
7626
7744
|
return { x: col, y: row };
|
|
7627
7745
|
}
|
|
7628
7746
|
const adjustedX = screenX - baseOffsetX;
|
|
7629
|
-
const tileX = (adjustedX / (
|
|
7630
|
-
const tileY = (screenY / (
|
|
7747
|
+
const tileX = (adjustedX / (w / 2) + screenY / (fh / 2)) / 2;
|
|
7748
|
+
const tileY = (screenY / (fh / 2) - adjustedX / (w / 2)) / 2;
|
|
7631
7749
|
return { x: Math.round(tileX), y: Math.round(tileY) };
|
|
7632
7750
|
}
|
|
7633
|
-
var TILE_WIDTH,
|
|
7751
|
+
var TILE_WIDTH, DIAMOND_TOP_Y, BACKGROUND_FALLBACK_COLOR, MINIMAP_TERRAIN_COLORS;
|
|
7634
7752
|
var init_isometric = __esm({
|
|
7635
7753
|
"lib/isometric.ts"() {
|
|
7636
7754
|
TILE_WIDTH = 256;
|
|
7637
|
-
FLOOR_HEIGHT = 128;
|
|
7638
7755
|
DIAMOND_TOP_Y = 374;
|
|
7639
7756
|
BACKGROUND_FALLBACK_COLOR = "#1a1a2e";
|
|
7640
7757
|
MINIMAP_TERRAIN_COLORS = {
|
|
@@ -8119,210 +8236,6 @@ var init_ChoiceButton = __esm({
|
|
|
8119
8236
|
ChoiceButton.displayName = "ChoiceButton";
|
|
8120
8237
|
}
|
|
8121
8238
|
});
|
|
8122
|
-
function SvgStage({
|
|
8123
|
-
cols,
|
|
8124
|
-
rows,
|
|
8125
|
-
tileSize = 32,
|
|
8126
|
-
background = "var(--color-background)",
|
|
8127
|
-
tileClickEvent,
|
|
8128
|
-
tileHoverEvent,
|
|
8129
|
-
tileLeaveEvent,
|
|
8130
|
-
keyMap,
|
|
8131
|
-
keyUpMap,
|
|
8132
|
-
className,
|
|
8133
|
-
children
|
|
8134
|
-
}) {
|
|
8135
|
-
const eventBus = useEventBus();
|
|
8136
|
-
const svgRef = React83.useRef(null);
|
|
8137
|
-
const pointerDownRef = React83.useRef(null);
|
|
8138
|
-
const cellFromClient = React83.useCallback((clientX, clientY) => {
|
|
8139
|
-
const svg = svgRef.current;
|
|
8140
|
-
if (!svg) return null;
|
|
8141
|
-
const rect = svg.getBoundingClientRect();
|
|
8142
|
-
if (rect.width === 0 || rect.height === 0) return null;
|
|
8143
|
-
const vbW = cols * tileSize;
|
|
8144
|
-
const vbH = rows * tileSize;
|
|
8145
|
-
const meet = Math.min(rect.width / vbW, rect.height / vbH);
|
|
8146
|
-
const offsetX = (rect.width - vbW * meet) / 2;
|
|
8147
|
-
const offsetY = (rect.height - vbH * meet) / 2;
|
|
8148
|
-
const svgX = (clientX - rect.left - offsetX) / meet;
|
|
8149
|
-
const svgY = (clientY - rect.top - offsetY) / meet;
|
|
8150
|
-
return {
|
|
8151
|
-
x: Math.min(Math.max(Math.floor(svgX / tileSize), 0), cols - 1),
|
|
8152
|
-
y: Math.min(Math.max(Math.floor(svgY / tileSize), 0), rows - 1)
|
|
8153
|
-
};
|
|
8154
|
-
}, [cols, rows, tileSize]);
|
|
8155
|
-
const handlePointerDown = React83.useCallback((e) => {
|
|
8156
|
-
pointerDownRef.current = { clientX: e.clientX, clientY: e.clientY };
|
|
8157
|
-
}, []);
|
|
8158
|
-
const handlePointerUp = React83.useCallback((e) => {
|
|
8159
|
-
const down = pointerDownRef.current;
|
|
8160
|
-
pointerDownRef.current = null;
|
|
8161
|
-
if (!tileClickEvent) return;
|
|
8162
|
-
if (down && Math.hypot(e.clientX - down.clientX, e.clientY - down.clientY) > 5) return;
|
|
8163
|
-
const cell = cellFromClient(e.clientX, e.clientY);
|
|
8164
|
-
if (cell) eventBus.emit(`UI:${tileClickEvent}`, cell);
|
|
8165
|
-
}, [cellFromClient, tileClickEvent, eventBus]);
|
|
8166
|
-
const handlePointerMove = React83.useCallback((e) => {
|
|
8167
|
-
if (!tileHoverEvent) return;
|
|
8168
|
-
const cell = cellFromClient(e.clientX, e.clientY);
|
|
8169
|
-
if (cell) eventBus.emit(`UI:${tileHoverEvent}`, cell);
|
|
8170
|
-
}, [cellFromClient, tileHoverEvent, eventBus]);
|
|
8171
|
-
const handlePointerLeave = React83.useCallback(() => {
|
|
8172
|
-
pointerDownRef.current = null;
|
|
8173
|
-
if (tileLeaveEvent) eventBus.emit(`UI:${tileLeaveEvent}`, {});
|
|
8174
|
-
}, [tileLeaveEvent, eventBus]);
|
|
8175
|
-
React83.useEffect(() => {
|
|
8176
|
-
if (!keyMap && !keyUpMap) return;
|
|
8177
|
-
const onDown = (e) => {
|
|
8178
|
-
const ev = keyMap?.[e.code];
|
|
8179
|
-
if (ev) {
|
|
8180
|
-
eventBus.emit(`UI:${ev}`, {});
|
|
8181
|
-
e.preventDefault();
|
|
8182
|
-
}
|
|
8183
|
-
};
|
|
8184
|
-
const onUp = (e) => {
|
|
8185
|
-
const ev = keyUpMap?.[e.code];
|
|
8186
|
-
if (ev) eventBus.emit(`UI:${ev}`, {});
|
|
8187
|
-
};
|
|
8188
|
-
window.addEventListener("keydown", onDown);
|
|
8189
|
-
window.addEventListener("keyup", onUp);
|
|
8190
|
-
return () => {
|
|
8191
|
-
window.removeEventListener("keydown", onDown);
|
|
8192
|
-
window.removeEventListener("keyup", onUp);
|
|
8193
|
-
};
|
|
8194
|
-
}, [keyMap, keyUpMap, eventBus]);
|
|
8195
|
-
React83.useEffect(() => {
|
|
8196
|
-
if (!keyMap && !keyUpMap) return;
|
|
8197
|
-
svgRef.current?.focus();
|
|
8198
|
-
}, [keyMap, keyUpMap]);
|
|
8199
|
-
const stageContext = React83.useMemo(() => ({ tileSize }), [tileSize]);
|
|
8200
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
8201
|
-
"svg",
|
|
8202
|
-
{
|
|
8203
|
-
ref: svgRef,
|
|
8204
|
-
"data-testid": "svg-stage",
|
|
8205
|
-
viewBox: `0 0 ${cols * tileSize} ${rows * tileSize}`,
|
|
8206
|
-
preserveAspectRatio: "xMidYMid meet",
|
|
8207
|
-
className: cn("block h-full w-full", className),
|
|
8208
|
-
tabIndex: keyMap || keyUpMap ? 0 : void 0,
|
|
8209
|
-
onPointerDown: handlePointerDown,
|
|
8210
|
-
onPointerMove: handlePointerMove,
|
|
8211
|
-
onPointerUp: handlePointerUp,
|
|
8212
|
-
onPointerLeave: handlePointerLeave,
|
|
8213
|
-
children: [
|
|
8214
|
-
/* @__PURE__ */ jsxRuntime.jsx("rect", { width: cols * tileSize, height: rows * tileSize, fill: background }),
|
|
8215
|
-
/* @__PURE__ */ jsxRuntime.jsx(SvgStageContext.Provider, { value: stageContext, children })
|
|
8216
|
-
]
|
|
8217
|
-
}
|
|
8218
|
-
);
|
|
8219
|
-
}
|
|
8220
|
-
var SvgStageContext;
|
|
8221
|
-
var init_SvgStage = __esm({
|
|
8222
|
-
"components/game/molecules/SvgStage.tsx"() {
|
|
8223
|
-
"use client";
|
|
8224
|
-
init_cn();
|
|
8225
|
-
init_useEventBus();
|
|
8226
|
-
SvgStageContext = React83__namespace.createContext({ tileSize: 1 });
|
|
8227
|
-
SvgStage.displayName = "SvgStage";
|
|
8228
|
-
}
|
|
8229
|
-
});
|
|
8230
|
-
function SvgDrawShape({
|
|
8231
|
-
shape,
|
|
8232
|
-
x,
|
|
8233
|
-
y,
|
|
8234
|
-
width,
|
|
8235
|
-
height,
|
|
8236
|
-
radius,
|
|
8237
|
-
radiusY,
|
|
8238
|
-
points,
|
|
8239
|
-
d,
|
|
8240
|
-
x2,
|
|
8241
|
-
y2,
|
|
8242
|
-
fill,
|
|
8243
|
-
stroke,
|
|
8244
|
-
strokeWidth,
|
|
8245
|
-
opacity,
|
|
8246
|
-
className
|
|
8247
|
-
}) {
|
|
8248
|
-
const { tileSize } = React83.useContext(SvgStageContext);
|
|
8249
|
-
const cell = (v) => v === void 0 ? void 0 : v * tileSize;
|
|
8250
|
-
const paint = {
|
|
8251
|
-
fill: fill ?? (stroke === void 0 ? "var(--color-primary)" : "none"),
|
|
8252
|
-
stroke,
|
|
8253
|
-
strokeWidth,
|
|
8254
|
-
opacity,
|
|
8255
|
-
className
|
|
8256
|
-
};
|
|
8257
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("g", { transform: `translate(${x * tileSize} ${y * tileSize})`, children: [
|
|
8258
|
-
shape === "rect" && /* @__PURE__ */ jsxRuntime.jsx("rect", { width: cell(width), height: cell(height), ...paint }),
|
|
8259
|
-
shape === "circle" && /* @__PURE__ */ jsxRuntime.jsx("circle", { r: cell(radius), ...paint }),
|
|
8260
|
-
shape === "ellipse" && /* @__PURE__ */ jsxRuntime.jsx("ellipse", { rx: cell(radius), ry: cell(radiusY ?? radius), ...paint }),
|
|
8261
|
-
shape === "polygon" && /* @__PURE__ */ jsxRuntime.jsx("polygon", { points, ...paint }),
|
|
8262
|
-
shape === "polyline" && /* @__PURE__ */ jsxRuntime.jsx("polyline", { points, ...paint }),
|
|
8263
|
-
shape === "path" && /* @__PURE__ */ jsxRuntime.jsx("path", { d, ...paint }),
|
|
8264
|
-
shape === "line" && /* @__PURE__ */ jsxRuntime.jsx("line", { x2: cell(x2), y2: cell(y2), ...paint })
|
|
8265
|
-
] });
|
|
8266
|
-
}
|
|
8267
|
-
var init_SvgDrawShape = __esm({
|
|
8268
|
-
"components/game/atoms/SvgDrawShape.tsx"() {
|
|
8269
|
-
"use client";
|
|
8270
|
-
init_SvgStage();
|
|
8271
|
-
SvgDrawShape.displayName = "SvgDrawShape";
|
|
8272
|
-
}
|
|
8273
|
-
});
|
|
8274
|
-
function SvgDrawGroup({
|
|
8275
|
-
x = 0,
|
|
8276
|
-
y = 0,
|
|
8277
|
-
scale,
|
|
8278
|
-
rotate,
|
|
8279
|
-
opacity,
|
|
8280
|
-
className,
|
|
8281
|
-
children
|
|
8282
|
-
}) {
|
|
8283
|
-
const { tileSize } = React83.useContext(SvgStageContext);
|
|
8284
|
-
const transforms = [`translate(${x * tileSize} ${y * tileSize})`];
|
|
8285
|
-
if (rotate !== void 0) transforms.push(`rotate(${rotate})`);
|
|
8286
|
-
if (scale !== void 0) transforms.push(`scale(${scale})`);
|
|
8287
|
-
return /* @__PURE__ */ jsxRuntime.jsx("g", { transform: transforms.join(" "), opacity, className, children });
|
|
8288
|
-
}
|
|
8289
|
-
var init_SvgDrawGroup = __esm({
|
|
8290
|
-
"components/game/atoms/SvgDrawGroup.tsx"() {
|
|
8291
|
-
"use client";
|
|
8292
|
-
init_SvgStage();
|
|
8293
|
-
SvgDrawGroup.displayName = "SvgDrawGroup";
|
|
8294
|
-
}
|
|
8295
|
-
});
|
|
8296
|
-
function SvgDrawText({
|
|
8297
|
-
x,
|
|
8298
|
-
y,
|
|
8299
|
-
text,
|
|
8300
|
-
size = 12,
|
|
8301
|
-
fill = "var(--color-foreground)",
|
|
8302
|
-
anchor = "middle",
|
|
8303
|
-
className
|
|
8304
|
-
}) {
|
|
8305
|
-
const { tileSize } = React83.useContext(SvgStageContext);
|
|
8306
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
8307
|
-
"text",
|
|
8308
|
-
{
|
|
8309
|
-
x: x * tileSize,
|
|
8310
|
-
y: y * tileSize,
|
|
8311
|
-
fontSize: size,
|
|
8312
|
-
fill,
|
|
8313
|
-
textAnchor: anchor,
|
|
8314
|
-
className,
|
|
8315
|
-
children: text
|
|
8316
|
-
}
|
|
8317
|
-
);
|
|
8318
|
-
}
|
|
8319
|
-
var init_SvgDrawText = __esm({
|
|
8320
|
-
"components/game/atoms/SvgDrawText.tsx"() {
|
|
8321
|
-
"use client";
|
|
8322
|
-
init_SvgStage();
|
|
8323
|
-
SvgDrawText.displayName = "SvgDrawText";
|
|
8324
|
-
}
|
|
8325
|
-
});
|
|
8326
8239
|
function ControlGrid({
|
|
8327
8240
|
kind,
|
|
8328
8241
|
buttons = DEFAULT_BUTTONS,
|
|
@@ -9026,6 +8939,7 @@ function MiniMap({
|
|
|
9026
8939
|
const cached = imgCacheRef.current.get(url);
|
|
9027
8940
|
if (cached) return cached.complete ? cached : null;
|
|
9028
8941
|
const img = new Image();
|
|
8942
|
+
img.crossOrigin = "anonymous";
|
|
9029
8943
|
img.src = url;
|
|
9030
8944
|
img.onload = () => {
|
|
9031
8945
|
const canvas = canvasRef.current;
|
|
@@ -9193,7 +9107,7 @@ function useCamera(initial) {
|
|
|
9193
9107
|
const handleWheel = React83.useCallback((e, drawFn) => {
|
|
9194
9108
|
e.preventDefault();
|
|
9195
9109
|
const zoomDelta = e.deltaY > 0 ? 0.9 : 1.1;
|
|
9196
|
-
cameraRef.current.zoom = Math.max(
|
|
9110
|
+
cameraRef.current.zoom = Math.max(MIN_ZOOM, Math.min(MAX_ZOOM, cameraRef.current.zoom * zoomDelta));
|
|
9197
9111
|
drawFn?.();
|
|
9198
9112
|
}, []);
|
|
9199
9113
|
const handlePointerDown = React83.useCallback((e) => {
|
|
@@ -9214,7 +9128,7 @@ function useCamera(initial) {
|
|
|
9214
9128
|
const zoomAtPoint = React83.useCallback((factor, centerX, centerY, viewportSize, drawFn) => {
|
|
9215
9129
|
const cam = cameraRef.current;
|
|
9216
9130
|
const oldZoom = cam.zoom;
|
|
9217
|
-
const newZoom = Math.max(
|
|
9131
|
+
const newZoom = Math.max(MIN_ZOOM, Math.min(MAX_ZOOM, oldZoom * factor));
|
|
9218
9132
|
if (newZoom === oldZoom) {
|
|
9219
9133
|
drawFn?.();
|
|
9220
9134
|
return;
|
|
@@ -9266,9 +9180,12 @@ function useCamera(initial) {
|
|
|
9266
9180
|
lerpToTarget
|
|
9267
9181
|
};
|
|
9268
9182
|
}
|
|
9183
|
+
var MIN_ZOOM, MAX_ZOOM;
|
|
9269
9184
|
var init_useCamera = __esm({
|
|
9270
9185
|
"hooks/useCamera.ts"() {
|
|
9271
9186
|
"use client";
|
|
9187
|
+
MIN_ZOOM = 0.05;
|
|
9188
|
+
MAX_ZOOM = 10;
|
|
9272
9189
|
}
|
|
9273
9190
|
});
|
|
9274
9191
|
|
|
@@ -9282,6 +9199,7 @@ function getOrLoadImage(url, onReady) {
|
|
|
9282
9199
|
return null;
|
|
9283
9200
|
}
|
|
9284
9201
|
const img = new Image();
|
|
9202
|
+
img.crossOrigin = "anonymous";
|
|
9285
9203
|
const entry = { img, status: "pending", onReady };
|
|
9286
9204
|
cache.set(url, entry);
|
|
9287
9205
|
updateAssetStatus(url, "pending");
|
|
@@ -9293,10 +9211,14 @@ function getOrLoadImage(url, onReady) {
|
|
|
9293
9211
|
img.onerror = () => {
|
|
9294
9212
|
entry.status = "failed";
|
|
9295
9213
|
updateAssetStatus(url, "failed");
|
|
9214
|
+
entry.onReady?.();
|
|
9296
9215
|
};
|
|
9297
9216
|
img.src = url;
|
|
9298
9217
|
return null;
|
|
9299
9218
|
}
|
|
9219
|
+
function getImageStatus(url) {
|
|
9220
|
+
return cache.get(url)?.status;
|
|
9221
|
+
}
|
|
9300
9222
|
var cache;
|
|
9301
9223
|
var init_imageCache = __esm({
|
|
9302
9224
|
"lib/imageCache.ts"() {
|
|
@@ -9405,6 +9327,15 @@ function createWebPainter(ctx, onAssetLoad) {
|
|
|
9405
9327
|
ctx.lineWidth = lineWidth;
|
|
9406
9328
|
ctx.stroke();
|
|
9407
9329
|
},
|
|
9330
|
+
fillPath(d, color) {
|
|
9331
|
+
ctx.fillStyle = color;
|
|
9332
|
+
ctx.fill(new Path2D(d));
|
|
9333
|
+
},
|
|
9334
|
+
strokePath(d, color, lineWidth = 1) {
|
|
9335
|
+
ctx.strokeStyle = color;
|
|
9336
|
+
ctx.lineWidth = lineWidth;
|
|
9337
|
+
ctx.stroke(new Path2D(d));
|
|
9338
|
+
},
|
|
9408
9339
|
text(str, x, y, style) {
|
|
9409
9340
|
if (style.font) ctx.font = style.font;
|
|
9410
9341
|
ctx.fillStyle = style.color;
|
|
@@ -9426,12 +9357,13 @@ var init_webPainter2d = __esm({
|
|
|
9426
9357
|
|
|
9427
9358
|
// lib/drawable/projector.ts
|
|
9428
9359
|
function create2DProjector(opts) {
|
|
9429
|
-
const {
|
|
9430
|
-
const
|
|
9431
|
-
const
|
|
9432
|
-
const
|
|
9360
|
+
const { baseOffsetX, layout } = opts;
|
|
9361
|
+
const tw = opts.tileWidth ?? TILE_WIDTH;
|
|
9362
|
+
const tileWidth = layout === "free" ? 1 : tw;
|
|
9363
|
+
const floorHeight = layout === "free" ? 1 : tw / 2;
|
|
9364
|
+
const diamondTopY = layout === "free" ? 0 : opts.diamondTopY ?? tw * (DIAMOND_TOP_Y / TILE_WIDTH);
|
|
9433
9365
|
const squareGrid = layout === "flat" || layout === "free";
|
|
9434
|
-
const project = (pos) => layout === "free" ? { x: pos.x, y: pos.y } : isoToScreen(pos.x, pos.y,
|
|
9366
|
+
const project = (pos) => layout === "free" ? { x: pos.x, y: pos.y } : isoToScreen(pos.x, pos.y, tw, baseOffsetX, layout);
|
|
9435
9367
|
const anchorPoint = (pos, anchor) => {
|
|
9436
9368
|
const base = project(pos);
|
|
9437
9369
|
if (anchor === "top-left") return base;
|
|
@@ -9462,7 +9394,7 @@ function create2DProjector(opts) {
|
|
|
9462
9394
|
{ x: base.x, y: topY + floorHeight / 2 }
|
|
9463
9395
|
];
|
|
9464
9396
|
};
|
|
9465
|
-
return { project, anchorPoint, cellPath, tileWidth, floorHeight, diamondTopY,
|
|
9397
|
+
return { project, anchorPoint, cellPath, tileWidth, floorHeight, diamondTopY, squareGrid, worldPixelDirect: layout === "free" };
|
|
9466
9398
|
}
|
|
9467
9399
|
var init_projector = __esm({
|
|
9468
9400
|
"lib/drawable/projector.ts"() {
|
|
@@ -9478,32 +9410,67 @@ var init_contract = __esm({
|
|
|
9478
9410
|
"lib/drawable/contract.ts"() {
|
|
9479
9411
|
}
|
|
9480
9412
|
});
|
|
9481
|
-
|
|
9482
|
-
|
|
9413
|
+
function warnMissingOnce(reason, node) {
|
|
9414
|
+
const key = `${reason}:${node.asset.url}:${String(node.asset.atlas)}:${String(node.asset.sprite)}`;
|
|
9415
|
+
if (loggedMissing.has(key)) return;
|
|
9416
|
+
loggedMissing.add(key);
|
|
9417
|
+
spriteLog.warn("draw-sprite asset unresolvable \u2014 painting fallback square", { reason, url: node.asset.url, atlas: node.asset.atlas, sprite: node.asset.sprite });
|
|
9418
|
+
}
|
|
9419
|
+
function paintFallbackSquare(painter, node, dctx, reason) {
|
|
9420
|
+
warnMissingOnce(reason, node);
|
|
9421
|
+
const tw = dctx.projector.tileWidth;
|
|
9422
|
+
const natural = dctx.projector.worldPixelDirect ? FALLBACK_WORLD_PX : tw;
|
|
9423
|
+
const w = node.width !== void 0 ? node.width * tw : natural;
|
|
9424
|
+
const h = node.height !== void 0 ? node.height * tw : natural;
|
|
9425
|
+
const anchor = node.anchor ?? "top-left";
|
|
9426
|
+
const p = dctx.projector.anchorPoint(node.position, anchor);
|
|
9427
|
+
const dx = anchor === "top-left" ? p.x : p.x - w / 2;
|
|
9428
|
+
const dy = anchor === "ground" ? p.y - h : anchor === "center" ? p.y - h / 2 : p.y;
|
|
9429
|
+
painter.save();
|
|
9430
|
+
if (node.opacity !== void 0 && node.opacity !== 1) painter.setAlpha(node.opacity);
|
|
9431
|
+
painter.fillRect(dx, dy, w, h, "#9b8f7f");
|
|
9432
|
+
painter.strokeRect(dx, dy, w, h, "#5e564b", Math.max(1, tw / 32));
|
|
9433
|
+
painter.restore();
|
|
9434
|
+
}
|
|
9483
9435
|
function DrawSprite(_props) {
|
|
9484
9436
|
return null;
|
|
9485
9437
|
}
|
|
9486
|
-
var paintSprite;
|
|
9438
|
+
var spriteLog, loggedMissing, FALLBACK_WORLD_PX, paintSprite;
|
|
9487
9439
|
var init_DrawSprite = __esm({
|
|
9488
9440
|
"components/game/atoms/DrawSprite.tsx"() {
|
|
9489
9441
|
"use client";
|
|
9490
9442
|
init_atlasSlice();
|
|
9443
|
+
init_imageCache();
|
|
9491
9444
|
init_contract();
|
|
9445
|
+
spriteLog = logger.createLogger("almadar:ui:draw-sprite");
|
|
9446
|
+
loggedMissing = /* @__PURE__ */ new Set();
|
|
9447
|
+
FALLBACK_WORLD_PX = 32;
|
|
9492
9448
|
paintSprite = (painter, node, dctx) => {
|
|
9493
9449
|
if (!node.asset?.url || !isValidScenePos(node.position)) return;
|
|
9494
9450
|
const tex = painter.resolveTexture(node.asset.url);
|
|
9495
|
-
if (!tex)
|
|
9451
|
+
if (!tex) {
|
|
9452
|
+
if (getImageStatus(node.asset.url) === "failed") paintFallbackSquare(painter, node, dctx, "texture-failed");
|
|
9453
|
+
return;
|
|
9454
|
+
}
|
|
9496
9455
|
let src = typeof node.frame === "object" ? node.frame : void 0;
|
|
9497
9456
|
if (!src && isAtlasAsset(node.asset)) {
|
|
9498
9457
|
const atlas = getAtlas(node.asset.atlas, dctx.invalidate);
|
|
9499
|
-
if (!atlas)
|
|
9458
|
+
if (!atlas) {
|
|
9459
|
+
if (atlasFailed(node.asset.atlas)) paintFallbackSquare(painter, node, dctx, "atlas-failed");
|
|
9460
|
+
return;
|
|
9461
|
+
}
|
|
9500
9462
|
const r = subRectFor(atlas, node.asset.sprite);
|
|
9501
|
-
if (!r)
|
|
9463
|
+
if (!r) {
|
|
9464
|
+
paintFallbackSquare(painter, node, dctx, "sprite-missing");
|
|
9465
|
+
return;
|
|
9466
|
+
}
|
|
9502
9467
|
src = { x: r.sx, y: r.sy, w: r.sw, h: r.sh };
|
|
9503
9468
|
}
|
|
9504
9469
|
const tw = dctx.projector.tileWidth;
|
|
9505
|
-
const
|
|
9506
|
-
const
|
|
9470
|
+
const fallbackW = dctx.projector.worldPixelDirect ? src ? src.w : tex.width : tw;
|
|
9471
|
+
const fallbackH = dctx.projector.worldPixelDirect ? src ? src.h : tex.height : tw;
|
|
9472
|
+
const w = node.width !== void 0 ? node.width * tw : fallbackW;
|
|
9473
|
+
const h = node.height !== void 0 ? node.height * tw : fallbackH;
|
|
9507
9474
|
const anchor = node.anchor ?? "top-left";
|
|
9508
9475
|
const p = dctx.projector.anchorPoint(node.position, anchor);
|
|
9509
9476
|
const dx = anchor === "top-left" ? p.x : p.x - w / 2;
|
|
@@ -9580,6 +9547,16 @@ var init_DrawShape = __esm({
|
|
|
9580
9547
|
if (node.stroke) painter.strokePoly(pts, node.stroke, node.strokeWidth ?? 1, true);
|
|
9581
9548
|
break;
|
|
9582
9549
|
}
|
|
9550
|
+
case "path": {
|
|
9551
|
+
if (!node.d) break;
|
|
9552
|
+
const base = dctx.projector.project(node.position);
|
|
9553
|
+
const tw = dctx.projector.tileWidth;
|
|
9554
|
+
painter.translate(base.x, base.y);
|
|
9555
|
+
painter.scale(tw, tw);
|
|
9556
|
+
if (node.fill) painter.fillPath(node.d, node.fill);
|
|
9557
|
+
if (node.stroke) painter.strokePath(node.d, node.stroke, (node.strokeWidth ?? 1) / tw);
|
|
9558
|
+
break;
|
|
9559
|
+
}
|
|
9583
9560
|
}
|
|
9584
9561
|
painter.restore();
|
|
9585
9562
|
};
|
|
@@ -9671,6 +9648,19 @@ function paintDrawable(painter, node, dctx) {
|
|
|
9671
9648
|
case "draw-text":
|
|
9672
9649
|
paintText(painter, node, dctx);
|
|
9673
9650
|
break;
|
|
9651
|
+
case "draw-group": {
|
|
9652
|
+
if (!isValidScenePos(node.position)) break;
|
|
9653
|
+
if (!Array.isArray(node.items)) break;
|
|
9654
|
+
const p = dctx.projector.project(node.position);
|
|
9655
|
+
painter.save();
|
|
9656
|
+
painter.translate(p.x, p.y);
|
|
9657
|
+
if (node.scale !== void 0) painter.scale(node.scale, node.scale);
|
|
9658
|
+
if (node.rotate !== void 0) painter.rotate(node.rotate);
|
|
9659
|
+
if (node.opacity !== void 0 && node.opacity !== 1) painter.setAlpha(node.opacity);
|
|
9660
|
+
for (const item of node.items) paintDrawable(painter, item, dctx);
|
|
9661
|
+
painter.restore();
|
|
9662
|
+
break;
|
|
9663
|
+
}
|
|
9674
9664
|
case "draw-sprite-layer":
|
|
9675
9665
|
paintSpriteLayer(painter, node, dctx);
|
|
9676
9666
|
break;
|
|
@@ -9684,6 +9674,7 @@ function paintDrawable(painter, node, dctx) {
|
|
|
9684
9674
|
}
|
|
9685
9675
|
var init_paintDispatch = __esm({
|
|
9686
9676
|
"lib/drawable/paintDispatch.ts"() {
|
|
9677
|
+
init_contract();
|
|
9687
9678
|
init_DrawSprite();
|
|
9688
9679
|
init_DrawShape();
|
|
9689
9680
|
init_DrawText();
|
|
@@ -9701,6 +9692,7 @@ function collectDrawnItems(nodes) {
|
|
|
9701
9692
|
case "draw-sprite":
|
|
9702
9693
|
case "draw-shape":
|
|
9703
9694
|
case "draw-text":
|
|
9695
|
+
case "draw-group":
|
|
9704
9696
|
if (isValidScenePos(n.position)) out.push({ pos: n.position, id: n.id });
|
|
9705
9697
|
break;
|
|
9706
9698
|
case "draw-sprite-layer":
|
|
@@ -9744,6 +9736,8 @@ function Canvas2D({
|
|
|
9744
9736
|
keyUpMap,
|
|
9745
9737
|
camera = "pan-zoom",
|
|
9746
9738
|
scale = 0.4,
|
|
9739
|
+
tileWidth,
|
|
9740
|
+
fit = false,
|
|
9747
9741
|
showMinimap = true,
|
|
9748
9742
|
followTarget,
|
|
9749
9743
|
cameraPos,
|
|
@@ -9786,9 +9780,32 @@ function Canvas2D({
|
|
|
9786
9780
|
observer2.observe(el);
|
|
9787
9781
|
return () => observer2.disconnect();
|
|
9788
9782
|
}, []);
|
|
9789
|
-
const
|
|
9790
|
-
const
|
|
9791
|
-
const
|
|
9783
|
+
const [atlasVersion, setAtlasVersion] = React83.useState(0);
|
|
9784
|
+
const bumpAtlas = React83.useCallback(() => setAtlasVersion((v) => v + 1), []);
|
|
9785
|
+
const detectedTileWidth = React83.useMemo(() => {
|
|
9786
|
+
for (const n of drawables ?? []) {
|
|
9787
|
+
const refs = [];
|
|
9788
|
+
if (n.type === "draw-sprite") refs.push(n.asset);
|
|
9789
|
+
else if (n.type === "draw-sprite-layer") for (const it of n.items) refs.push(it.asset);
|
|
9790
|
+
for (const a of refs) {
|
|
9791
|
+
if (a && isAtlasAsset(a) && a.atlas) {
|
|
9792
|
+
const atlas = getAtlas(a.atlas, bumpAtlas);
|
|
9793
|
+
if (atlas) {
|
|
9794
|
+
if ("tileWidth" in atlas) return atlas.tileWidth;
|
|
9795
|
+
if ("subTextures" in atlas) {
|
|
9796
|
+
const first = Object.values(atlas.subTextures)[0];
|
|
9797
|
+
if (first && typeof first.width === "number") return first.width;
|
|
9798
|
+
}
|
|
9799
|
+
}
|
|
9800
|
+
}
|
|
9801
|
+
}
|
|
9802
|
+
}
|
|
9803
|
+
return void 0;
|
|
9804
|
+
}, [drawables, atlasVersion]);
|
|
9805
|
+
const nativeTileW = tileWidth ?? detectedTileWidth ?? TILE_WIDTH;
|
|
9806
|
+
const scaledTileWidth = nativeTileW;
|
|
9807
|
+
const scaledFloorHeight = nativeTileW / 2;
|
|
9808
|
+
const scaledDiamondTopY = nativeTileW * (DIAMOND_TOP_Y / TILE_WIDTH);
|
|
9792
9809
|
const drawnItems = React83.useMemo(() => collectDrawnItems(drawables ?? []), [drawables]);
|
|
9793
9810
|
const scenePositions = React83.useMemo(() => drawnItems.map((i) => i.pos), [drawnItems]);
|
|
9794
9811
|
const hitIndex = React83.useMemo(() => buildHitIndex(drawnItems), [drawnItems]);
|
|
@@ -9806,14 +9823,36 @@ function Canvas2D({
|
|
|
9806
9823
|
if (isFree || projection === "flat" || projection === "side") return 0;
|
|
9807
9824
|
return (gridExtent.height - 1) * (scaledTileWidth / 2);
|
|
9808
9825
|
}, [isFree, projection, gridExtent.height, scaledTileWidth]);
|
|
9826
|
+
const effectiveZoom = React83.useMemo(() => {
|
|
9827
|
+
if (isFree || projection === "side") return scale;
|
|
9828
|
+
if (!fit) {
|
|
9829
|
+
const z2 = TILE_WIDTH * scale * scale / nativeTileW;
|
|
9830
|
+
return Number.isFinite(z2) && z2 > 0 ? z2 : scale;
|
|
9831
|
+
}
|
|
9832
|
+
if (!viewportSize.width || gridExtent.width < 2 || gridExtent.height < 2) return scale;
|
|
9833
|
+
let boardW;
|
|
9834
|
+
let boardH;
|
|
9835
|
+
if (projection === "flat") {
|
|
9836
|
+
boardW = gridExtent.width * nativeTileW;
|
|
9837
|
+
boardH = gridExtent.height * nativeTileW;
|
|
9838
|
+
} else if (projection === "hex") {
|
|
9839
|
+
boardW = (gridExtent.width + 0.5) * nativeTileW;
|
|
9840
|
+
boardH = gridExtent.height * (nativeTileW / 2) * 0.75 + nativeTileW / 2;
|
|
9841
|
+
} else {
|
|
9842
|
+
boardW = (gridExtent.width + gridExtent.height) * (nativeTileW / 2);
|
|
9843
|
+
boardH = (gridExtent.width + gridExtent.height) * (nativeTileW / 4);
|
|
9844
|
+
}
|
|
9845
|
+
const z = Math.min(viewportSize.width * 0.85 / boardW, viewportSize.height * 0.85 / boardH);
|
|
9846
|
+
return Number.isFinite(z) && z > 0 ? z : scale;
|
|
9847
|
+
}, [isFree, projection, fit, viewportSize, gridExtent, nativeTileW, scale]);
|
|
9809
9848
|
const projector = React83.useMemo(
|
|
9810
|
-
() => create2DProjector({
|
|
9811
|
-
[
|
|
9849
|
+
() => create2DProjector({ tileWidth: nativeTileW, baseOffsetX, layout }),
|
|
9850
|
+
[nativeTileW, baseOffsetX, layout]
|
|
9812
9851
|
);
|
|
9813
9852
|
const unproject = React83.useCallback((screenX, screenY) => {
|
|
9814
9853
|
if (projection === "free" || projection === "side") return { x: Math.round(screenX), y: Math.round(screenY) };
|
|
9815
|
-
return screenToIso(screenX, screenY,
|
|
9816
|
-
}, [projection,
|
|
9854
|
+
return screenToIso(screenX, screenY, nativeTileW, baseOffsetX, projection);
|
|
9855
|
+
}, [projection, nativeTileW, baseOffsetX]);
|
|
9817
9856
|
const bgUrls = React83.useMemo(() => backgroundImage ? [backgroundImage.url] : [], [backgroundImage]);
|
|
9818
9857
|
const { getImage, pendingCount: _imagePendingCount } = useImageCache(bgUrls);
|
|
9819
9858
|
React83.useEffect(() => {
|
|
@@ -9840,9 +9879,7 @@ function Canvas2D({
|
|
|
9840
9879
|
zoomAtPoint,
|
|
9841
9880
|
screenToWorld,
|
|
9842
9881
|
lerpToTarget
|
|
9843
|
-
} = useCamera({ zoom:
|
|
9844
|
-
const [atlasVersion, setAtlasVersion] = React83.useState(0);
|
|
9845
|
-
const bumpAtlas = React83.useCallback(() => setAtlasVersion((v) => v + 1), []);
|
|
9882
|
+
} = useCamera({ zoom: effectiveZoom });
|
|
9846
9883
|
const miniMapTiles = React83.useMemo(() => {
|
|
9847
9884
|
if (!showMinimap) return [];
|
|
9848
9885
|
const color = MINIMAP_TERRAIN_COLORS.default;
|
|
@@ -9917,6 +9954,13 @@ function Canvas2D({
|
|
|
9917
9954
|
React83.useEffect(() => {
|
|
9918
9955
|
draw();
|
|
9919
9956
|
}, [_imagePendingCount, draw]);
|
|
9957
|
+
const userZoomedRef = React83.useRef(false);
|
|
9958
|
+
React83.useEffect(() => {
|
|
9959
|
+
if (userZoomedRef.current) return;
|
|
9960
|
+
if (cameraRef.current.zoom === effectiveZoom) return;
|
|
9961
|
+
cameraRef.current.zoom = effectiveZoom;
|
|
9962
|
+
draw();
|
|
9963
|
+
}, [effectiveZoom, cameraRef, draw]);
|
|
9920
9964
|
React83.useEffect(() => {
|
|
9921
9965
|
draw();
|
|
9922
9966
|
}, [atlasVersion, draw]);
|
|
@@ -9973,7 +10017,9 @@ function Canvas2D({
|
|
|
9973
10017
|
if (tileLeaveEvent) eventBus.emit(`UI:${tileLeaveEvent}`, {});
|
|
9974
10018
|
}, [handleMouseLeave, tileLeaveEvent, eventBus]);
|
|
9975
10019
|
const applyZoom = React83.useCallback((factor, centerX, centerY) => {
|
|
9976
|
-
if (enableCamera)
|
|
10020
|
+
if (!enableCamera) return;
|
|
10021
|
+
userZoomedRef.current = true;
|
|
10022
|
+
zoomAtPoint(factor, centerX, centerY, viewportSize, () => draw());
|
|
9977
10023
|
}, [enableCamera, zoomAtPoint, viewportSize, draw]);
|
|
9978
10024
|
const applyPanDelta = React83.useCallback((dx, dy) => {
|
|
9979
10025
|
if (enableCamera) panBy(dx, dy, () => draw());
|
|
@@ -10158,6 +10204,8 @@ function Canvas({
|
|
|
10158
10204
|
isLoading,
|
|
10159
10205
|
unitScale,
|
|
10160
10206
|
showMinimap,
|
|
10207
|
+
fit,
|
|
10208
|
+
tileWidth,
|
|
10161
10209
|
backgroundImage,
|
|
10162
10210
|
backgroundColor,
|
|
10163
10211
|
worldWidth,
|
|
@@ -10215,6 +10263,8 @@ function Canvas({
|
|
|
10215
10263
|
projection,
|
|
10216
10264
|
camera: to2DCamera(camera?.mode),
|
|
10217
10265
|
...zoom !== void 0 ? { scale: zoom } : {},
|
|
10266
|
+
...fit !== void 0 ? { fit } : {},
|
|
10267
|
+
...tileWidth !== void 0 ? { tileWidth } : {},
|
|
10218
10268
|
...camera?.target !== void 0 ? { followTarget: camera.target } : {},
|
|
10219
10269
|
...camera?.pos !== void 0 ? { cameraPos: camera.pos } : {},
|
|
10220
10270
|
showMinimap,
|
|
@@ -10241,32 +10291,6 @@ var init_Canvas = __esm({
|
|
|
10241
10291
|
Canvas.displayName = "Canvas";
|
|
10242
10292
|
}
|
|
10243
10293
|
});
|
|
10244
|
-
function SvgDrawShapeLayer({
|
|
10245
|
-
items,
|
|
10246
|
-
fill,
|
|
10247
|
-
stroke,
|
|
10248
|
-
strokeWidth,
|
|
10249
|
-
opacity
|
|
10250
|
-
}) {
|
|
10251
|
-
return /* @__PURE__ */ jsxRuntime.jsx("g", { children: items.map(({ id, ...shape }) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
10252
|
-
SvgDrawShape,
|
|
10253
|
-
{
|
|
10254
|
-
...shape,
|
|
10255
|
-
fill: shape.fill ?? fill,
|
|
10256
|
-
stroke: shape.stroke ?? stroke,
|
|
10257
|
-
strokeWidth: shape.strokeWidth ?? strokeWidth,
|
|
10258
|
-
opacity: shape.opacity ?? opacity
|
|
10259
|
-
},
|
|
10260
|
-
id
|
|
10261
|
-
)) });
|
|
10262
|
-
}
|
|
10263
|
-
var init_SvgDrawShapeLayer = __esm({
|
|
10264
|
-
"components/game/molecules/SvgDrawShapeLayer.tsx"() {
|
|
10265
|
-
"use client";
|
|
10266
|
-
init_SvgDrawShape();
|
|
10267
|
-
SvgDrawShapeLayer.displayName = "SvgDrawShapeLayer";
|
|
10268
|
-
}
|
|
10269
|
-
});
|
|
10270
10294
|
function GameAudioToggle({
|
|
10271
10295
|
size = "sm",
|
|
10272
10296
|
className,
|
|
@@ -23452,6 +23476,8 @@ function DataList({
|
|
|
23452
23476
|
hasMore,
|
|
23453
23477
|
children,
|
|
23454
23478
|
pageSize = 5,
|
|
23479
|
+
sortBy,
|
|
23480
|
+
sortDirection,
|
|
23455
23481
|
renderItem: schemaRenderItem,
|
|
23456
23482
|
dragGroup,
|
|
23457
23483
|
accepts,
|
|
@@ -23480,7 +23506,11 @@ function DataList({
|
|
|
23480
23506
|
dndItemIdField,
|
|
23481
23507
|
dndRoot
|
|
23482
23508
|
});
|
|
23483
|
-
const
|
|
23509
|
+
const orderedData = dnd.orderedItems;
|
|
23510
|
+
const allData = React83__namespace.default.useMemo(
|
|
23511
|
+
() => sortRows(orderedData, sortBy, sortDirection),
|
|
23512
|
+
[orderedData, sortBy, sortDirection]
|
|
23513
|
+
);
|
|
23484
23514
|
const data = pageSize > 0 ? allData.slice(0, visibleCount) : allData;
|
|
23485
23515
|
const hasMoreLocal = pageSize > 0 && visibleCount < allData.length;
|
|
23486
23516
|
const hasRenderProp = typeof children === "function";
|
|
@@ -23517,7 +23547,7 @@ function DataList({
|
|
|
23517
23547
|
};
|
|
23518
23548
|
eventBus.emit(`UI:${action.event}`, payload);
|
|
23519
23549
|
};
|
|
23520
|
-
const renderItemActions = (itemData) => {
|
|
23550
|
+
const renderItemActions = (itemData, onPrimary = false) => {
|
|
23521
23551
|
if (!itemActions || itemActions.length === 0) return null;
|
|
23522
23552
|
const inline = maxInlineActions != null ? itemActions.slice(0, maxInlineActions) : itemActions;
|
|
23523
23553
|
const overflow = maxInlineActions != null ? itemActions.slice(maxInlineActions) : [];
|
|
@@ -23530,7 +23560,12 @@ function DataList({
|
|
|
23530
23560
|
onClick: handleActionClick(action, itemData),
|
|
23531
23561
|
"data-testid": `action-${action.event}`,
|
|
23532
23562
|
"data-row-id": String(itemData.id),
|
|
23533
|
-
className: cn(
|
|
23563
|
+
className: cn(
|
|
23564
|
+
action.variant === "danger" && "text-error hover:bg-error/10",
|
|
23565
|
+
// Must sit on the Button itself: the variant's own text colour
|
|
23566
|
+
// beats an inherited one from the row wrapper.
|
|
23567
|
+
onPrimary && "!text-primary-foreground hover:bg-primary-foreground/15"
|
|
23568
|
+
),
|
|
23534
23569
|
children: [
|
|
23535
23570
|
action.icon && renderIconInput2(action.icon, { size: "xs", className: "mr-1" }),
|
|
23536
23571
|
action.label
|
|
@@ -23630,7 +23665,11 @@ function DataList({
|
|
|
23630
23665
|
metaFields.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(HStack, { gap: "xs", className: "mt-1 flex-wrap", children: metaFields.map((f3) => {
|
|
23631
23666
|
const v = getNestedValue(itemData, f3.name);
|
|
23632
23667
|
if (v === void 0 || v === null || v === "") return null;
|
|
23633
|
-
return f3.variant === "badge" ?
|
|
23668
|
+
return f3.variant === "badge" ? (
|
|
23669
|
+
// `format` applies here too — a boolean field badged
|
|
23670
|
+
// without it renders the raw "false" instead of "No".
|
|
23671
|
+
/* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: statusVariant3(String(v)), children: formatValue2(v, f3.format) }, f3.name)
|
|
23672
|
+
) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
23634
23673
|
Typography,
|
|
23635
23674
|
{
|
|
23636
23675
|
variant: "caption",
|
|
@@ -23649,7 +23688,7 @@ function DataList({
|
|
|
23649
23688
|
children: formatDate(timestamp)
|
|
23650
23689
|
}
|
|
23651
23690
|
) : /* @__PURE__ */ jsxRuntime.jsx("span", {}),
|
|
23652
|
-
renderItemActions(itemData)
|
|
23691
|
+
renderItemActions(itemData, isSent)
|
|
23653
23692
|
] })
|
|
23654
23693
|
]
|
|
23655
23694
|
}
|
|
@@ -23742,7 +23781,7 @@ function DataList({
|
|
|
23742
23781
|
if (val === void 0 || val === null) return null;
|
|
23743
23782
|
return /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "xs", className: "items-center flex-shrink-0", children: [
|
|
23744
23783
|
field.icon && renderIconInput2(field.icon, { size: "xs" }),
|
|
23745
|
-
/* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: statusVariant3(String(val)), children:
|
|
23784
|
+
/* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: statusVariant3(String(val)), children: formatValue2(val, field.format) })
|
|
23746
23785
|
] }, field.name);
|
|
23747
23786
|
})
|
|
23748
23787
|
] }),
|
|
@@ -23981,6 +24020,182 @@ var init_FormSection = __esm({
|
|
|
23981
24020
|
FormActions.displayName = "FormActions";
|
|
23982
24021
|
}
|
|
23983
24022
|
});
|
|
24023
|
+
var ALL_CATEGORY, MAX_RENDERED, GridPicker;
|
|
24024
|
+
var init_GridPicker = __esm({
|
|
24025
|
+
"components/core/molecules/GridPicker.tsx"() {
|
|
24026
|
+
"use client";
|
|
24027
|
+
init_cn();
|
|
24028
|
+
init_Input();
|
|
24029
|
+
init_Badge();
|
|
24030
|
+
init_Stack();
|
|
24031
|
+
ALL_CATEGORY = "__all__";
|
|
24032
|
+
MAX_RENDERED = 300;
|
|
24033
|
+
GridPicker = ({
|
|
24034
|
+
items,
|
|
24035
|
+
value,
|
|
24036
|
+
onChange,
|
|
24037
|
+
categories,
|
|
24038
|
+
searchPlaceholder,
|
|
24039
|
+
renderThumbnail,
|
|
24040
|
+
cellSize = 32,
|
|
24041
|
+
className
|
|
24042
|
+
}) => {
|
|
24043
|
+
const [search, setSearch] = React83.useState("");
|
|
24044
|
+
const [activeCategory, setActiveCategory] = React83.useState(ALL_CATEGORY);
|
|
24045
|
+
const gridRef = React83.useRef(null);
|
|
24046
|
+
const categoryChips = React83.useMemo(() => {
|
|
24047
|
+
if (categories !== void 0) return categories;
|
|
24048
|
+
const seen = [];
|
|
24049
|
+
for (const item of items) {
|
|
24050
|
+
if (!seen.includes(item.category)) seen.push(item.category);
|
|
24051
|
+
}
|
|
24052
|
+
return seen;
|
|
24053
|
+
}, [categories, items]);
|
|
24054
|
+
const filtered = React83.useMemo(() => {
|
|
24055
|
+
const needle = search.trim().toLowerCase();
|
|
24056
|
+
return items.filter((item) => {
|
|
24057
|
+
const matchesCategory = activeCategory === ALL_CATEGORY || item.category === activeCategory;
|
|
24058
|
+
const matchesSearch = needle === "" || item.label.toLowerCase().includes(needle) || item.keywords !== void 0 && item.keywords.some((k) => k.toLowerCase().includes(needle));
|
|
24059
|
+
return matchesCategory && matchesSearch;
|
|
24060
|
+
});
|
|
24061
|
+
}, [items, search, activeCategory]);
|
|
24062
|
+
const visible = React83.useMemo(() => filtered.slice(0, MAX_RENDERED), [filtered]);
|
|
24063
|
+
const truncated = filtered.length - visible.length;
|
|
24064
|
+
const select = React83.useCallback(
|
|
24065
|
+
(item) => {
|
|
24066
|
+
onChange(item.id);
|
|
24067
|
+
},
|
|
24068
|
+
[onChange]
|
|
24069
|
+
);
|
|
24070
|
+
const handleKeyDown = React83.useCallback(
|
|
24071
|
+
(e, index) => {
|
|
24072
|
+
const cells = gridRef.current?.querySelectorAll(
|
|
24073
|
+
"[data-gridpicker-cell]"
|
|
24074
|
+
);
|
|
24075
|
+
if (cells === void 0 || cells.length === 0) return;
|
|
24076
|
+
const columns = (() => {
|
|
24077
|
+
const grid = gridRef.current;
|
|
24078
|
+
if (grid === null) return 1;
|
|
24079
|
+
const style = window.getComputedStyle(grid);
|
|
24080
|
+
const cols = style.gridTemplateColumns.split(" ").filter(Boolean).length;
|
|
24081
|
+
return cols > 0 ? cols : 1;
|
|
24082
|
+
})();
|
|
24083
|
+
let next = -1;
|
|
24084
|
+
if (e.key === "ArrowRight") next = index + 1;
|
|
24085
|
+
else if (e.key === "ArrowLeft") next = index - 1;
|
|
24086
|
+
else if (e.key === "ArrowDown") next = index + columns;
|
|
24087
|
+
else if (e.key === "ArrowUp") next = index - columns;
|
|
24088
|
+
else if (e.key === "Enter" || e.key === " ") {
|
|
24089
|
+
e.preventDefault();
|
|
24090
|
+
select(filtered[index]);
|
|
24091
|
+
return;
|
|
24092
|
+
} else {
|
|
24093
|
+
return;
|
|
24094
|
+
}
|
|
24095
|
+
e.preventDefault();
|
|
24096
|
+
if (next >= 0 && next < cells.length) {
|
|
24097
|
+
cells[next].focus();
|
|
24098
|
+
}
|
|
24099
|
+
},
|
|
24100
|
+
[filtered, select]
|
|
24101
|
+
);
|
|
24102
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "sm", className: cn("w-full", className), children: [
|
|
24103
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
24104
|
+
Input,
|
|
24105
|
+
{
|
|
24106
|
+
type: "search",
|
|
24107
|
+
icon: "search",
|
|
24108
|
+
value: search,
|
|
24109
|
+
placeholder: searchPlaceholder,
|
|
24110
|
+
clearable: true,
|
|
24111
|
+
onClear: () => setSearch(""),
|
|
24112
|
+
onChange: (e) => setSearch(e.target.value)
|
|
24113
|
+
}
|
|
24114
|
+
),
|
|
24115
|
+
categoryChips.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "xs", wrap: true, children: [
|
|
24116
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
24117
|
+
Badge,
|
|
24118
|
+
{
|
|
24119
|
+
variant: activeCategory === ALL_CATEGORY ? "primary" : "neutral",
|
|
24120
|
+
size: "sm",
|
|
24121
|
+
role: "button",
|
|
24122
|
+
tabIndex: 0,
|
|
24123
|
+
"aria-pressed": activeCategory === ALL_CATEGORY,
|
|
24124
|
+
className: "cursor-pointer",
|
|
24125
|
+
onClick: () => setActiveCategory(ALL_CATEGORY),
|
|
24126
|
+
onKeyDown: (e) => {
|
|
24127
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
24128
|
+
e.preventDefault();
|
|
24129
|
+
setActiveCategory(ALL_CATEGORY);
|
|
24130
|
+
}
|
|
24131
|
+
},
|
|
24132
|
+
children: "All"
|
|
24133
|
+
}
|
|
24134
|
+
),
|
|
24135
|
+
categoryChips.map((category) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
24136
|
+
Badge,
|
|
24137
|
+
{
|
|
24138
|
+
variant: activeCategory === category ? "primary" : "neutral",
|
|
24139
|
+
size: "sm",
|
|
24140
|
+
role: "button",
|
|
24141
|
+
tabIndex: 0,
|
|
24142
|
+
"aria-pressed": activeCategory === category,
|
|
24143
|
+
className: "cursor-pointer",
|
|
24144
|
+
onClick: () => setActiveCategory(category),
|
|
24145
|
+
onKeyDown: (e) => {
|
|
24146
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
24147
|
+
e.preventDefault();
|
|
24148
|
+
setActiveCategory(category);
|
|
24149
|
+
}
|
|
24150
|
+
},
|
|
24151
|
+
children: category
|
|
24152
|
+
},
|
|
24153
|
+
category
|
|
24154
|
+
))
|
|
24155
|
+
] }),
|
|
24156
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
24157
|
+
"div",
|
|
24158
|
+
{
|
|
24159
|
+
ref: gridRef,
|
|
24160
|
+
role: "listbox",
|
|
24161
|
+
className: "grid gap-1 overflow-y-auto max-h-64 p-1",
|
|
24162
|
+
style: {
|
|
24163
|
+
gridTemplateColumns: `repeat(auto-fill, minmax(${cellSize}px, 1fr))`
|
|
24164
|
+
},
|
|
24165
|
+
children: visible.map((item, index) => {
|
|
24166
|
+
const selected = item.id === value;
|
|
24167
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
24168
|
+
"button",
|
|
24169
|
+
{
|
|
24170
|
+
type: "button",
|
|
24171
|
+
role: "option",
|
|
24172
|
+
"aria-selected": selected,
|
|
24173
|
+
"aria-label": item.label,
|
|
24174
|
+
title: item.label,
|
|
24175
|
+
"data-gridpicker-cell": true,
|
|
24176
|
+
tabIndex: selected || value === void 0 && index === 0 ? 0 : -1,
|
|
24177
|
+
onClick: () => select(item),
|
|
24178
|
+
onKeyDown: (e) => handleKeyDown(e, index),
|
|
24179
|
+
className: cn(
|
|
24180
|
+
"flex items-center justify-center rounded-sm",
|
|
24181
|
+
"transition-colors hover:bg-muted",
|
|
24182
|
+
"focus:outline-none focus:ring-1 focus:ring-ring",
|
|
24183
|
+
selected && "bg-primary/10 ring-1 ring-primary"
|
|
24184
|
+
),
|
|
24185
|
+
style: { width: cellSize, height: cellSize },
|
|
24186
|
+
children: renderThumbnail(item)
|
|
24187
|
+
},
|
|
24188
|
+
item.id
|
|
24189
|
+
);
|
|
24190
|
+
})
|
|
24191
|
+
}
|
|
24192
|
+
),
|
|
24193
|
+
truncated > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-1 text-xs text-muted-foreground", children: `+${truncated} more \u2014 refine your search` })
|
|
24194
|
+
] });
|
|
24195
|
+
};
|
|
24196
|
+
GridPicker.displayName = "GridPicker";
|
|
24197
|
+
}
|
|
24198
|
+
});
|
|
23984
24199
|
function fileIcon(name) {
|
|
23985
24200
|
const ext = name.split(".").pop()?.toLowerCase() ?? "";
|
|
23986
24201
|
switch (ext) {
|
|
@@ -24945,9 +25160,16 @@ var init_Popover = __esm({
|
|
|
24945
25160
|
position = "bottom",
|
|
24946
25161
|
trigger = "click",
|
|
24947
25162
|
showArrow = true,
|
|
25163
|
+
open,
|
|
25164
|
+
onOpenChange,
|
|
24948
25165
|
className
|
|
24949
25166
|
}) => {
|
|
24950
|
-
const [
|
|
25167
|
+
const [uncontrolledOpen, setUncontrolledOpen] = React83.useState(false);
|
|
25168
|
+
const isOpen = open !== void 0 ? open : uncontrolledOpen;
|
|
25169
|
+
const setIsOpen = (next) => {
|
|
25170
|
+
if (open === void 0) setUncontrolledOpen(next);
|
|
25171
|
+
onOpenChange?.(next);
|
|
25172
|
+
};
|
|
24951
25173
|
const [triggerRect, setTriggerRect] = React83.useState(null);
|
|
24952
25174
|
const [popoverWidth, setPopoverWidth] = React83.useState(0);
|
|
24953
25175
|
const triggerRef = React83.useRef(null);
|
|
@@ -24980,6 +25202,23 @@ var init_Popover = __esm({
|
|
|
24980
25202
|
updatePosition();
|
|
24981
25203
|
}
|
|
24982
25204
|
}, [isOpen]);
|
|
25205
|
+
React83.useEffect(() => {
|
|
25206
|
+
if (!isOpen) return;
|
|
25207
|
+
let raf = 0;
|
|
25208
|
+
let lastTop = Number.NaN;
|
|
25209
|
+
let lastLeft = Number.NaN;
|
|
25210
|
+
const track = () => {
|
|
25211
|
+
const rect = triggerRef.current?.getBoundingClientRect();
|
|
25212
|
+
if (rect && (rect.top !== lastTop || rect.left !== lastLeft)) {
|
|
25213
|
+
lastTop = rect.top;
|
|
25214
|
+
lastLeft = rect.left;
|
|
25215
|
+
updatePosition();
|
|
25216
|
+
}
|
|
25217
|
+
raf = requestAnimationFrame(track);
|
|
25218
|
+
};
|
|
25219
|
+
raf = requestAnimationFrame(track);
|
|
25220
|
+
return () => cancelAnimationFrame(raf);
|
|
25221
|
+
}, [isOpen]);
|
|
24983
25222
|
React83.useEffect(() => {
|
|
24984
25223
|
if (!mounted) setPopoverWidth(0);
|
|
24985
25224
|
}, [mounted]);
|
|
@@ -26328,6 +26567,80 @@ var init_FlipCard = __esm({
|
|
|
26328
26567
|
FlipCard.displayName = "FlipCard";
|
|
26329
26568
|
}
|
|
26330
26569
|
});
|
|
26570
|
+
var EMOJI_ITEMS, EmojiPicker;
|
|
26571
|
+
var init_EmojiPicker = __esm({
|
|
26572
|
+
"components/core/molecules/EmojiPicker.tsx"() {
|
|
26573
|
+
"use client";
|
|
26574
|
+
init_useEventBus();
|
|
26575
|
+
init_Button();
|
|
26576
|
+
init_GridPicker();
|
|
26577
|
+
init_Popover();
|
|
26578
|
+
EMOJI_ITEMS = (() => {
|
|
26579
|
+
const items = [];
|
|
26580
|
+
for (const name of emojilib.ordered) {
|
|
26581
|
+
const entry = emojilib.lib[name];
|
|
26582
|
+
if (entry === void 0 || entry.char === null || entry.char === "") continue;
|
|
26583
|
+
items.push({
|
|
26584
|
+
id: entry.char,
|
|
26585
|
+
label: name.replace(/_/g, " "),
|
|
26586
|
+
category: entry.category.replace(/_/g, " "),
|
|
26587
|
+
keywords: entry.keywords
|
|
26588
|
+
});
|
|
26589
|
+
}
|
|
26590
|
+
return items;
|
|
26591
|
+
})();
|
|
26592
|
+
EmojiPicker = ({
|
|
26593
|
+
pickEvent,
|
|
26594
|
+
position = "top",
|
|
26595
|
+
triggerIcon = "smile",
|
|
26596
|
+
triggerLabel = "Add emoji",
|
|
26597
|
+
className
|
|
26598
|
+
}) => {
|
|
26599
|
+
const eventBus = useEventBus();
|
|
26600
|
+
const [open, setOpen] = React83.useState(false);
|
|
26601
|
+
const handlePick = (glyph) => {
|
|
26602
|
+
if (pickEvent !== void 0) {
|
|
26603
|
+
const payload = { emoji: glyph };
|
|
26604
|
+
eventBus.emit(`UI:${pickEvent}`, payload);
|
|
26605
|
+
}
|
|
26606
|
+
setOpen(false);
|
|
26607
|
+
};
|
|
26608
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
26609
|
+
Popover,
|
|
26610
|
+
{
|
|
26611
|
+
position,
|
|
26612
|
+
trigger: "click",
|
|
26613
|
+
showArrow: false,
|
|
26614
|
+
open,
|
|
26615
|
+
onOpenChange: setOpen,
|
|
26616
|
+
content: /* @__PURE__ */ jsxRuntime.jsx(
|
|
26617
|
+
GridPicker,
|
|
26618
|
+
{
|
|
26619
|
+
items: EMOJI_ITEMS,
|
|
26620
|
+
onChange: handlePick,
|
|
26621
|
+
searchPlaceholder: "Search emoji\u2026",
|
|
26622
|
+
renderThumbnail: (item) => /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xl leading-none", "aria-hidden": "true", children: item.id }),
|
|
26623
|
+
cellSize: 32,
|
|
26624
|
+
className: "w-80"
|
|
26625
|
+
}
|
|
26626
|
+
),
|
|
26627
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
26628
|
+
Button,
|
|
26629
|
+
{
|
|
26630
|
+
variant: "ghost",
|
|
26631
|
+
icon: triggerIcon,
|
|
26632
|
+
"aria-label": triggerLabel,
|
|
26633
|
+
title: triggerLabel,
|
|
26634
|
+
className,
|
|
26635
|
+
"data-testid": "emoji-picker-trigger"
|
|
26636
|
+
}
|
|
26637
|
+
)
|
|
26638
|
+
}
|
|
26639
|
+
);
|
|
26640
|
+
};
|
|
26641
|
+
EmojiPicker.displayName = "EmojiPicker";
|
|
26642
|
+
}
|
|
26643
|
+
});
|
|
26331
26644
|
function toISODate(d) {
|
|
26332
26645
|
return d.toISOString().slice(0, 10);
|
|
26333
26646
|
}
|
|
@@ -27280,13 +27593,13 @@ var init_MapView = __esm({
|
|
|
27280
27593
|
shadowSize: [41, 41]
|
|
27281
27594
|
});
|
|
27282
27595
|
L.Marker.prototype.options.icon = defaultIcon;
|
|
27283
|
-
const { useEffect:
|
|
27596
|
+
const { useEffect: useEffect59, useRef: useRef61, useCallback: useCallback89, useState: useState91 } = React83__namespace.default;
|
|
27284
27597
|
const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
|
|
27285
27598
|
const { useEventBus: useEventBus2 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
|
|
27286
27599
|
function MapUpdater({ centerLat, centerLng, zoom }) {
|
|
27287
27600
|
const map = useMap();
|
|
27288
27601
|
const prevRef = useRef61({ centerLat, centerLng, zoom });
|
|
27289
|
-
|
|
27602
|
+
useEffect59(() => {
|
|
27290
27603
|
const prev = prevRef.current;
|
|
27291
27604
|
if (prev.centerLat !== centerLat || prev.centerLng !== centerLng || prev.zoom !== zoom) {
|
|
27292
27605
|
map.setView([centerLat, centerLng], zoom);
|
|
@@ -27297,7 +27610,7 @@ var init_MapView = __esm({
|
|
|
27297
27610
|
}
|
|
27298
27611
|
function MapClickHandler({ onMapClick }) {
|
|
27299
27612
|
const map = useMap();
|
|
27300
|
-
|
|
27613
|
+
useEffect59(() => {
|
|
27301
27614
|
if (!onMapClick) return;
|
|
27302
27615
|
const handler = (e) => {
|
|
27303
27616
|
onMapClick(e.latlng.lat, e.latlng.lng);
|
|
@@ -27325,7 +27638,7 @@ var init_MapView = __esm({
|
|
|
27325
27638
|
showAttribution = true
|
|
27326
27639
|
}) {
|
|
27327
27640
|
const eventBus = useEventBus2();
|
|
27328
|
-
const [clickedPosition, setClickedPosition] =
|
|
27641
|
+
const [clickedPosition, setClickedPosition] = useState91(null);
|
|
27329
27642
|
const handleMapClick = useCallback89((lat, lng) => {
|
|
27330
27643
|
if (showClickedPin) {
|
|
27331
27644
|
setClickedPosition({ lat, lng });
|
|
@@ -28150,6 +28463,7 @@ function TableView({
|
|
|
28150
28463
|
fields,
|
|
28151
28464
|
itemActions,
|
|
28152
28465
|
maxInlineActions,
|
|
28466
|
+
itemClickEvent,
|
|
28153
28467
|
selectable = false,
|
|
28154
28468
|
selectEvent,
|
|
28155
28469
|
selectedIds,
|
|
@@ -28194,9 +28508,9 @@ function TableView({
|
|
|
28194
28508
|
dndItemIdField,
|
|
28195
28509
|
dndRoot
|
|
28196
28510
|
});
|
|
28197
|
-
const
|
|
28198
|
-
const data = pageSize > 0 ?
|
|
28199
|
-
const hasMore = pageSize > 0 && visibleCount <
|
|
28511
|
+
const ordered2 = dnd.orderedItems;
|
|
28512
|
+
const data = pageSize > 0 ? ordered2.slice(0, visibleCount) : ordered2;
|
|
28513
|
+
const hasMore = pageSize > 0 && visibleCount < ordered2.length;
|
|
28200
28514
|
const hasRenderProp = typeof children === "function";
|
|
28201
28515
|
const idField = dndItemIdField ?? "id";
|
|
28202
28516
|
const isCoarsePointer = useMediaQuery("(pointer: coarse)");
|
|
@@ -28249,6 +28563,14 @@ function TableView({
|
|
|
28249
28563
|
};
|
|
28250
28564
|
eventBus.emit(`UI:${action.event}`, payload);
|
|
28251
28565
|
};
|
|
28566
|
+
const handleRowClick = (row) => () => {
|
|
28567
|
+
if (!itemClickEvent) return;
|
|
28568
|
+
const payload = {
|
|
28569
|
+
id: row.id,
|
|
28570
|
+
row
|
|
28571
|
+
};
|
|
28572
|
+
eventBus.emit(`UI:${itemClickEvent}`, payload);
|
|
28573
|
+
};
|
|
28252
28574
|
const colFloors = React83__namespace.default.useMemo(
|
|
28253
28575
|
() => colDefs.map((col) => {
|
|
28254
28576
|
const longest = data.reduce((widest, row) => {
|
|
@@ -28325,10 +28647,12 @@ function TableView({
|
|
|
28325
28647
|
role: "row",
|
|
28326
28648
|
"data-entity-row": true,
|
|
28327
28649
|
"data-entity-id": id,
|
|
28650
|
+
onClick: itemClickEvent ? handleRowClick(row) : void 0,
|
|
28328
28651
|
style: !hasRenderProp ? { gridTemplateColumns } : void 0,
|
|
28329
28652
|
className: cn(
|
|
28330
28653
|
"group items-center gap-3 transition-colors duration-fast",
|
|
28331
28654
|
hasRenderProp ? "flex" : "grid",
|
|
28655
|
+
itemClickEvent && "cursor-pointer",
|
|
28332
28656
|
lk.rowPad,
|
|
28333
28657
|
lk.divider && "border-b border-[var(--color-border)]",
|
|
28334
28658
|
lk.striped && index % 2 === 1 && "bg-[var(--color-surface-subtle)]",
|
|
@@ -28336,7 +28660,7 @@ function TableView({
|
|
|
28336
28660
|
look === "bordered" && "[&>*]:border-r [&>*]:border-[var(--color-border)] [&>*:last-child]:border-r-0"
|
|
28337
28661
|
),
|
|
28338
28662
|
children: [
|
|
28339
|
-
selectable && /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "flex items-center", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
28663
|
+
selectable && /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "flex items-center", onClick: itemClickEvent ? (e) => e.stopPropagation() : void 0, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
28340
28664
|
Checkbox,
|
|
28341
28665
|
{
|
|
28342
28666
|
checked: selected.has(id),
|
|
@@ -28361,6 +28685,7 @@ function TableView({
|
|
|
28361
28685
|
HStack,
|
|
28362
28686
|
{
|
|
28363
28687
|
gap: "xs",
|
|
28688
|
+
onClick: itemClickEvent ? (e) => e.stopPropagation() : void 0,
|
|
28364
28689
|
className: cn(
|
|
28365
28690
|
// Pinned: the fixed column tracks routinely overflow the caller's
|
|
28366
28691
|
// scroll container, which used to leave the actions off-screen.
|
|
@@ -28430,7 +28755,7 @@ function TableView({
|
|
|
28430
28755
|
/* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "chevron-down", size: "xs", className: "mr-1" }),
|
|
28431
28756
|
t("common.showMore"),
|
|
28432
28757
|
" (",
|
|
28433
|
-
t("common.remaining", { count:
|
|
28758
|
+
t("common.remaining", { count: ordered2.length - visibleCount }),
|
|
28434
28759
|
")"
|
|
28435
28760
|
] }) })
|
|
28436
28761
|
]
|
|
@@ -37731,6 +38056,16 @@ var init_DetailPanel = __esm({
|
|
|
37731
38056
|
DetailPanel.displayName = "DetailPanel";
|
|
37732
38057
|
}
|
|
37733
38058
|
});
|
|
38059
|
+
|
|
38060
|
+
// components/game/atoms/DrawGroup.tsx
|
|
38061
|
+
function DrawGroup(_props) {
|
|
38062
|
+
return null;
|
|
38063
|
+
}
|
|
38064
|
+
var init_DrawGroup = __esm({
|
|
38065
|
+
"components/game/atoms/DrawGroup.tsx"() {
|
|
38066
|
+
"use client";
|
|
38067
|
+
}
|
|
38068
|
+
});
|
|
37734
38069
|
function extractTitle(children) {
|
|
37735
38070
|
if (!React83__namespace.default.isValidElement(children)) return void 0;
|
|
37736
38071
|
const props = children.props;
|
|
@@ -43453,6 +43788,7 @@ var init_component_registry_generated = __esm({
|
|
|
43453
43788
|
init_DocSidebar();
|
|
43454
43789
|
init_DocTOC();
|
|
43455
43790
|
init_DocumentViewer();
|
|
43791
|
+
init_DrawGroup();
|
|
43456
43792
|
init_DrawShape();
|
|
43457
43793
|
init_DrawShapeLayer();
|
|
43458
43794
|
init_DrawSprite();
|
|
@@ -43462,6 +43798,7 @@ var init_component_registry_generated = __esm({
|
|
|
43462
43798
|
init_Drawer();
|
|
43463
43799
|
init_DrawerSlot();
|
|
43464
43800
|
init_EdgeDecoration();
|
|
43801
|
+
init_EmojiPicker();
|
|
43465
43802
|
init_EmptyState();
|
|
43466
43803
|
init_ErrorBoundary();
|
|
43467
43804
|
init_ErrorState();
|
|
@@ -43596,10 +43933,6 @@ var init_component_registry_generated = __esm({
|
|
|
43596
43933
|
init_SubagentTracePanel();
|
|
43597
43934
|
init_SvgBranch();
|
|
43598
43935
|
init_SvgConnection();
|
|
43599
|
-
init_SvgDrawGroup();
|
|
43600
|
-
init_SvgDrawShape();
|
|
43601
|
-
init_SvgDrawShapeLayer();
|
|
43602
|
-
init_SvgDrawText();
|
|
43603
43936
|
init_SvgFlow();
|
|
43604
43937
|
init_SvgGrid();
|
|
43605
43938
|
init_SvgLobe();
|
|
@@ -43610,7 +43943,6 @@ var init_component_registry_generated = __esm({
|
|
|
43610
43943
|
init_SvgRing();
|
|
43611
43944
|
init_SvgShield();
|
|
43612
43945
|
init_SvgStack();
|
|
43613
|
-
init_SvgStage();
|
|
43614
43946
|
init_SwipeableRow();
|
|
43615
43947
|
init_Switch();
|
|
43616
43948
|
init_TabbedContainer();
|
|
@@ -43724,6 +44056,7 @@ var init_component_registry_generated = __esm({
|
|
|
43724
44056
|
"DocSidebar": DocSidebar,
|
|
43725
44057
|
"DocTOC": DocTOC,
|
|
43726
44058
|
"DocumentViewer": DocumentViewer,
|
|
44059
|
+
"DrawGroup": DrawGroup,
|
|
43727
44060
|
"DrawShape": DrawShape,
|
|
43728
44061
|
"DrawShapeLayer": DrawShapeLayer,
|
|
43729
44062
|
"DrawSprite": DrawSprite,
|
|
@@ -43733,6 +44066,7 @@ var init_component_registry_generated = __esm({
|
|
|
43733
44066
|
"Drawer": Drawer,
|
|
43734
44067
|
"DrawerSlot": DrawerSlot,
|
|
43735
44068
|
"EdgeDecoration": EdgeDecoration,
|
|
44069
|
+
"EmojiPicker": EmojiPicker,
|
|
43736
44070
|
"EmptyState": EmptyState,
|
|
43737
44071
|
"ErrorBoundary": ErrorBoundary,
|
|
43738
44072
|
"ErrorState": ErrorState,
|
|
@@ -43872,10 +44206,6 @@ var init_component_registry_generated = __esm({
|
|
|
43872
44206
|
"SubagentTracePanel": SubagentTracePanel,
|
|
43873
44207
|
"SvgBranch": SvgBranch,
|
|
43874
44208
|
"SvgConnection": SvgConnection,
|
|
43875
|
-
"SvgDrawGroup": SvgDrawGroup,
|
|
43876
|
-
"SvgDrawShape": SvgDrawShape,
|
|
43877
|
-
"SvgDrawShapeLayer": SvgDrawShapeLayer,
|
|
43878
|
-
"SvgDrawText": SvgDrawText,
|
|
43879
44209
|
"SvgFlow": SvgFlow,
|
|
43880
44210
|
"SvgGrid": SvgGrid,
|
|
43881
44211
|
"SvgLobe": SvgLobe,
|
|
@@ -43886,7 +44216,6 @@ var init_component_registry_generated = __esm({
|
|
|
43886
44216
|
"SvgRing": SvgRing,
|
|
43887
44217
|
"SvgShield": SvgShield,
|
|
43888
44218
|
"SvgStack": SvgStack,
|
|
43889
|
-
"SvgStage": SvgStage,
|
|
43890
44219
|
"SwipeableRow": SwipeableRow,
|
|
43891
44220
|
"Switch": Switch,
|
|
43892
44221
|
"TabbedContainer": TabbedContainer,
|
|
@@ -44165,7 +44494,19 @@ function UISlotComponent({
|
|
|
44165
44494
|
const suspenseConfig = React83.useContext(SuspenseConfigContext);
|
|
44166
44495
|
const contained = React83.useContext(SlotContainedContext);
|
|
44167
44496
|
const schemaCtx = providers.useEntitySchemaOptional();
|
|
44168
|
-
const
|
|
44497
|
+
const rawContent = slots[slot];
|
|
44498
|
+
const binding = providers.useEntityBindingSnapshot(rawContent?.sourceTrait);
|
|
44499
|
+
const content = React83.useMemo(() => {
|
|
44500
|
+
if (!rawContent) return rawContent;
|
|
44501
|
+
const resolvedProps = resolveRenderBindingMarkers(
|
|
44502
|
+
rawContent.props,
|
|
44503
|
+
rawContent.sourceTrait,
|
|
44504
|
+
binding.entity,
|
|
44505
|
+
binding.config,
|
|
44506
|
+
binding.state
|
|
44507
|
+
);
|
|
44508
|
+
return resolvedProps === rawContent.props ? rawContent : { ...rawContent, props: resolvedProps };
|
|
44509
|
+
}, [rawContent, binding.entity, binding.config, binding.state]);
|
|
44169
44510
|
if (children !== void 0) {
|
|
44170
44511
|
if (pattern === "clear") {
|
|
44171
44512
|
return null;
|
|
@@ -44509,6 +44850,7 @@ function isPlainConfigObject(value) {
|
|
|
44509
44850
|
return proto === Object.prototype || proto === null;
|
|
44510
44851
|
}
|
|
44511
44852
|
function substituteTraitRefsDeep(value, pathKey) {
|
|
44853
|
+
if (core.isRenderBindingMarker(value)) return value;
|
|
44512
44854
|
if (typeof value === "string") {
|
|
44513
44855
|
const match = TRAIT_BINDING_RE.exec(value);
|
|
44514
44856
|
if (match) {
|
|
@@ -44581,7 +44923,14 @@ function SlotContentRenderer({
|
|
|
44581
44923
|
onDismiss,
|
|
44582
44924
|
patternPath
|
|
44583
44925
|
}) {
|
|
44584
|
-
const
|
|
44926
|
+
const ambientScope = providers.useTraitScope();
|
|
44927
|
+
const bindingTrait = content.sourceTrait ?? ambientScope?.trait;
|
|
44928
|
+
const binding = providers.useEntityBindingSnapshot(bindingTrait);
|
|
44929
|
+
const liveProps = React83.useMemo(
|
|
44930
|
+
() => resolveRenderBindingMarkers(content.props, bindingTrait, binding.entity, binding.config, binding.state),
|
|
44931
|
+
[content.props, bindingTrait, binding.entity, binding.config, binding.state]
|
|
44932
|
+
);
|
|
44933
|
+
const entityProp = liveProps.entity;
|
|
44585
44934
|
if (content.pattern === "form-section") {
|
|
44586
44935
|
slotLog.debug("SlotContentRenderer:form-section-render", {
|
|
44587
44936
|
contentId: content.id,
|
|
@@ -44612,7 +44961,7 @@ function SlotContentRenderer({
|
|
|
44612
44961
|
const orbitalName = schemaCtx && content.sourceTrait !== void 0 ? schemaCtx.orbitalsByTrait.get(content.sourceTrait) : void 0;
|
|
44613
44962
|
const PatternComponent = getComponentForPattern(content.pattern);
|
|
44614
44963
|
if (PatternComponent) {
|
|
44615
|
-
const childrenConfig =
|
|
44964
|
+
const childrenConfig = liveProps.children;
|
|
44616
44965
|
const isSingleChild = typeof childrenConfig === "string" || typeof childrenConfig === "object" && childrenConfig !== null && !Array.isArray(childrenConfig) && "type" in childrenConfig;
|
|
44617
44966
|
const hasChildren = PATTERNS_WITH_CHILDREN.has(content.pattern) || Array.isArray(childrenConfig) && childrenConfig.length > 0 || isSingleChild;
|
|
44618
44967
|
const isDrawHost = patterns.isDrawHostPattern(content.pattern);
|
|
@@ -44623,9 +44972,9 @@ function SlotContentRenderer({
|
|
|
44623
44972
|
fromState: content.fromState,
|
|
44624
44973
|
entity: content.entity
|
|
44625
44974
|
}) : void 0;
|
|
44626
|
-
const incomingChildren =
|
|
44975
|
+
const incomingChildren = liveProps.children;
|
|
44627
44976
|
const childrenIsRenderFn = typeof incomingChildren === "function";
|
|
44628
|
-
const { children: _childrenConfig, ...restPropsNoChildren } =
|
|
44977
|
+
const { children: _childrenConfig, ...restPropsNoChildren } = liveProps;
|
|
44629
44978
|
const restProps = childrenIsRenderFn ? { ...restPropsNoChildren, children: incomingChildren } : restPropsNoChildren;
|
|
44630
44979
|
const nodeSlotOverrides = {};
|
|
44631
44980
|
for (const slotKey of CONTENT_NODE_SLOTS) {
|
|
@@ -44734,7 +45083,7 @@ function SlotContentRenderer({
|
|
|
44734
45083
|
"data-orb-path": patternPath ?? "root",
|
|
44735
45084
|
"data-orb-pattern": content.pattern,
|
|
44736
45085
|
"data-orb-orbital": orbitalName,
|
|
44737
|
-
children:
|
|
45086
|
+
children: liveProps.children ?? /* @__PURE__ */ jsxRuntime.jsxs(Box, { className: "p-4 text-sm text-muted-foreground border border-dashed border-border rounded", children: [
|
|
44738
45087
|
"Unknown pattern: ",
|
|
44739
45088
|
content.pattern,
|
|
44740
45089
|
content.sourceTrait && /* @__PURE__ */ jsxRuntime.jsxs(Typography, { variant: "small", className: "ml-2", children: [
|
|
@@ -44806,6 +45155,7 @@ var scopeWrapLog, TRAIT_BINDING_RE, SuspenseConfigContext, SlotContainedContext,
|
|
|
44806
45155
|
var init_UISlotRenderer = __esm({
|
|
44807
45156
|
"components/core/organisms/UISlotRenderer.tsx"() {
|
|
44808
45157
|
"use client";
|
|
45158
|
+
init_resolve_render_bindings();
|
|
44809
45159
|
init_Modal();
|
|
44810
45160
|
init_Drawer();
|
|
44811
45161
|
init_Toast();
|
|
@@ -45052,6 +45402,9 @@ function resolveLambdaBindings(body, params, item, index) {
|
|
|
45052
45402
|
const arr = body;
|
|
45053
45403
|
const substituted = arr.map((b) => recur(b));
|
|
45054
45404
|
if (isOperatorCall(substituted) && core.isSExpr(substituted)) {
|
|
45405
|
+
if (core.containsEntityBinding(substituted)) {
|
|
45406
|
+
return substituted;
|
|
45407
|
+
}
|
|
45055
45408
|
const evaluated = evaluator.evaluate(substituted, evaluator.createMinimalContext());
|
|
45056
45409
|
return core.isEventPayloadValue(evaluated) ? evaluated : String(evaluated);
|
|
45057
45410
|
}
|
|
@@ -45073,9 +45426,37 @@ function getSlotContentRenderer2() {
|
|
|
45073
45426
|
_slotContentRenderer2 = mod.SlotContentRenderer;
|
|
45074
45427
|
return _slotContentRenderer2;
|
|
45075
45428
|
}
|
|
45429
|
+
function deferLambdaEntityExprs(value) {
|
|
45430
|
+
if (typeof value === "string") {
|
|
45431
|
+
if (core.containsEntityBinding(value)) {
|
|
45432
|
+
const marker = { [core.RENDER_BINDING_MARKER]: true, expression: value };
|
|
45433
|
+
return marker;
|
|
45434
|
+
}
|
|
45435
|
+
return value;
|
|
45436
|
+
}
|
|
45437
|
+
if (Array.isArray(value)) {
|
|
45438
|
+
if (isFnFormLambda(value)) return value;
|
|
45439
|
+
const arr = value;
|
|
45440
|
+
if (isOperatorCall(arr) && core.isSExpr(arr) && core.containsEntityBinding(arr)) {
|
|
45441
|
+
const marker = { [core.RENDER_BINDING_MARKER]: true, expression: arr };
|
|
45442
|
+
return marker;
|
|
45443
|
+
}
|
|
45444
|
+
return arr.map((v) => deferLambdaEntityExprs(v));
|
|
45445
|
+
}
|
|
45446
|
+
if (value !== null && typeof value === "object" && !React83__namespace.default.isValidElement(value) && !(value instanceof Date) && typeof value !== "function" && !core.isRenderBindingMarker(value)) {
|
|
45447
|
+
const out = {};
|
|
45448
|
+
for (const [k, v] of Object.entries(value)) {
|
|
45449
|
+
out[k] = deferLambdaEntityExprs(v);
|
|
45450
|
+
}
|
|
45451
|
+
return out;
|
|
45452
|
+
}
|
|
45453
|
+
return value;
|
|
45454
|
+
}
|
|
45076
45455
|
function makeLambdaFn(params, lambdaBody, callerKey) {
|
|
45077
45456
|
return (item, index) => {
|
|
45078
|
-
const resolvedBody =
|
|
45457
|
+
const resolvedBody = deferLambdaEntityExprs(
|
|
45458
|
+
resolveLambdaBindings(lambdaBody, params, item, index)
|
|
45459
|
+
);
|
|
45079
45460
|
if (resolvedBody === null || typeof resolvedBody !== "object" || Array.isArray(resolvedBody) || typeof resolvedBody === "function" || React83__namespace.default.isValidElement(resolvedBody) || resolvedBody instanceof Date) {
|
|
45080
45461
|
return null;
|
|
45081
45462
|
}
|
|
@@ -45100,6 +45481,7 @@ function makeLambdaFn(params, lambdaBody, callerKey) {
|
|
|
45100
45481
|
}
|
|
45101
45482
|
function convertNode(node, callerKey) {
|
|
45102
45483
|
if (node === null || node === void 0) return node;
|
|
45484
|
+
if (core.isRenderBindingMarker(node)) return node;
|
|
45103
45485
|
if (Array.isArray(node)) {
|
|
45104
45486
|
if (isFnFormLambda(node)) {
|
|
45105
45487
|
const arr2 = node;
|
|
@@ -45152,6 +45534,7 @@ var tickLog = logger.createLogger("almadar:ui:tick-effects");
|
|
|
45152
45534
|
logger.setNamespaceLevel("almadar:ui:tick-effects", "WARN");
|
|
45153
45535
|
var sharedEntityLog = logger.createLogger("almadar:ui:shared-entity");
|
|
45154
45536
|
logger.setNamespaceLevel("almadar:ui:shared-entity", "WARN");
|
|
45537
|
+
var EMPTY_BINDING_SNAPSHOT = {};
|
|
45155
45538
|
var SYNC_TICK_OPERATORS = /* @__PURE__ */ new Set([
|
|
45156
45539
|
"set",
|
|
45157
45540
|
"emit",
|
|
@@ -45172,11 +45555,6 @@ var SYNC_TICK_OPERATORS = /* @__PURE__ */ new Set([
|
|
|
45172
45555
|
"do",
|
|
45173
45556
|
"when"
|
|
45174
45557
|
]);
|
|
45175
|
-
var REACTIVE_REPAINT_PATTERN_TYPES = /* @__PURE__ */ new Set([
|
|
45176
|
-
"canvas",
|
|
45177
|
-
"game-hud",
|
|
45178
|
-
"game-shell"
|
|
45179
|
-
]);
|
|
45180
45558
|
var LIFECYCLE_EVENTS = ["INIT", "LOAD", "$MOUNT"];
|
|
45181
45559
|
function toTraitDefinition(binding) {
|
|
45182
45560
|
return {
|
|
@@ -45217,6 +45595,27 @@ function classifySharedTick(tick) {
|
|
|
45217
45595
|
if (renders) return "renderer";
|
|
45218
45596
|
return "neither";
|
|
45219
45597
|
}
|
|
45598
|
+
function buildTraitRenderConfig(binding, traitConfigsByName, payload) {
|
|
45599
|
+
const declaredDefaults = runtime.collectDeclaredConfigDefaults(binding.trait);
|
|
45600
|
+
const resolvedDefaults = traitConfigsByName?.[binding.trait.name];
|
|
45601
|
+
const callSiteConfig = getBindingConfig(binding);
|
|
45602
|
+
const callSiteOverrides = callSiteConfig ? runtime.resolveCallSitePayloadCaptures(
|
|
45603
|
+
Object.fromEntries(
|
|
45604
|
+
Object.entries(callSiteConfig).filter(
|
|
45605
|
+
([, v]) => !containsConfigForward(v)
|
|
45606
|
+
)
|
|
45607
|
+
),
|
|
45608
|
+
payload
|
|
45609
|
+
) : void 0;
|
|
45610
|
+
if (declaredDefaults || resolvedDefaults || callSiteOverrides) {
|
|
45611
|
+
return {
|
|
45612
|
+
...declaredDefaults ?? {},
|
|
45613
|
+
...resolvedDefaults ?? {},
|
|
45614
|
+
...callSiteOverrides ?? {}
|
|
45615
|
+
};
|
|
45616
|
+
}
|
|
45617
|
+
return void 0;
|
|
45618
|
+
}
|
|
45220
45619
|
function createSharedEntityWriter(binding, tick, traitStatesRef, emit) {
|
|
45221
45620
|
return (scratch) => {
|
|
45222
45621
|
const traitName = binding.trait.name;
|
|
@@ -45437,8 +45836,24 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
45437
45836
|
}, [traitStates]);
|
|
45438
45837
|
const traitSnapshotDataRef = React83.useRef(/* @__PURE__ */ new Map());
|
|
45439
45838
|
const traitFieldStatesRef = React83.useRef(/* @__PURE__ */ new Map());
|
|
45440
|
-
const
|
|
45441
|
-
const
|
|
45839
|
+
const bridgeEchoPendingRef = React83.useRef(/* @__PURE__ */ new Map());
|
|
45840
|
+
const bindingSnapshotsRef = React83.useRef(/* @__PURE__ */ new Map());
|
|
45841
|
+
const bindingListenersRef = React83.useRef(/* @__PURE__ */ new Map());
|
|
45842
|
+
const publishBindingSnapshot = React83.useCallback((traitName, row) => {
|
|
45843
|
+
bindingSnapshotsRef.current.set(traitName, { ...row });
|
|
45844
|
+
const listeners7 = bindingListenersRef.current.get(traitName);
|
|
45845
|
+
if (!listeners7) return;
|
|
45846
|
+
listeners7.forEach((callback) => {
|
|
45847
|
+
try {
|
|
45848
|
+
callback();
|
|
45849
|
+
} catch (error) {
|
|
45850
|
+
stateLog.error("binding-snapshot listener error", {
|
|
45851
|
+
traitName,
|
|
45852
|
+
error: error instanceof Error ? error.message : String(error)
|
|
45853
|
+
});
|
|
45854
|
+
}
|
|
45855
|
+
});
|
|
45856
|
+
}, []);
|
|
45442
45857
|
React83.useEffect(() => {
|
|
45443
45858
|
const mgr = managerRef.current;
|
|
45444
45859
|
const bindings = traitBindingsRef.current;
|
|
@@ -45566,15 +45981,6 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
45566
45981
|
const existing = pendingSlots.get(slot) || [];
|
|
45567
45982
|
existing.push({ pattern, props: props || {} });
|
|
45568
45983
|
pendingSlots.set(slot, existing);
|
|
45569
|
-
const patternType = pattern?.type;
|
|
45570
|
-
if (patternType !== void 0 && REACTIVE_REPAINT_PATTERN_TYPES.has(patternType)) {
|
|
45571
|
-
const rawForSlot = effects.filter(
|
|
45572
|
-
(e) => Array.isArray(e) && (e[0] === "render-ui" || e[0] === "render") && e[1] === slot
|
|
45573
|
-
);
|
|
45574
|
-
if (rawForSlot.length > 0) {
|
|
45575
|
-
lastCanvasRenderUiRef.current.set(traitName, rawForSlot);
|
|
45576
|
-
}
|
|
45577
|
-
}
|
|
45578
45984
|
},
|
|
45579
45985
|
clearSlot: (slot) => {
|
|
45580
45986
|
pendingSlots.set(slot, []);
|
|
@@ -45646,11 +46052,13 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
45646
46052
|
};
|
|
45647
46053
|
}
|
|
45648
46054
|
const sharedWrites = [];
|
|
46055
|
+
let didWrite = false;
|
|
45649
46056
|
const baseSet = handlers.set;
|
|
45650
46057
|
handlers = {
|
|
45651
46058
|
...handlers,
|
|
45652
46059
|
set: async (targetId, field, value) => {
|
|
45653
46060
|
if (baseSet) await baseSet(targetId, field, value);
|
|
46061
|
+
didWrite = true;
|
|
45654
46062
|
if (sharedKey !== void 0) {
|
|
45655
46063
|
sharedWrites.push({ field, value });
|
|
45656
46064
|
}
|
|
@@ -45667,23 +46075,9 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
45667
46075
|
payload: payload || {},
|
|
45668
46076
|
state: previousState
|
|
45669
46077
|
};
|
|
45670
|
-
const
|
|
45671
|
-
|
|
45672
|
-
|
|
45673
|
-
const callSiteOverrides = callSiteConfig ? runtime.resolveCallSitePayloadCaptures(
|
|
45674
|
-
Object.fromEntries(
|
|
45675
|
-
Object.entries(callSiteConfig).filter(
|
|
45676
|
-
([, v]) => !containsConfigForward(v)
|
|
45677
|
-
)
|
|
45678
|
-
),
|
|
45679
|
-
payload || {}
|
|
45680
|
-
) : void 0;
|
|
45681
|
-
if (declaredDefaults || resolvedDefaults || callSiteOverrides) {
|
|
45682
|
-
bindingCtx.config = {
|
|
45683
|
-
...declaredDefaults ?? {},
|
|
45684
|
-
...resolvedDefaults ?? {},
|
|
45685
|
-
...callSiteOverrides ?? {}
|
|
45686
|
-
};
|
|
46078
|
+
const renderConfig = buildTraitRenderConfig(binding, traitConfigsByName, payload || {});
|
|
46079
|
+
if (renderConfig !== void 0) {
|
|
46080
|
+
bindingCtx.config = renderConfig;
|
|
45687
46081
|
}
|
|
45688
46082
|
if (traitName === "Authority" || traitName === "Hero") {
|
|
45689
46083
|
sharedEntityLog.debug("executeTransitionEffects config tiles", {
|
|
@@ -45717,7 +46111,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
45717
46111
|
effectHeads: effects.map((e) => Array.isArray(e) ? String(e[0]) : "??")
|
|
45718
46112
|
});
|
|
45719
46113
|
}
|
|
45720
|
-
const executor = new runtime.EffectExecutor({ handlers: trackingHandlers, bindings: bindingCtx, context: effectContext });
|
|
46114
|
+
const executor = new runtime.EffectExecutor({ handlers: trackingHandlers, bindings: bindingCtx, context: effectContext, deferRenderBindings: true });
|
|
45721
46115
|
try {
|
|
45722
46116
|
await executor.executeAll(effects);
|
|
45723
46117
|
if (traitName === "Authority" || traitName === "Hero") {
|
|
@@ -45758,37 +46152,8 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
45758
46152
|
entity: binding.linkedEntity
|
|
45759
46153
|
});
|
|
45760
46154
|
}
|
|
45761
|
-
if (
|
|
45762
|
-
|
|
45763
|
-
if (stashed !== void 0 && stashed.length > 0) {
|
|
45764
|
-
await executor.executeAll(stashed);
|
|
45765
|
-
for (const [slot, patterns] of pendingSlots) {
|
|
45766
|
-
flushSlot(traitName, slot, patterns, {
|
|
45767
|
-
event: flushEvent,
|
|
45768
|
-
state: previousState,
|
|
45769
|
-
entity: binding.linkedEntity
|
|
45770
|
-
});
|
|
45771
|
-
}
|
|
45772
|
-
}
|
|
45773
|
-
if (sharedKey !== void 0 && executeTransitionEffectsRef.current !== null) {
|
|
45774
|
-
for (const sibling of traitBindingsRef.current) {
|
|
45775
|
-
const siblingName = sibling.trait.name;
|
|
45776
|
-
if (siblingName === traitName) continue;
|
|
45777
|
-
if (sharedKeyByTraitNameRef.current.get(siblingName) !== sharedKey) continue;
|
|
45778
|
-
const siblingStash = lastCanvasRenderUiRef.current.get(siblingName);
|
|
45779
|
-
if (siblingStash === void 0 || siblingStash.length === 0) continue;
|
|
45780
|
-
const siblingState = traitStatesRef.current.get(siblingName)?.currentState ?? "";
|
|
45781
|
-
await executeTransitionEffectsRef.current({
|
|
45782
|
-
binding: sibling,
|
|
45783
|
-
effects: siblingStash,
|
|
45784
|
-
previousState: siblingState,
|
|
45785
|
-
newState: siblingState,
|
|
45786
|
-
flushEvent: `${flushEvent}:repaint`,
|
|
45787
|
-
syncOnly,
|
|
45788
|
-
log: log9
|
|
45789
|
-
});
|
|
45790
|
-
}
|
|
45791
|
-
}
|
|
46155
|
+
if (didWrite && sharedKey === void 0) {
|
|
46156
|
+
publishBindingSnapshot(traitName, liveEntity);
|
|
45792
46157
|
}
|
|
45793
46158
|
} catch (error) {
|
|
45794
46159
|
log9.error("effects:error", {
|
|
@@ -45800,10 +46165,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
45800
46165
|
});
|
|
45801
46166
|
}
|
|
45802
46167
|
return emittedDuringExec;
|
|
45803
|
-
}, [eventBus, flushSlot, sharedEntityStore]);
|
|
45804
|
-
React83.useEffect(() => {
|
|
45805
|
-
executeTransitionEffectsRef.current = executeTransitionEffects;
|
|
45806
|
-
}, [executeTransitionEffects]);
|
|
46168
|
+
}, [eventBus, flushSlot, sharedEntityStore, publishBindingSnapshot]);
|
|
45807
46169
|
const runTickEffects = React83.useCallback((tick, binding) => {
|
|
45808
46170
|
const traitName = binding.trait.name;
|
|
45809
46171
|
const currentState = traitStatesRef.current.get(traitName)?.currentState ?? "";
|
|
@@ -45866,24 +46228,6 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
45866
46228
|
({ binding, tick }) => createSharedEntityWriter(binding, tick, traitStatesRef, emitFromSharedWriter)
|
|
45867
46229
|
);
|
|
45868
46230
|
runTickFrame(group.storeKey, writers, sharedEntityStore);
|
|
45869
|
-
const repaint = executeTransitionEffectsRef.current;
|
|
45870
|
-
if (repaint !== null) {
|
|
45871
|
-
for (const renderBinding of group.renderBindings) {
|
|
45872
|
-
const renderTraitName = renderBinding.trait.name;
|
|
45873
|
-
const stash = lastCanvasRenderUiRef.current.get(renderTraitName);
|
|
45874
|
-
if (stash === void 0 || stash.length === 0) continue;
|
|
45875
|
-
const renderState = traitStatesRef.current.get(renderTraitName)?.currentState ?? "";
|
|
45876
|
-
void repaint({
|
|
45877
|
-
binding: renderBinding,
|
|
45878
|
-
effects: stash,
|
|
45879
|
-
previousState: renderState,
|
|
45880
|
-
newState: renderState,
|
|
45881
|
-
flushEvent: "tick:repaint",
|
|
45882
|
-
syncOnly: true,
|
|
45883
|
-
log: sharedEntityLog
|
|
45884
|
-
});
|
|
45885
|
-
}
|
|
45886
|
-
}
|
|
45887
46231
|
};
|
|
45888
46232
|
if (interval === "frame") {
|
|
45889
46233
|
scheduler.add(0, onDue);
|
|
@@ -45954,6 +46298,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
45954
46298
|
executedTraits: results.map((r) => r.traitName).join(",")
|
|
45955
46299
|
});
|
|
45956
46300
|
const emittedByTrait = /* @__PURE__ */ new Map();
|
|
46301
|
+
bridgeEchoPendingRef.current.clear();
|
|
45957
46302
|
for (const { traitName, result } of results) {
|
|
45958
46303
|
const binding = bindingMap.get(traitName);
|
|
45959
46304
|
const traitState = currentManager.getState(traitName);
|
|
@@ -46008,6 +46353,12 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
46008
46353
|
log: stateLog
|
|
46009
46354
|
});
|
|
46010
46355
|
emittedByTrait.set(traitName, emittedDuringExec);
|
|
46356
|
+
for (const emittedKey of emittedDuringExec) {
|
|
46357
|
+
bridgeEchoPendingRef.current.set(
|
|
46358
|
+
emittedKey,
|
|
46359
|
+
(bridgeEchoPendingRef.current.get(emittedKey) ?? 0) + 1
|
|
46360
|
+
);
|
|
46361
|
+
}
|
|
46011
46362
|
} else if (!result.executed) {
|
|
46012
46363
|
if (result.guardResult === false) {
|
|
46013
46364
|
stateLog.debug("guard-blocked-transition", {
|
|
@@ -46157,8 +46508,13 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
46157
46508
|
crossTraitLog.debug("self:subscribe", { traitName, busKey: selfBusKey, eventKey });
|
|
46158
46509
|
const unsub = eventBus.on(selfBusKey, (event) => {
|
|
46159
46510
|
if (event.source && event.source.dispatched) {
|
|
46160
|
-
|
|
46161
|
-
|
|
46511
|
+
const pendingEchoes = bridgeEchoPendingRef.current.get(eventKey) ?? 0;
|
|
46512
|
+
if (pendingEchoes > 0) {
|
|
46513
|
+
bridgeEchoPendingRef.current.set(eventKey, pendingEchoes - 1);
|
|
46514
|
+
crossTraitLog.debug("self:fire-skipped-bridge-echo", { traitName, busKey: selfBusKey, eventKey });
|
|
46515
|
+
return;
|
|
46516
|
+
}
|
|
46517
|
+
crossTraitLog.debug("self:fire-server-cascade", { traitName, busKey: selfBusKey, eventKey });
|
|
46162
46518
|
}
|
|
46163
46519
|
crossTraitLog.debug("self:fire", { traitName, busKey: selfBusKey, eventKey });
|
|
46164
46520
|
enqueueAndDrain(eventKey, event.payload, traitName);
|
|
@@ -46250,11 +46606,47 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
46250
46606
|
initedTraitsRef.current = /* @__PURE__ */ new Set();
|
|
46251
46607
|
};
|
|
46252
46608
|
}, [traitBindings, enqueueAndDrain]);
|
|
46609
|
+
const entityBindingSource = React83.useMemo(() => ({
|
|
46610
|
+
getEntitySnapshot: (traitName) => {
|
|
46611
|
+
const sharedKey = sharedKeyByTraitNameRef.current.get(traitName);
|
|
46612
|
+
if (sharedKey !== void 0) {
|
|
46613
|
+
return sharedEntityStore.getSnapshot(sharedKey);
|
|
46614
|
+
}
|
|
46615
|
+
return bindingSnapshotsRef.current.get(traitName) ?? EMPTY_BINDING_SNAPSHOT;
|
|
46616
|
+
},
|
|
46617
|
+
getConfig: (traitName) => {
|
|
46618
|
+
const binding = traitBindingsRef.current.find((b) => b.trait.name === traitName);
|
|
46619
|
+
if (binding === void 0) return void 0;
|
|
46620
|
+
return buildTraitRenderConfig(binding, traitConfigsByName, {});
|
|
46621
|
+
},
|
|
46622
|
+
getState: (traitName) => traitStatesRef.current.get(traitName)?.currentState ?? "",
|
|
46623
|
+
subscribe: (traitName, callback) => {
|
|
46624
|
+
const sharedKey = sharedKeyByTraitNameRef.current.get(traitName);
|
|
46625
|
+
if (sharedKey !== void 0) {
|
|
46626
|
+
return sharedEntityStore.subscribe(sharedKey, callback);
|
|
46627
|
+
}
|
|
46628
|
+
let listeners7 = bindingListenersRef.current.get(traitName);
|
|
46629
|
+
if (!listeners7) {
|
|
46630
|
+
listeners7 = /* @__PURE__ */ new Set();
|
|
46631
|
+
bindingListenersRef.current.set(traitName, listeners7);
|
|
46632
|
+
}
|
|
46633
|
+
listeners7.add(callback);
|
|
46634
|
+
return () => {
|
|
46635
|
+
const current = bindingListenersRef.current.get(traitName);
|
|
46636
|
+
if (!current) return;
|
|
46637
|
+
current.delete(callback);
|
|
46638
|
+
if (current.size === 0) {
|
|
46639
|
+
bindingListenersRef.current.delete(traitName);
|
|
46640
|
+
}
|
|
46641
|
+
};
|
|
46642
|
+
}
|
|
46643
|
+
}), [sharedEntityStore, traitConfigsByName]);
|
|
46253
46644
|
return {
|
|
46254
46645
|
traitStates,
|
|
46255
46646
|
sendEvent,
|
|
46256
46647
|
getTraitState,
|
|
46257
|
-
canHandleEvent
|
|
46648
|
+
canHandleEvent,
|
|
46649
|
+
entityBindingSource
|
|
46258
46650
|
};
|
|
46259
46651
|
}
|
|
46260
46652
|
var resolvedSchemaLog = logger.createLogger("almadar:ui:resolved-schema");
|
|
@@ -46446,7 +46838,7 @@ function collectServerActiveTraits(ir, allTraits, mountedTraitNames) {
|
|
|
46446
46838
|
}
|
|
46447
46839
|
return active;
|
|
46448
46840
|
}
|
|
46449
|
-
function TraitInitializer({ traits: traits2, routeParams, orbitalNames, onNavigate, onLocalFallback, persistence, traitConfigsByName, orbitalsByTrait, embeddedTraits, serverActiveTraits }) {
|
|
46841
|
+
function TraitInitializer({ traits: traits2, routeParams, orbitalNames, onNavigate, onLocalFallback, persistence, traitConfigsByName, orbitalsByTrait, embeddedTraits, serverActiveTraits, children }) {
|
|
46450
46842
|
const bridge = providers.useServerBridge();
|
|
46451
46843
|
const activeTraitNames = React83.useMemo(
|
|
46452
46844
|
() => new Set(traits2.map((b) => b.trait.name).filter((n) => !!n)),
|
|
@@ -46476,7 +46868,7 @@ function TraitInitializer({ traits: traits2, routeParams, orbitalNames, onNaviga
|
|
|
46476
46868
|
}
|
|
46477
46869
|
}, [bridge.connected, bridge.sendEvent, orbitalNames, uiSlots, onNavigate, embeddedTraits, activeTraitNames, withActiveTraits]);
|
|
46478
46870
|
const opts = orbitalNames ? { onEventProcessed, navigate: onNavigate, traitConfigsByName, orbitalsByTrait, embeddedTraits, initPayload: routeParams } : { navigate: onNavigate, persistence, traitConfigsByName, orbitalsByTrait, embeddedTraits, initPayload: routeParams };
|
|
46479
|
-
const { sendEvent } = useTraitStateMachine(traits2, uiSlots, opts);
|
|
46871
|
+
const { sendEvent, entityBindingSource } = useTraitStateMachine(traits2, uiSlots, opts);
|
|
46480
46872
|
const initSentRef = React83.useRef(false);
|
|
46481
46873
|
const prevTraitsRef = React83.useRef(void 0);
|
|
46482
46874
|
const paramsKey = JSON.stringify(routeParams ?? {});
|
|
@@ -46522,7 +46914,7 @@ function TraitInitializer({ traits: traits2, routeParams, orbitalNames, onNaviga
|
|
|
46522
46914
|
{ type: "fetch", args: [], status: "executed" },
|
|
46523
46915
|
...effects.map((eff) => ({
|
|
46524
46916
|
type: eff.type,
|
|
46525
|
-
args: eff.type === "render-ui" ? [eff.slot] : [],
|
|
46917
|
+
args: eff.type === "render-ui" && eff.slot !== void 0 ? [eff.slot] : [],
|
|
46526
46918
|
status: "executed"
|
|
46527
46919
|
}))
|
|
46528
46920
|
];
|
|
@@ -46538,7 +46930,7 @@ function TraitInitializer({ traits: traits2, routeParams, orbitalNames, onNaviga
|
|
|
46538
46930
|
}
|
|
46539
46931
|
})();
|
|
46540
46932
|
}, [bridge.connected, orbitalNames, bridge.sendEvent, uiSlots, onNavigate, embeddedTraits, activeTraitNames, withActiveTraits, routeParams]);
|
|
46541
|
-
return
|
|
46933
|
+
return /* @__PURE__ */ jsxRuntime.jsx(providers.EntityBindingContext.Provider, { value: entityBindingSource, children });
|
|
46542
46934
|
}
|
|
46543
46935
|
function SchemaRunner({ schema, serverUrl, transport, mockData, pageName, routeParams, onNavigate, onLocalFallback, persistence }) {
|
|
46544
46936
|
const { traits: traits2, allEntities, allTraits, ir } = useResolvedSchema(schema, pageName);
|
|
@@ -46671,30 +47063,28 @@ function SchemaRunner({ schema, serverUrl, transport, mockData, pageName, routeP
|
|
|
46671
47063
|
}
|
|
46672
47064
|
return schema.orbitals[0]?.theme;
|
|
46673
47065
|
}, [schema, pageName]);
|
|
46674
|
-
const inner = /* @__PURE__ */ jsxRuntime.jsx(providers.VerificationProvider, { enabled: true, children: /* @__PURE__ */ jsxRuntime.
|
|
47066
|
+
const inner = /* @__PURE__ */ jsxRuntime.jsx(providers.VerificationProvider, { enabled: true, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
46675
47067
|
providers.EntitySchemaProvider,
|
|
46676
47068
|
{
|
|
46677
47069
|
entities: entitiesArray,
|
|
46678
47070
|
traitLinkedEntities: traitLinkedEntitiesMap,
|
|
46679
47071
|
orbitalsByTrait: orbitalsByTraitMap,
|
|
46680
|
-
children:
|
|
46681
|
-
|
|
46682
|
-
|
|
46683
|
-
|
|
46684
|
-
|
|
46685
|
-
|
|
46686
|
-
|
|
46687
|
-
|
|
46688
|
-
|
|
46689
|
-
|
|
46690
|
-
|
|
46691
|
-
|
|
46692
|
-
|
|
46693
|
-
|
|
46694
|
-
|
|
46695
|
-
|
|
46696
|
-
/* @__PURE__ */ jsxRuntime.jsx(providers.OrbitalThemeProvider, { theme: activeOrbitalTheme, children: /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "h-full min-h-full overflow-auto p-4", children: /* @__PURE__ */ jsxRuntime.jsx(UISlotRenderer, { includeHud: true, hudMode: "inline", includeFloating: true }) }) })
|
|
46697
|
-
]
|
|
47072
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
47073
|
+
TraitInitializer,
|
|
47074
|
+
{
|
|
47075
|
+
traits: allPageTraits,
|
|
47076
|
+
routeParams,
|
|
47077
|
+
orbitalNames: serverUrl || transport ? pageOrbitalNames : void 0,
|
|
47078
|
+
traitConfigsByName,
|
|
47079
|
+
orbitalsByTrait,
|
|
47080
|
+
embeddedTraits,
|
|
47081
|
+
serverActiveTraits,
|
|
47082
|
+
onNavigate,
|
|
47083
|
+
onLocalFallback,
|
|
47084
|
+
persistence,
|
|
47085
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(providers.OrbitalThemeProvider, { theme: activeOrbitalTheme, children: /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "h-full min-h-full overflow-auto p-4", children: /* @__PURE__ */ jsxRuntime.jsx(UISlotRenderer, { includeHud: true, hudMode: "inline", includeFloating: true }) }) })
|
|
47086
|
+
}
|
|
47087
|
+
)
|
|
46698
47088
|
}
|
|
46699
47089
|
) });
|
|
46700
47090
|
if (serverUrl || transport) {
|