@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/avl/index.cjs
CHANGED
|
@@ -7,6 +7,8 @@ var logger = require('@almadar/logger');
|
|
|
7
7
|
var ELK = require('elkjs/lib/elk.bundled.js');
|
|
8
8
|
var react = require('@xyflow/react');
|
|
9
9
|
var hooks = require('@almadar/ui/hooks');
|
|
10
|
+
var runtime = require('@almadar/runtime');
|
|
11
|
+
var core = require('@almadar/core');
|
|
10
12
|
var LucideIcons2 = require('lucide-react');
|
|
11
13
|
var reactDom = require('react-dom');
|
|
12
14
|
var context = require('@almadar/ui/context');
|
|
@@ -66,15 +68,14 @@ var ReactMarkdown = require('react-markdown');
|
|
|
66
68
|
var remarkGfm = require('remark-gfm');
|
|
67
69
|
var remarkMath = require('remark-math');
|
|
68
70
|
var rehypeKatex = require('rehype-katex');
|
|
69
|
-
var core = require('@almadar/core');
|
|
70
71
|
var core$1 = require('@dnd-kit/core');
|
|
71
72
|
var sortable = require('@dnd-kit/sortable');
|
|
72
73
|
var utilities = require('@dnd-kit/utilities');
|
|
74
|
+
var emojilib = require('emojilib');
|
|
73
75
|
var d3Force = require('d3-force');
|
|
74
76
|
var patterns = require('@almadar/core/patterns');
|
|
75
77
|
var OrbitalServerRuntime = require('@almadar/runtime/OrbitalServerRuntime');
|
|
76
78
|
var registry = require('@almadar/std/registry');
|
|
77
|
-
var runtime = require('@almadar/runtime');
|
|
78
79
|
|
|
79
80
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
80
81
|
|
|
@@ -3238,6 +3239,32 @@ function formatValue(value, format) {
|
|
|
3238
3239
|
return String(value);
|
|
3239
3240
|
}
|
|
3240
3241
|
}
|
|
3242
|
+
function compareCellValues(a, b) {
|
|
3243
|
+
const aEmpty = a === null || a === void 0 || a === "";
|
|
3244
|
+
const bEmpty = b === null || b === void 0 || b === "";
|
|
3245
|
+
if (aEmpty || bEmpty) return aEmpty && bEmpty ? 0 : aEmpty ? 1 : -1;
|
|
3246
|
+
if (typeof a === "number" && typeof b === "number") return a - b;
|
|
3247
|
+
if (typeof a === "boolean" && typeof b === "boolean") return Number(a) - Number(b);
|
|
3248
|
+
const aNum = Number(a);
|
|
3249
|
+
const bNum = Number(b);
|
|
3250
|
+
if (Number.isFinite(aNum) && Number.isFinite(bNum)) return aNum - bNum;
|
|
3251
|
+
const aTime = dateLikeTime(a);
|
|
3252
|
+
const bTime = dateLikeTime(b);
|
|
3253
|
+
if (aTime !== null && bTime !== null) return aTime - bTime;
|
|
3254
|
+
return String(a).localeCompare(String(b));
|
|
3255
|
+
}
|
|
3256
|
+
function dateLikeTime(value) {
|
|
3257
|
+
if (value instanceof Date) return value.getTime();
|
|
3258
|
+
const text = String(value);
|
|
3259
|
+
if (!/\d/.test(text) || !/[-/:T]/.test(text)) return null;
|
|
3260
|
+
const time = Date.parse(text);
|
|
3261
|
+
return Number.isNaN(time) ? null : time;
|
|
3262
|
+
}
|
|
3263
|
+
function sortRows(rows, field, direction = "asc") {
|
|
3264
|
+
if (!field) return rows;
|
|
3265
|
+
const dir = direction === "desc" ? -1 : 1;
|
|
3266
|
+
return [...rows].sort((a, b) => dir * compareCellValues(a?.[field], b?.[field]));
|
|
3267
|
+
}
|
|
3241
3268
|
var init_format = __esm({
|
|
3242
3269
|
"lib/format.ts"() {
|
|
3243
3270
|
}
|
|
@@ -4620,6 +4647,75 @@ var init_BehaviorView = __esm({
|
|
|
4620
4647
|
exports.BehaviorView.displayName = "BehaviorView";
|
|
4621
4648
|
}
|
|
4622
4649
|
});
|
|
4650
|
+
function resolveMarkerExpression(expression, entity, config, state) {
|
|
4651
|
+
const ctx = runtime.createContextFromBindings({
|
|
4652
|
+
entity,
|
|
4653
|
+
payload: {},
|
|
4654
|
+
state,
|
|
4655
|
+
...config !== void 0 ? { config } : {}
|
|
4656
|
+
});
|
|
4657
|
+
return runtime.interpolateValue(expression, ctx);
|
|
4658
|
+
}
|
|
4659
|
+
function isPlainObject(value) {
|
|
4660
|
+
if (value === null || value === void 0 || typeof value !== "object") return false;
|
|
4661
|
+
if (Array.isArray(value)) return false;
|
|
4662
|
+
if (React92__namespace.default.isValidElement(value)) return false;
|
|
4663
|
+
if (value instanceof Date) return false;
|
|
4664
|
+
if (typeof value === "function") return false;
|
|
4665
|
+
return true;
|
|
4666
|
+
}
|
|
4667
|
+
function walkValue(value, scopeTrait, entity, config, state) {
|
|
4668
|
+
if (core.isRenderBindingMarker(value)) {
|
|
4669
|
+
return { resolved: resolveMarkerExpression(value.expression, entity, config, state), changed: true };
|
|
4670
|
+
}
|
|
4671
|
+
if (Array.isArray(value)) {
|
|
4672
|
+
const out = [];
|
|
4673
|
+
let changed = false;
|
|
4674
|
+
for (const item of value) {
|
|
4675
|
+
const element = item;
|
|
4676
|
+
const wasMarker = core.isRenderBindingMarker(element);
|
|
4677
|
+
const { resolved, changed: itemChanged } = walkValue(element, scopeTrait, entity, config, state);
|
|
4678
|
+
if (wasMarker && Array.isArray(resolved)) {
|
|
4679
|
+
out.push(...resolved);
|
|
4680
|
+
changed = true;
|
|
4681
|
+
continue;
|
|
4682
|
+
}
|
|
4683
|
+
out.push(resolved);
|
|
4684
|
+
if (itemChanged) changed = true;
|
|
4685
|
+
}
|
|
4686
|
+
return changed ? { resolved: out, changed: true } : { resolved: value, changed: false };
|
|
4687
|
+
}
|
|
4688
|
+
if (isPlainObject(value)) {
|
|
4689
|
+
const sourceTrait = value._sourceTrait;
|
|
4690
|
+
if (typeof sourceTrait === "string" && sourceTrait !== scopeTrait) {
|
|
4691
|
+
return { resolved: value, changed: false };
|
|
4692
|
+
}
|
|
4693
|
+
const out = {};
|
|
4694
|
+
let changed = false;
|
|
4695
|
+
for (const [key, item] of Object.entries(value)) {
|
|
4696
|
+
const { resolved, changed: itemChanged } = walkValue(item, scopeTrait, entity, config, state);
|
|
4697
|
+
out[key] = resolved;
|
|
4698
|
+
if (itemChanged) changed = true;
|
|
4699
|
+
}
|
|
4700
|
+
return changed ? { resolved: out, changed: true } : { resolved: value, changed: false };
|
|
4701
|
+
}
|
|
4702
|
+
return { resolved: value, changed: false };
|
|
4703
|
+
}
|
|
4704
|
+
function resolveRenderBindingMarkers(props, scopeTrait, entity, config, state) {
|
|
4705
|
+
const out = {};
|
|
4706
|
+
let changed = false;
|
|
4707
|
+
for (const [key, value] of Object.entries(props)) {
|
|
4708
|
+
const { resolved, changed: propChanged } = walkValue(value, scopeTrait, entity, config, state);
|
|
4709
|
+
out[key] = resolved;
|
|
4710
|
+
if (propChanged) changed = true;
|
|
4711
|
+
}
|
|
4712
|
+
return changed ? out : props;
|
|
4713
|
+
}
|
|
4714
|
+
var init_resolve_render_bindings = __esm({
|
|
4715
|
+
"lib/resolve-render-bindings.ts"() {
|
|
4716
|
+
"use client";
|
|
4717
|
+
}
|
|
4718
|
+
});
|
|
4623
4719
|
function getCurrentIconFamily() {
|
|
4624
4720
|
if (typeof window === "undefined" || typeof document === "undefined") {
|
|
4625
4721
|
return DEFAULT_FAMILY;
|
|
@@ -4862,9 +4958,13 @@ function getAtlas(url, onReady) {
|
|
|
4862
4958
|
onReady();
|
|
4863
4959
|
}).catch(() => {
|
|
4864
4960
|
atlasCache.set(url, null);
|
|
4961
|
+
onReady();
|
|
4865
4962
|
});
|
|
4866
4963
|
return void 0;
|
|
4867
4964
|
}
|
|
4965
|
+
function atlasFailed(url) {
|
|
4966
|
+
return atlasCache.get(url) === null;
|
|
4967
|
+
}
|
|
4868
4968
|
function subRectFor(atlas, sprite) {
|
|
4869
4969
|
if (isTilesheet(atlas)) {
|
|
4870
4970
|
let col;
|
|
@@ -6922,6 +7022,20 @@ var init_Input = __esm({
|
|
|
6922
7022
|
const { t } = hooks.useTranslate();
|
|
6923
7023
|
const eventBus = useEventBus();
|
|
6924
7024
|
const type = inputType || htmlType || "text";
|
|
7025
|
+
const isDeclarative = typeof onChange === "string";
|
|
7026
|
+
const [localValue, setLocalValue] = React92__namespace.default.useState(value);
|
|
7027
|
+
const pendingEchoRef = React92__namespace.default.useRef(/* @__PURE__ */ new Set());
|
|
7028
|
+
React92__namespace.default.useEffect(() => {
|
|
7029
|
+
if (!isDeclarative) return;
|
|
7030
|
+
const incoming = value == null ? "" : String(value);
|
|
7031
|
+
if (pendingEchoRef.current.has(incoming)) {
|
|
7032
|
+
pendingEchoRef.current.delete(incoming);
|
|
7033
|
+
return;
|
|
7034
|
+
}
|
|
7035
|
+
pendingEchoRef.current.clear();
|
|
7036
|
+
setLocalValue(value);
|
|
7037
|
+
}, [value, isDeclarative]);
|
|
7038
|
+
const displayValue = isDeclarative ? localValue : value;
|
|
6925
7039
|
const resolveIconNode = (i, cls) => {
|
|
6926
7040
|
if (!i) return null;
|
|
6927
7041
|
if (typeof i === "string") return /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: i, className: cls });
|
|
@@ -6931,7 +7045,7 @@ var init_Input = __esm({
|
|
|
6931
7045
|
const iconCls = "h-icon-default w-icon-default";
|
|
6932
7046
|
const IconComponent = typeof iconProp === "string" ? resolveIcon(iconProp) : iconProp;
|
|
6933
7047
|
const resolvedLeftIcon = (leftIcon ? resolveIconNode(leftIcon, iconCls) : null) || IconComponent && /* @__PURE__ */ jsxRuntime.jsx(IconComponent, { className: iconCls });
|
|
6934
|
-
const showClearButton = clearable &&
|
|
7048
|
+
const showClearButton = clearable && displayValue && String(displayValue).length > 0;
|
|
6935
7049
|
const isMultiline = type === "textarea";
|
|
6936
7050
|
const baseClassName = cn(
|
|
6937
7051
|
"block w-full rounded-sm transition-all duration-fast",
|
|
@@ -6950,6 +7064,10 @@ var init_Input = __esm({
|
|
|
6950
7064
|
if (typeof onChange === "string") {
|
|
6951
7065
|
const target = e.target;
|
|
6952
7066
|
const payload = type === "checkbox" ? { checked: target.checked } : { value: target.value };
|
|
7067
|
+
if (type !== "checkbox") {
|
|
7068
|
+
pendingEchoRef.current.add(target.value);
|
|
7069
|
+
setLocalValue(target.value);
|
|
7070
|
+
}
|
|
6953
7071
|
eventBus.emit(`UI:${onChange}`, payload);
|
|
6954
7072
|
} else {
|
|
6955
7073
|
onChange?.(e);
|
|
@@ -6980,7 +7098,7 @@ var init_Input = __esm({
|
|
|
6980
7098
|
"select",
|
|
6981
7099
|
{
|
|
6982
7100
|
ref,
|
|
6983
|
-
value,
|
|
7101
|
+
value: displayValue,
|
|
6984
7102
|
onChange: handleChange,
|
|
6985
7103
|
className: cn(baseClassName, "appearance-none pr-10", className),
|
|
6986
7104
|
...props,
|
|
@@ -7000,7 +7118,7 @@ var init_Input = __esm({
|
|
|
7000
7118
|
"textarea",
|
|
7001
7119
|
{
|
|
7002
7120
|
ref,
|
|
7003
|
-
value,
|
|
7121
|
+
value: displayValue,
|
|
7004
7122
|
onChange: handleChange,
|
|
7005
7123
|
rows,
|
|
7006
7124
|
className: baseClassName,
|
|
@@ -7039,7 +7157,7 @@ var init_Input = __esm({
|
|
|
7039
7157
|
{
|
|
7040
7158
|
ref,
|
|
7041
7159
|
type,
|
|
7042
|
-
value,
|
|
7160
|
+
value: displayValue,
|
|
7043
7161
|
onChange: handleChange,
|
|
7044
7162
|
onKeyDown: handleKeyDown,
|
|
7045
7163
|
className: baseClassName,
|
|
@@ -10876,46 +10994,45 @@ var init_useImageCache = __esm({
|
|
|
10876
10994
|
});
|
|
10877
10995
|
|
|
10878
10996
|
// lib/isometric.ts
|
|
10879
|
-
function isoToScreen(tileX, tileY,
|
|
10880
|
-
const
|
|
10881
|
-
const
|
|
10997
|
+
function isoToScreen(tileX, tileY, cellWidth, baseOffsetX, layout = "isometric") {
|
|
10998
|
+
const w = cellWidth;
|
|
10999
|
+
const fh = cellWidth / 2;
|
|
10882
11000
|
if (layout === "hex") {
|
|
10883
|
-
const screenX2 = tileX *
|
|
10884
|
-
const screenY2 = tileY * (
|
|
11001
|
+
const screenX2 = tileX * w + (tileY & 1) * (w / 2) + baseOffsetX;
|
|
11002
|
+
const screenY2 = tileY * (fh * 0.75);
|
|
10885
11003
|
return { x: screenX2, y: screenY2 };
|
|
10886
11004
|
}
|
|
10887
11005
|
if (layout === "flat") {
|
|
10888
|
-
const screenX2 = tileX *
|
|
10889
|
-
const screenY2 = tileY *
|
|
11006
|
+
const screenX2 = tileX * w + baseOffsetX;
|
|
11007
|
+
const screenY2 = tileY * w;
|
|
10890
11008
|
return { x: screenX2, y: screenY2 };
|
|
10891
11009
|
}
|
|
10892
|
-
const screenX = (tileX - tileY) * (
|
|
10893
|
-
const screenY = (tileX + tileY) * (
|
|
11010
|
+
const screenX = (tileX - tileY) * (w / 2) + baseOffsetX;
|
|
11011
|
+
const screenY = (tileX + tileY) * (fh / 2);
|
|
10894
11012
|
return { x: screenX, y: screenY };
|
|
10895
11013
|
}
|
|
10896
|
-
function screenToIso(screenX, screenY,
|
|
10897
|
-
const
|
|
10898
|
-
const
|
|
11014
|
+
function screenToIso(screenX, screenY, cellWidth, baseOffsetX, layout = "isometric") {
|
|
11015
|
+
const w = cellWidth;
|
|
11016
|
+
const fh = cellWidth / 2;
|
|
10899
11017
|
if (layout === "hex") {
|
|
10900
|
-
const row = Math.round(screenY / (
|
|
10901
|
-
const col = Math.round((screenX - (row & 1) * (
|
|
11018
|
+
const row = Math.round(screenY / (fh * 0.75));
|
|
11019
|
+
const col = Math.round((screenX - (row & 1) * (w / 2) - baseOffsetX) / w);
|
|
10902
11020
|
return { x: col, y: row };
|
|
10903
11021
|
}
|
|
10904
11022
|
if (layout === "flat") {
|
|
10905
|
-
const col = Math.round((screenX - baseOffsetX) /
|
|
10906
|
-
const row = Math.round(screenY /
|
|
11023
|
+
const col = Math.round((screenX - baseOffsetX) / w);
|
|
11024
|
+
const row = Math.round(screenY / w);
|
|
10907
11025
|
return { x: col, y: row };
|
|
10908
11026
|
}
|
|
10909
11027
|
const adjustedX = screenX - baseOffsetX;
|
|
10910
|
-
const tileX = (adjustedX / (
|
|
10911
|
-
const tileY = (screenY / (
|
|
11028
|
+
const tileX = (adjustedX / (w / 2) + screenY / (fh / 2)) / 2;
|
|
11029
|
+
const tileY = (screenY / (fh / 2) - adjustedX / (w / 2)) / 2;
|
|
10912
11030
|
return { x: Math.round(tileX), y: Math.round(tileY) };
|
|
10913
11031
|
}
|
|
10914
|
-
var TILE_WIDTH,
|
|
11032
|
+
var TILE_WIDTH, DIAMOND_TOP_Y, BACKGROUND_FALLBACK_COLOR, MINIMAP_TERRAIN_COLORS;
|
|
10915
11033
|
var init_isometric = __esm({
|
|
10916
11034
|
"lib/isometric.ts"() {
|
|
10917
11035
|
TILE_WIDTH = 256;
|
|
10918
|
-
FLOOR_HEIGHT = 128;
|
|
10919
11036
|
DIAMOND_TOP_Y = 374;
|
|
10920
11037
|
BACKGROUND_FALLBACK_COLOR = "#1a1a2e";
|
|
10921
11038
|
MINIMAP_TERRAIN_COLORS = {
|
|
@@ -11400,210 +11517,6 @@ var init_ChoiceButton = __esm({
|
|
|
11400
11517
|
ChoiceButton.displayName = "ChoiceButton";
|
|
11401
11518
|
}
|
|
11402
11519
|
});
|
|
11403
|
-
function SvgStage({
|
|
11404
|
-
cols,
|
|
11405
|
-
rows,
|
|
11406
|
-
tileSize = 32,
|
|
11407
|
-
background = "var(--color-background)",
|
|
11408
|
-
tileClickEvent,
|
|
11409
|
-
tileHoverEvent,
|
|
11410
|
-
tileLeaveEvent,
|
|
11411
|
-
keyMap,
|
|
11412
|
-
keyUpMap,
|
|
11413
|
-
className,
|
|
11414
|
-
children
|
|
11415
|
-
}) {
|
|
11416
|
-
const eventBus = useEventBus();
|
|
11417
|
-
const svgRef = React92.useRef(null);
|
|
11418
|
-
const pointerDownRef = React92.useRef(null);
|
|
11419
|
-
const cellFromClient = React92.useCallback((clientX, clientY) => {
|
|
11420
|
-
const svg = svgRef.current;
|
|
11421
|
-
if (!svg) return null;
|
|
11422
|
-
const rect = svg.getBoundingClientRect();
|
|
11423
|
-
if (rect.width === 0 || rect.height === 0) return null;
|
|
11424
|
-
const vbW = cols * tileSize;
|
|
11425
|
-
const vbH = rows * tileSize;
|
|
11426
|
-
const meet = Math.min(rect.width / vbW, rect.height / vbH);
|
|
11427
|
-
const offsetX = (rect.width - vbW * meet) / 2;
|
|
11428
|
-
const offsetY = (rect.height - vbH * meet) / 2;
|
|
11429
|
-
const svgX = (clientX - rect.left - offsetX) / meet;
|
|
11430
|
-
const svgY = (clientY - rect.top - offsetY) / meet;
|
|
11431
|
-
return {
|
|
11432
|
-
x: Math.min(Math.max(Math.floor(svgX / tileSize), 0), cols - 1),
|
|
11433
|
-
y: Math.min(Math.max(Math.floor(svgY / tileSize), 0), rows - 1)
|
|
11434
|
-
};
|
|
11435
|
-
}, [cols, rows, tileSize]);
|
|
11436
|
-
const handlePointerDown = React92.useCallback((e) => {
|
|
11437
|
-
pointerDownRef.current = { clientX: e.clientX, clientY: e.clientY };
|
|
11438
|
-
}, []);
|
|
11439
|
-
const handlePointerUp = React92.useCallback((e) => {
|
|
11440
|
-
const down = pointerDownRef.current;
|
|
11441
|
-
pointerDownRef.current = null;
|
|
11442
|
-
if (!tileClickEvent) return;
|
|
11443
|
-
if (down && Math.hypot(e.clientX - down.clientX, e.clientY - down.clientY) > 5) return;
|
|
11444
|
-
const cell = cellFromClient(e.clientX, e.clientY);
|
|
11445
|
-
if (cell) eventBus.emit(`UI:${tileClickEvent}`, cell);
|
|
11446
|
-
}, [cellFromClient, tileClickEvent, eventBus]);
|
|
11447
|
-
const handlePointerMove = React92.useCallback((e) => {
|
|
11448
|
-
if (!tileHoverEvent) return;
|
|
11449
|
-
const cell = cellFromClient(e.clientX, e.clientY);
|
|
11450
|
-
if (cell) eventBus.emit(`UI:${tileHoverEvent}`, cell);
|
|
11451
|
-
}, [cellFromClient, tileHoverEvent, eventBus]);
|
|
11452
|
-
const handlePointerLeave = React92.useCallback(() => {
|
|
11453
|
-
pointerDownRef.current = null;
|
|
11454
|
-
if (tileLeaveEvent) eventBus.emit(`UI:${tileLeaveEvent}`, {});
|
|
11455
|
-
}, [tileLeaveEvent, eventBus]);
|
|
11456
|
-
React92.useEffect(() => {
|
|
11457
|
-
if (!keyMap && !keyUpMap) return;
|
|
11458
|
-
const onDown = (e) => {
|
|
11459
|
-
const ev = keyMap?.[e.code];
|
|
11460
|
-
if (ev) {
|
|
11461
|
-
eventBus.emit(`UI:${ev}`, {});
|
|
11462
|
-
e.preventDefault();
|
|
11463
|
-
}
|
|
11464
|
-
};
|
|
11465
|
-
const onUp = (e) => {
|
|
11466
|
-
const ev = keyUpMap?.[e.code];
|
|
11467
|
-
if (ev) eventBus.emit(`UI:${ev}`, {});
|
|
11468
|
-
};
|
|
11469
|
-
window.addEventListener("keydown", onDown);
|
|
11470
|
-
window.addEventListener("keyup", onUp);
|
|
11471
|
-
return () => {
|
|
11472
|
-
window.removeEventListener("keydown", onDown);
|
|
11473
|
-
window.removeEventListener("keyup", onUp);
|
|
11474
|
-
};
|
|
11475
|
-
}, [keyMap, keyUpMap, eventBus]);
|
|
11476
|
-
React92.useEffect(() => {
|
|
11477
|
-
if (!keyMap && !keyUpMap) return;
|
|
11478
|
-
svgRef.current?.focus();
|
|
11479
|
-
}, [keyMap, keyUpMap]);
|
|
11480
|
-
const stageContext = React92.useMemo(() => ({ tileSize }), [tileSize]);
|
|
11481
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
11482
|
-
"svg",
|
|
11483
|
-
{
|
|
11484
|
-
ref: svgRef,
|
|
11485
|
-
"data-testid": "svg-stage",
|
|
11486
|
-
viewBox: `0 0 ${cols * tileSize} ${rows * tileSize}`,
|
|
11487
|
-
preserveAspectRatio: "xMidYMid meet",
|
|
11488
|
-
className: cn("block h-full w-full", className),
|
|
11489
|
-
tabIndex: keyMap || keyUpMap ? 0 : void 0,
|
|
11490
|
-
onPointerDown: handlePointerDown,
|
|
11491
|
-
onPointerMove: handlePointerMove,
|
|
11492
|
-
onPointerUp: handlePointerUp,
|
|
11493
|
-
onPointerLeave: handlePointerLeave,
|
|
11494
|
-
children: [
|
|
11495
|
-
/* @__PURE__ */ jsxRuntime.jsx("rect", { width: cols * tileSize, height: rows * tileSize, fill: background }),
|
|
11496
|
-
/* @__PURE__ */ jsxRuntime.jsx(SvgStageContext.Provider, { value: stageContext, children })
|
|
11497
|
-
]
|
|
11498
|
-
}
|
|
11499
|
-
);
|
|
11500
|
-
}
|
|
11501
|
-
var SvgStageContext;
|
|
11502
|
-
var init_SvgStage = __esm({
|
|
11503
|
-
"components/game/molecules/SvgStage.tsx"() {
|
|
11504
|
-
"use client";
|
|
11505
|
-
init_cn();
|
|
11506
|
-
init_useEventBus();
|
|
11507
|
-
SvgStageContext = React92__namespace.createContext({ tileSize: 1 });
|
|
11508
|
-
SvgStage.displayName = "SvgStage";
|
|
11509
|
-
}
|
|
11510
|
-
});
|
|
11511
|
-
function SvgDrawShape({
|
|
11512
|
-
shape,
|
|
11513
|
-
x,
|
|
11514
|
-
y,
|
|
11515
|
-
width,
|
|
11516
|
-
height,
|
|
11517
|
-
radius,
|
|
11518
|
-
radiusY,
|
|
11519
|
-
points,
|
|
11520
|
-
d,
|
|
11521
|
-
x2,
|
|
11522
|
-
y2,
|
|
11523
|
-
fill,
|
|
11524
|
-
stroke,
|
|
11525
|
-
strokeWidth,
|
|
11526
|
-
opacity,
|
|
11527
|
-
className
|
|
11528
|
-
}) {
|
|
11529
|
-
const { tileSize } = React92.useContext(SvgStageContext);
|
|
11530
|
-
const cell = (v) => v === void 0 ? void 0 : v * tileSize;
|
|
11531
|
-
const paint = {
|
|
11532
|
-
fill: fill ?? (stroke === void 0 ? "var(--color-primary)" : "none"),
|
|
11533
|
-
stroke,
|
|
11534
|
-
strokeWidth,
|
|
11535
|
-
opacity,
|
|
11536
|
-
className
|
|
11537
|
-
};
|
|
11538
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("g", { transform: `translate(${x * tileSize} ${y * tileSize})`, children: [
|
|
11539
|
-
shape === "rect" && /* @__PURE__ */ jsxRuntime.jsx("rect", { width: cell(width), height: cell(height), ...paint }),
|
|
11540
|
-
shape === "circle" && /* @__PURE__ */ jsxRuntime.jsx("circle", { r: cell(radius), ...paint }),
|
|
11541
|
-
shape === "ellipse" && /* @__PURE__ */ jsxRuntime.jsx("ellipse", { rx: cell(radius), ry: cell(radiusY ?? radius), ...paint }),
|
|
11542
|
-
shape === "polygon" && /* @__PURE__ */ jsxRuntime.jsx("polygon", { points, ...paint }),
|
|
11543
|
-
shape === "polyline" && /* @__PURE__ */ jsxRuntime.jsx("polyline", { points, ...paint }),
|
|
11544
|
-
shape === "path" && /* @__PURE__ */ jsxRuntime.jsx("path", { d, ...paint }),
|
|
11545
|
-
shape === "line" && /* @__PURE__ */ jsxRuntime.jsx("line", { x2: cell(x2), y2: cell(y2), ...paint })
|
|
11546
|
-
] });
|
|
11547
|
-
}
|
|
11548
|
-
var init_SvgDrawShape = __esm({
|
|
11549
|
-
"components/game/atoms/SvgDrawShape.tsx"() {
|
|
11550
|
-
"use client";
|
|
11551
|
-
init_SvgStage();
|
|
11552
|
-
SvgDrawShape.displayName = "SvgDrawShape";
|
|
11553
|
-
}
|
|
11554
|
-
});
|
|
11555
|
-
function SvgDrawGroup({
|
|
11556
|
-
x = 0,
|
|
11557
|
-
y = 0,
|
|
11558
|
-
scale,
|
|
11559
|
-
rotate,
|
|
11560
|
-
opacity,
|
|
11561
|
-
className,
|
|
11562
|
-
children
|
|
11563
|
-
}) {
|
|
11564
|
-
const { tileSize } = React92.useContext(SvgStageContext);
|
|
11565
|
-
const transforms = [`translate(${x * tileSize} ${y * tileSize})`];
|
|
11566
|
-
if (rotate !== void 0) transforms.push(`rotate(${rotate})`);
|
|
11567
|
-
if (scale !== void 0) transforms.push(`scale(${scale})`);
|
|
11568
|
-
return /* @__PURE__ */ jsxRuntime.jsx("g", { transform: transforms.join(" "), opacity, className, children });
|
|
11569
|
-
}
|
|
11570
|
-
var init_SvgDrawGroup = __esm({
|
|
11571
|
-
"components/game/atoms/SvgDrawGroup.tsx"() {
|
|
11572
|
-
"use client";
|
|
11573
|
-
init_SvgStage();
|
|
11574
|
-
SvgDrawGroup.displayName = "SvgDrawGroup";
|
|
11575
|
-
}
|
|
11576
|
-
});
|
|
11577
|
-
function SvgDrawText({
|
|
11578
|
-
x,
|
|
11579
|
-
y,
|
|
11580
|
-
text,
|
|
11581
|
-
size = 12,
|
|
11582
|
-
fill = "var(--color-foreground)",
|
|
11583
|
-
anchor = "middle",
|
|
11584
|
-
className
|
|
11585
|
-
}) {
|
|
11586
|
-
const { tileSize } = React92.useContext(SvgStageContext);
|
|
11587
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
11588
|
-
"text",
|
|
11589
|
-
{
|
|
11590
|
-
x: x * tileSize,
|
|
11591
|
-
y: y * tileSize,
|
|
11592
|
-
fontSize: size,
|
|
11593
|
-
fill,
|
|
11594
|
-
textAnchor: anchor,
|
|
11595
|
-
className,
|
|
11596
|
-
children: text
|
|
11597
|
-
}
|
|
11598
|
-
);
|
|
11599
|
-
}
|
|
11600
|
-
var init_SvgDrawText = __esm({
|
|
11601
|
-
"components/game/atoms/SvgDrawText.tsx"() {
|
|
11602
|
-
"use client";
|
|
11603
|
-
init_SvgStage();
|
|
11604
|
-
SvgDrawText.displayName = "SvgDrawText";
|
|
11605
|
-
}
|
|
11606
|
-
});
|
|
11607
11520
|
function ControlGrid({
|
|
11608
11521
|
kind,
|
|
11609
11522
|
buttons = DEFAULT_BUTTONS,
|
|
@@ -12307,6 +12220,7 @@ function MiniMap({
|
|
|
12307
12220
|
const cached = imgCacheRef.current.get(url);
|
|
12308
12221
|
if (cached) return cached.complete ? cached : null;
|
|
12309
12222
|
const img = new Image();
|
|
12223
|
+
img.crossOrigin = "anonymous";
|
|
12310
12224
|
img.src = url;
|
|
12311
12225
|
img.onload = () => {
|
|
12312
12226
|
const canvas = canvasRef.current;
|
|
@@ -12474,7 +12388,7 @@ function useCamera(initial) {
|
|
|
12474
12388
|
const handleWheel = React92.useCallback((e, drawFn) => {
|
|
12475
12389
|
e.preventDefault();
|
|
12476
12390
|
const zoomDelta = e.deltaY > 0 ? 0.9 : 1.1;
|
|
12477
|
-
cameraRef.current.zoom = Math.max(
|
|
12391
|
+
cameraRef.current.zoom = Math.max(MIN_ZOOM, Math.min(MAX_ZOOM, cameraRef.current.zoom * zoomDelta));
|
|
12478
12392
|
drawFn?.();
|
|
12479
12393
|
}, []);
|
|
12480
12394
|
const handlePointerDown = React92.useCallback((e) => {
|
|
@@ -12495,7 +12409,7 @@ function useCamera(initial) {
|
|
|
12495
12409
|
const zoomAtPoint = React92.useCallback((factor, centerX, centerY, viewportSize, drawFn) => {
|
|
12496
12410
|
const cam = cameraRef.current;
|
|
12497
12411
|
const oldZoom = cam.zoom;
|
|
12498
|
-
const newZoom = Math.max(
|
|
12412
|
+
const newZoom = Math.max(MIN_ZOOM, Math.min(MAX_ZOOM, oldZoom * factor));
|
|
12499
12413
|
if (newZoom === oldZoom) {
|
|
12500
12414
|
drawFn?.();
|
|
12501
12415
|
return;
|
|
@@ -12547,9 +12461,12 @@ function useCamera(initial) {
|
|
|
12547
12461
|
lerpToTarget
|
|
12548
12462
|
};
|
|
12549
12463
|
}
|
|
12464
|
+
var MIN_ZOOM, MAX_ZOOM;
|
|
12550
12465
|
var init_useCamera = __esm({
|
|
12551
12466
|
"hooks/useCamera.ts"() {
|
|
12552
12467
|
"use client";
|
|
12468
|
+
MIN_ZOOM = 0.05;
|
|
12469
|
+
MAX_ZOOM = 10;
|
|
12553
12470
|
}
|
|
12554
12471
|
});
|
|
12555
12472
|
function localPoint(canvas, clientX, clientY) {
|
|
@@ -12670,6 +12587,7 @@ function getOrLoadImage(url, onReady) {
|
|
|
12670
12587
|
return null;
|
|
12671
12588
|
}
|
|
12672
12589
|
const img = new Image();
|
|
12590
|
+
img.crossOrigin = "anonymous";
|
|
12673
12591
|
const entry = { img, status: "pending", onReady };
|
|
12674
12592
|
cache.set(url, entry);
|
|
12675
12593
|
updateAssetStatus(url, "pending");
|
|
@@ -12681,10 +12599,14 @@ function getOrLoadImage(url, onReady) {
|
|
|
12681
12599
|
img.onerror = () => {
|
|
12682
12600
|
entry.status = "failed";
|
|
12683
12601
|
updateAssetStatus(url, "failed");
|
|
12602
|
+
entry.onReady?.();
|
|
12684
12603
|
};
|
|
12685
12604
|
img.src = url;
|
|
12686
12605
|
return null;
|
|
12687
12606
|
}
|
|
12607
|
+
function getImageStatus(url) {
|
|
12608
|
+
return cache.get(url)?.status;
|
|
12609
|
+
}
|
|
12688
12610
|
var cache;
|
|
12689
12611
|
var init_imageCache = __esm({
|
|
12690
12612
|
"lib/imageCache.ts"() {
|
|
@@ -12793,6 +12715,15 @@ function createWebPainter(ctx, onAssetLoad) {
|
|
|
12793
12715
|
ctx.lineWidth = lineWidth;
|
|
12794
12716
|
ctx.stroke();
|
|
12795
12717
|
},
|
|
12718
|
+
fillPath(d, color) {
|
|
12719
|
+
ctx.fillStyle = color;
|
|
12720
|
+
ctx.fill(new Path2D(d));
|
|
12721
|
+
},
|
|
12722
|
+
strokePath(d, color, lineWidth = 1) {
|
|
12723
|
+
ctx.strokeStyle = color;
|
|
12724
|
+
ctx.lineWidth = lineWidth;
|
|
12725
|
+
ctx.stroke(new Path2D(d));
|
|
12726
|
+
},
|
|
12796
12727
|
text(str, x, y, style) {
|
|
12797
12728
|
if (style.font) ctx.font = style.font;
|
|
12798
12729
|
ctx.fillStyle = style.color;
|
|
@@ -12814,12 +12745,13 @@ var init_webPainter2d = __esm({
|
|
|
12814
12745
|
|
|
12815
12746
|
// lib/drawable/projector.ts
|
|
12816
12747
|
function create2DProjector(opts) {
|
|
12817
|
-
const {
|
|
12818
|
-
const
|
|
12819
|
-
const
|
|
12820
|
-
const
|
|
12748
|
+
const { baseOffsetX, layout } = opts;
|
|
12749
|
+
const tw = opts.tileWidth ?? TILE_WIDTH;
|
|
12750
|
+
const tileWidth = layout === "free" ? 1 : tw;
|
|
12751
|
+
const floorHeight = layout === "free" ? 1 : tw / 2;
|
|
12752
|
+
const diamondTopY = layout === "free" ? 0 : opts.diamondTopY ?? tw * (DIAMOND_TOP_Y / TILE_WIDTH);
|
|
12821
12753
|
const squareGrid = layout === "flat" || layout === "free";
|
|
12822
|
-
const project = (pos) => layout === "free" ? { x: pos.x, y: pos.y } : isoToScreen(pos.x, pos.y,
|
|
12754
|
+
const project = (pos) => layout === "free" ? { x: pos.x, y: pos.y } : isoToScreen(pos.x, pos.y, tw, baseOffsetX, layout);
|
|
12823
12755
|
const anchorPoint = (pos, anchor) => {
|
|
12824
12756
|
const base = project(pos);
|
|
12825
12757
|
if (anchor === "top-left") return base;
|
|
@@ -12850,7 +12782,7 @@ function create2DProjector(opts) {
|
|
|
12850
12782
|
{ x: base.x, y: topY + floorHeight / 2 }
|
|
12851
12783
|
];
|
|
12852
12784
|
};
|
|
12853
|
-
return { project, anchorPoint, cellPath, tileWidth, floorHeight, diamondTopY,
|
|
12785
|
+
return { project, anchorPoint, cellPath, tileWidth, floorHeight, diamondTopY, squareGrid, worldPixelDirect: layout === "free" };
|
|
12854
12786
|
}
|
|
12855
12787
|
var init_projector = __esm({
|
|
12856
12788
|
"lib/drawable/projector.ts"() {
|
|
@@ -12866,32 +12798,67 @@ var init_contract = __esm({
|
|
|
12866
12798
|
"lib/drawable/contract.ts"() {
|
|
12867
12799
|
}
|
|
12868
12800
|
});
|
|
12869
|
-
|
|
12870
|
-
|
|
12801
|
+
function warnMissingOnce(reason, node) {
|
|
12802
|
+
const key = `${reason}:${node.asset.url}:${String(node.asset.atlas)}:${String(node.asset.sprite)}`;
|
|
12803
|
+
if (loggedMissing.has(key)) return;
|
|
12804
|
+
loggedMissing.add(key);
|
|
12805
|
+
spriteLog.warn("draw-sprite asset unresolvable \u2014 painting fallback square", { reason, url: node.asset.url, atlas: node.asset.atlas, sprite: node.asset.sprite });
|
|
12806
|
+
}
|
|
12807
|
+
function paintFallbackSquare(painter, node, dctx, reason) {
|
|
12808
|
+
warnMissingOnce(reason, node);
|
|
12809
|
+
const tw = dctx.projector.tileWidth;
|
|
12810
|
+
const natural = dctx.projector.worldPixelDirect ? FALLBACK_WORLD_PX : tw;
|
|
12811
|
+
const w = node.width !== void 0 ? node.width * tw : natural;
|
|
12812
|
+
const h = node.height !== void 0 ? node.height * tw : natural;
|
|
12813
|
+
const anchor = node.anchor ?? "top-left";
|
|
12814
|
+
const p = dctx.projector.anchorPoint(node.position, anchor);
|
|
12815
|
+
const dx = anchor === "top-left" ? p.x : p.x - w / 2;
|
|
12816
|
+
const dy = anchor === "ground" ? p.y - h : anchor === "center" ? p.y - h / 2 : p.y;
|
|
12817
|
+
painter.save();
|
|
12818
|
+
if (node.opacity !== void 0 && node.opacity !== 1) painter.setAlpha(node.opacity);
|
|
12819
|
+
painter.fillRect(dx, dy, w, h, "#9b8f7f");
|
|
12820
|
+
painter.strokeRect(dx, dy, w, h, "#5e564b", Math.max(1, tw / 32));
|
|
12821
|
+
painter.restore();
|
|
12822
|
+
}
|
|
12871
12823
|
function DrawSprite(_props) {
|
|
12872
12824
|
return null;
|
|
12873
12825
|
}
|
|
12874
|
-
var paintSprite;
|
|
12826
|
+
var spriteLog, loggedMissing, FALLBACK_WORLD_PX, paintSprite;
|
|
12875
12827
|
var init_DrawSprite = __esm({
|
|
12876
12828
|
"components/game/atoms/DrawSprite.tsx"() {
|
|
12877
12829
|
"use client";
|
|
12878
12830
|
init_atlasSlice();
|
|
12831
|
+
init_imageCache();
|
|
12879
12832
|
init_contract();
|
|
12833
|
+
spriteLog = logger.createLogger("almadar:ui:draw-sprite");
|
|
12834
|
+
loggedMissing = /* @__PURE__ */ new Set();
|
|
12835
|
+
FALLBACK_WORLD_PX = 32;
|
|
12880
12836
|
paintSprite = (painter, node, dctx) => {
|
|
12881
12837
|
if (!node.asset?.url || !isValidScenePos(node.position)) return;
|
|
12882
12838
|
const tex = painter.resolveTexture(node.asset.url);
|
|
12883
|
-
if (!tex)
|
|
12839
|
+
if (!tex) {
|
|
12840
|
+
if (getImageStatus(node.asset.url) === "failed") paintFallbackSquare(painter, node, dctx, "texture-failed");
|
|
12841
|
+
return;
|
|
12842
|
+
}
|
|
12884
12843
|
let src = typeof node.frame === "object" ? node.frame : void 0;
|
|
12885
12844
|
if (!src && isAtlasAsset(node.asset)) {
|
|
12886
12845
|
const atlas = getAtlas(node.asset.atlas, dctx.invalidate);
|
|
12887
|
-
if (!atlas)
|
|
12846
|
+
if (!atlas) {
|
|
12847
|
+
if (atlasFailed(node.asset.atlas)) paintFallbackSquare(painter, node, dctx, "atlas-failed");
|
|
12848
|
+
return;
|
|
12849
|
+
}
|
|
12888
12850
|
const r2 = subRectFor(atlas, node.asset.sprite);
|
|
12889
|
-
if (!r2)
|
|
12851
|
+
if (!r2) {
|
|
12852
|
+
paintFallbackSquare(painter, node, dctx, "sprite-missing");
|
|
12853
|
+
return;
|
|
12854
|
+
}
|
|
12890
12855
|
src = { x: r2.sx, y: r2.sy, w: r2.sw, h: r2.sh };
|
|
12891
12856
|
}
|
|
12892
12857
|
const tw = dctx.projector.tileWidth;
|
|
12893
|
-
const
|
|
12894
|
-
const
|
|
12858
|
+
const fallbackW = dctx.projector.worldPixelDirect ? src ? src.w : tex.width : tw;
|
|
12859
|
+
const fallbackH = dctx.projector.worldPixelDirect ? src ? src.h : tex.height : tw;
|
|
12860
|
+
const w = node.width !== void 0 ? node.width * tw : fallbackW;
|
|
12861
|
+
const h = node.height !== void 0 ? node.height * tw : fallbackH;
|
|
12895
12862
|
const anchor = node.anchor ?? "top-left";
|
|
12896
12863
|
const p = dctx.projector.anchorPoint(node.position, anchor);
|
|
12897
12864
|
const dx = anchor === "top-left" ? p.x : p.x - w / 2;
|
|
@@ -12968,6 +12935,16 @@ var init_DrawShape = __esm({
|
|
|
12968
12935
|
if (node.stroke) painter.strokePoly(pts, node.stroke, node.strokeWidth ?? 1, true);
|
|
12969
12936
|
break;
|
|
12970
12937
|
}
|
|
12938
|
+
case "path": {
|
|
12939
|
+
if (!node.d) break;
|
|
12940
|
+
const base = dctx.projector.project(node.position);
|
|
12941
|
+
const tw = dctx.projector.tileWidth;
|
|
12942
|
+
painter.translate(base.x, base.y);
|
|
12943
|
+
painter.scale(tw, tw);
|
|
12944
|
+
if (node.fill) painter.fillPath(node.d, node.fill);
|
|
12945
|
+
if (node.stroke) painter.strokePath(node.d, node.stroke, (node.strokeWidth ?? 1) / tw);
|
|
12946
|
+
break;
|
|
12947
|
+
}
|
|
12971
12948
|
}
|
|
12972
12949
|
painter.restore();
|
|
12973
12950
|
};
|
|
@@ -13059,6 +13036,19 @@ function paintDrawable(painter, node, dctx) {
|
|
|
13059
13036
|
case "draw-text":
|
|
13060
13037
|
paintText(painter, node, dctx);
|
|
13061
13038
|
break;
|
|
13039
|
+
case "draw-group": {
|
|
13040
|
+
if (!isValidScenePos(node.position)) break;
|
|
13041
|
+
if (!Array.isArray(node.items)) break;
|
|
13042
|
+
const p = dctx.projector.project(node.position);
|
|
13043
|
+
painter.save();
|
|
13044
|
+
painter.translate(p.x, p.y);
|
|
13045
|
+
if (node.scale !== void 0) painter.scale(node.scale, node.scale);
|
|
13046
|
+
if (node.rotate !== void 0) painter.rotate(node.rotate);
|
|
13047
|
+
if (node.opacity !== void 0 && node.opacity !== 1) painter.setAlpha(node.opacity);
|
|
13048
|
+
for (const item of node.items) paintDrawable(painter, item, dctx);
|
|
13049
|
+
painter.restore();
|
|
13050
|
+
break;
|
|
13051
|
+
}
|
|
13062
13052
|
case "draw-sprite-layer":
|
|
13063
13053
|
paintSpriteLayer(painter, node, dctx);
|
|
13064
13054
|
break;
|
|
@@ -13072,6 +13062,7 @@ function paintDrawable(painter, node, dctx) {
|
|
|
13072
13062
|
}
|
|
13073
13063
|
var init_paintDispatch = __esm({
|
|
13074
13064
|
"lib/drawable/paintDispatch.ts"() {
|
|
13065
|
+
init_contract();
|
|
13075
13066
|
init_DrawSprite();
|
|
13076
13067
|
init_DrawShape();
|
|
13077
13068
|
init_DrawText();
|
|
@@ -13089,6 +13080,7 @@ function collectDrawnItems(nodes) {
|
|
|
13089
13080
|
case "draw-sprite":
|
|
13090
13081
|
case "draw-shape":
|
|
13091
13082
|
case "draw-text":
|
|
13083
|
+
case "draw-group":
|
|
13092
13084
|
if (isValidScenePos(n.position)) out.push({ pos: n.position, id: n.id });
|
|
13093
13085
|
break;
|
|
13094
13086
|
case "draw-sprite-layer":
|
|
@@ -13132,6 +13124,8 @@ function Canvas2D({
|
|
|
13132
13124
|
keyUpMap,
|
|
13133
13125
|
camera = "pan-zoom",
|
|
13134
13126
|
scale = 0.4,
|
|
13127
|
+
tileWidth,
|
|
13128
|
+
fit = false,
|
|
13135
13129
|
showMinimap = true,
|
|
13136
13130
|
followTarget,
|
|
13137
13131
|
cameraPos,
|
|
@@ -13174,9 +13168,32 @@ function Canvas2D({
|
|
|
13174
13168
|
observer2.observe(el);
|
|
13175
13169
|
return () => observer2.disconnect();
|
|
13176
13170
|
}, []);
|
|
13177
|
-
const
|
|
13178
|
-
const
|
|
13179
|
-
const
|
|
13171
|
+
const [atlasVersion, setAtlasVersion] = React92.useState(0);
|
|
13172
|
+
const bumpAtlas = React92.useCallback(() => setAtlasVersion((v) => v + 1), []);
|
|
13173
|
+
const detectedTileWidth = React92.useMemo(() => {
|
|
13174
|
+
for (const n of drawables ?? []) {
|
|
13175
|
+
const refs = [];
|
|
13176
|
+
if (n.type === "draw-sprite") refs.push(n.asset);
|
|
13177
|
+
else if (n.type === "draw-sprite-layer") for (const it of n.items) refs.push(it.asset);
|
|
13178
|
+
for (const a of refs) {
|
|
13179
|
+
if (a && isAtlasAsset(a) && a.atlas) {
|
|
13180
|
+
const atlas = getAtlas(a.atlas, bumpAtlas);
|
|
13181
|
+
if (atlas) {
|
|
13182
|
+
if ("tileWidth" in atlas) return atlas.tileWidth;
|
|
13183
|
+
if ("subTextures" in atlas) {
|
|
13184
|
+
const first = Object.values(atlas.subTextures)[0];
|
|
13185
|
+
if (first && typeof first.width === "number") return first.width;
|
|
13186
|
+
}
|
|
13187
|
+
}
|
|
13188
|
+
}
|
|
13189
|
+
}
|
|
13190
|
+
}
|
|
13191
|
+
return void 0;
|
|
13192
|
+
}, [drawables, atlasVersion]);
|
|
13193
|
+
const nativeTileW = tileWidth ?? detectedTileWidth ?? TILE_WIDTH;
|
|
13194
|
+
const scaledTileWidth = nativeTileW;
|
|
13195
|
+
const scaledFloorHeight = nativeTileW / 2;
|
|
13196
|
+
const scaledDiamondTopY = nativeTileW * (DIAMOND_TOP_Y / TILE_WIDTH);
|
|
13180
13197
|
const drawnItems = React92.useMemo(() => collectDrawnItems(drawables ?? []), [drawables]);
|
|
13181
13198
|
const scenePositions = React92.useMemo(() => drawnItems.map((i) => i.pos), [drawnItems]);
|
|
13182
13199
|
const hitIndex = React92.useMemo(() => buildHitIndex(drawnItems), [drawnItems]);
|
|
@@ -13194,14 +13211,36 @@ function Canvas2D({
|
|
|
13194
13211
|
if (isFree || projection === "flat" || projection === "side") return 0;
|
|
13195
13212
|
return (gridExtent.height - 1) * (scaledTileWidth / 2);
|
|
13196
13213
|
}, [isFree, projection, gridExtent.height, scaledTileWidth]);
|
|
13214
|
+
const effectiveZoom = React92.useMemo(() => {
|
|
13215
|
+
if (isFree || projection === "side") return scale;
|
|
13216
|
+
if (!fit) {
|
|
13217
|
+
const z2 = TILE_WIDTH * scale * scale / nativeTileW;
|
|
13218
|
+
return Number.isFinite(z2) && z2 > 0 ? z2 : scale;
|
|
13219
|
+
}
|
|
13220
|
+
if (!viewportSize.width || gridExtent.width < 2 || gridExtent.height < 2) return scale;
|
|
13221
|
+
let boardW;
|
|
13222
|
+
let boardH;
|
|
13223
|
+
if (projection === "flat") {
|
|
13224
|
+
boardW = gridExtent.width * nativeTileW;
|
|
13225
|
+
boardH = gridExtent.height * nativeTileW;
|
|
13226
|
+
} else if (projection === "hex") {
|
|
13227
|
+
boardW = (gridExtent.width + 0.5) * nativeTileW;
|
|
13228
|
+
boardH = gridExtent.height * (nativeTileW / 2) * 0.75 + nativeTileW / 2;
|
|
13229
|
+
} else {
|
|
13230
|
+
boardW = (gridExtent.width + gridExtent.height) * (nativeTileW / 2);
|
|
13231
|
+
boardH = (gridExtent.width + gridExtent.height) * (nativeTileW / 4);
|
|
13232
|
+
}
|
|
13233
|
+
const z = Math.min(viewportSize.width * 0.85 / boardW, viewportSize.height * 0.85 / boardH);
|
|
13234
|
+
return Number.isFinite(z) && z > 0 ? z : scale;
|
|
13235
|
+
}, [isFree, projection, fit, viewportSize, gridExtent, nativeTileW, scale]);
|
|
13197
13236
|
const projector = React92.useMemo(
|
|
13198
|
-
() => create2DProjector({
|
|
13199
|
-
[
|
|
13237
|
+
() => create2DProjector({ tileWidth: nativeTileW, baseOffsetX, layout }),
|
|
13238
|
+
[nativeTileW, baseOffsetX, layout]
|
|
13200
13239
|
);
|
|
13201
13240
|
const unproject = React92.useCallback((screenX, screenY) => {
|
|
13202
13241
|
if (projection === "free" || projection === "side") return { x: Math.round(screenX), y: Math.round(screenY) };
|
|
13203
|
-
return screenToIso(screenX, screenY,
|
|
13204
|
-
}, [projection,
|
|
13242
|
+
return screenToIso(screenX, screenY, nativeTileW, baseOffsetX, projection);
|
|
13243
|
+
}, [projection, nativeTileW, baseOffsetX]);
|
|
13205
13244
|
const bgUrls = React92.useMemo(() => backgroundImage ? [backgroundImage.url] : [], [backgroundImage]);
|
|
13206
13245
|
const { getImage, pendingCount: _imagePendingCount } = useImageCache(bgUrls);
|
|
13207
13246
|
React92.useEffect(() => {
|
|
@@ -13228,9 +13267,7 @@ function Canvas2D({
|
|
|
13228
13267
|
zoomAtPoint,
|
|
13229
13268
|
screenToWorld,
|
|
13230
13269
|
lerpToTarget
|
|
13231
|
-
} = useCamera({ zoom:
|
|
13232
|
-
const [atlasVersion, setAtlasVersion] = React92.useState(0);
|
|
13233
|
-
const bumpAtlas = React92.useCallback(() => setAtlasVersion((v) => v + 1), []);
|
|
13270
|
+
} = useCamera({ zoom: effectiveZoom });
|
|
13234
13271
|
const miniMapTiles = React92.useMemo(() => {
|
|
13235
13272
|
if (!showMinimap) return [];
|
|
13236
13273
|
const color = MINIMAP_TERRAIN_COLORS.default;
|
|
@@ -13305,6 +13342,13 @@ function Canvas2D({
|
|
|
13305
13342
|
React92.useEffect(() => {
|
|
13306
13343
|
draw();
|
|
13307
13344
|
}, [_imagePendingCount, draw]);
|
|
13345
|
+
const userZoomedRef = React92.useRef(false);
|
|
13346
|
+
React92.useEffect(() => {
|
|
13347
|
+
if (userZoomedRef.current) return;
|
|
13348
|
+
if (cameraRef.current.zoom === effectiveZoom) return;
|
|
13349
|
+
cameraRef.current.zoom = effectiveZoom;
|
|
13350
|
+
draw();
|
|
13351
|
+
}, [effectiveZoom, cameraRef, draw]);
|
|
13308
13352
|
React92.useEffect(() => {
|
|
13309
13353
|
draw();
|
|
13310
13354
|
}, [atlasVersion, draw]);
|
|
@@ -13361,7 +13405,9 @@ function Canvas2D({
|
|
|
13361
13405
|
if (tileLeaveEvent) eventBus.emit(`UI:${tileLeaveEvent}`, {});
|
|
13362
13406
|
}, [handleMouseLeave, tileLeaveEvent, eventBus]);
|
|
13363
13407
|
const applyZoom = React92.useCallback((factor, centerX, centerY) => {
|
|
13364
|
-
if (enableCamera)
|
|
13408
|
+
if (!enableCamera) return;
|
|
13409
|
+
userZoomedRef.current = true;
|
|
13410
|
+
zoomAtPoint(factor, centerX, centerY, viewportSize, () => draw());
|
|
13365
13411
|
}, [enableCamera, zoomAtPoint, viewportSize, draw]);
|
|
13366
13412
|
const applyPanDelta = React92.useCallback((dx, dy) => {
|
|
13367
13413
|
if (enableCamera) panBy(dx, dy, () => draw());
|
|
@@ -13546,6 +13592,8 @@ function Canvas({
|
|
|
13546
13592
|
isLoading,
|
|
13547
13593
|
unitScale,
|
|
13548
13594
|
showMinimap,
|
|
13595
|
+
fit,
|
|
13596
|
+
tileWidth,
|
|
13549
13597
|
backgroundImage,
|
|
13550
13598
|
backgroundColor,
|
|
13551
13599
|
worldWidth,
|
|
@@ -13603,6 +13651,8 @@ function Canvas({
|
|
|
13603
13651
|
projection,
|
|
13604
13652
|
camera: to2DCamera(camera?.mode),
|
|
13605
13653
|
...zoom !== void 0 ? { scale: zoom } : {},
|
|
13654
|
+
...fit !== void 0 ? { fit } : {},
|
|
13655
|
+
...tileWidth !== void 0 ? { tileWidth } : {},
|
|
13606
13656
|
...camera?.target !== void 0 ? { followTarget: camera.target } : {},
|
|
13607
13657
|
...camera?.pos !== void 0 ? { cameraPos: camera.pos } : {},
|
|
13608
13658
|
showMinimap,
|
|
@@ -13629,32 +13679,6 @@ var init_Canvas = __esm({
|
|
|
13629
13679
|
Canvas.displayName = "Canvas";
|
|
13630
13680
|
}
|
|
13631
13681
|
});
|
|
13632
|
-
function SvgDrawShapeLayer({
|
|
13633
|
-
items,
|
|
13634
|
-
fill,
|
|
13635
|
-
stroke,
|
|
13636
|
-
strokeWidth,
|
|
13637
|
-
opacity
|
|
13638
|
-
}) {
|
|
13639
|
-
return /* @__PURE__ */ jsxRuntime.jsx("g", { children: items.map(({ id, ...shape }) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
13640
|
-
SvgDrawShape,
|
|
13641
|
-
{
|
|
13642
|
-
...shape,
|
|
13643
|
-
fill: shape.fill ?? fill,
|
|
13644
|
-
stroke: shape.stroke ?? stroke,
|
|
13645
|
-
strokeWidth: shape.strokeWidth ?? strokeWidth,
|
|
13646
|
-
opacity: shape.opacity ?? opacity
|
|
13647
|
-
},
|
|
13648
|
-
id
|
|
13649
|
-
)) });
|
|
13650
|
-
}
|
|
13651
|
-
var init_SvgDrawShapeLayer = __esm({
|
|
13652
|
-
"components/game/molecules/SvgDrawShapeLayer.tsx"() {
|
|
13653
|
-
"use client";
|
|
13654
|
-
init_SvgDrawShape();
|
|
13655
|
-
SvgDrawShapeLayer.displayName = "SvgDrawShapeLayer";
|
|
13656
|
-
}
|
|
13657
|
-
});
|
|
13658
13682
|
function GameAudioToggle({
|
|
13659
13683
|
size = "sm",
|
|
13660
13684
|
className,
|
|
@@ -26144,6 +26168,8 @@ function DataList({
|
|
|
26144
26168
|
hasMore,
|
|
26145
26169
|
children,
|
|
26146
26170
|
pageSize = 5,
|
|
26171
|
+
sortBy,
|
|
26172
|
+
sortDirection,
|
|
26147
26173
|
renderItem: schemaRenderItem,
|
|
26148
26174
|
dragGroup,
|
|
26149
26175
|
accepts,
|
|
@@ -26172,7 +26198,11 @@ function DataList({
|
|
|
26172
26198
|
dndItemIdField,
|
|
26173
26199
|
dndRoot
|
|
26174
26200
|
});
|
|
26175
|
-
const
|
|
26201
|
+
const orderedData = dnd.orderedItems;
|
|
26202
|
+
const allData = React92__namespace.default.useMemo(
|
|
26203
|
+
() => sortRows(orderedData, sortBy, sortDirection),
|
|
26204
|
+
[orderedData, sortBy, sortDirection]
|
|
26205
|
+
);
|
|
26176
26206
|
const data = pageSize > 0 ? allData.slice(0, visibleCount) : allData;
|
|
26177
26207
|
const hasMoreLocal = pageSize > 0 && visibleCount < allData.length;
|
|
26178
26208
|
const hasRenderProp = typeof children === "function";
|
|
@@ -26209,7 +26239,7 @@ function DataList({
|
|
|
26209
26239
|
};
|
|
26210
26240
|
eventBus.emit(`UI:${action.event}`, payload);
|
|
26211
26241
|
};
|
|
26212
|
-
const renderItemActions = (itemData) => {
|
|
26242
|
+
const renderItemActions = (itemData, onPrimary = false) => {
|
|
26213
26243
|
if (!itemActions || itemActions.length === 0) return null;
|
|
26214
26244
|
const inline = maxInlineActions != null ? itemActions.slice(0, maxInlineActions) : itemActions;
|
|
26215
26245
|
const overflow = maxInlineActions != null ? itemActions.slice(maxInlineActions) : [];
|
|
@@ -26222,7 +26252,12 @@ function DataList({
|
|
|
26222
26252
|
onClick: handleActionClick(action, itemData),
|
|
26223
26253
|
"data-testid": `action-${action.event}`,
|
|
26224
26254
|
"data-row-id": String(itemData.id),
|
|
26225
|
-
className: cn(
|
|
26255
|
+
className: cn(
|
|
26256
|
+
action.variant === "danger" && "text-error hover:bg-error/10",
|
|
26257
|
+
// Must sit on the Button itself: the variant's own text colour
|
|
26258
|
+
// beats an inherited one from the row wrapper.
|
|
26259
|
+
onPrimary && "!text-primary-foreground hover:bg-primary-foreground/15"
|
|
26260
|
+
),
|
|
26226
26261
|
children: [
|
|
26227
26262
|
action.icon && renderIconInput2(action.icon, { size: "xs", className: "mr-1" }),
|
|
26228
26263
|
action.label
|
|
@@ -26322,7 +26357,11 @@ function DataList({
|
|
|
26322
26357
|
metaFields.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(HStack, { gap: "xs", className: "mt-1 flex-wrap", children: metaFields.map((f3) => {
|
|
26323
26358
|
const v = getNestedValue(itemData, f3.name);
|
|
26324
26359
|
if (v === void 0 || v === null || v === "") return null;
|
|
26325
|
-
return f3.variant === "badge" ?
|
|
26360
|
+
return f3.variant === "badge" ? (
|
|
26361
|
+
// `format` applies here too — a boolean field badged
|
|
26362
|
+
// without it renders the raw "false" instead of "No".
|
|
26363
|
+
/* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: statusVariant3(String(v)), children: formatValue2(v, f3.format) }, f3.name)
|
|
26364
|
+
) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
26326
26365
|
Typography,
|
|
26327
26366
|
{
|
|
26328
26367
|
variant: "caption",
|
|
@@ -26341,7 +26380,7 @@ function DataList({
|
|
|
26341
26380
|
children: formatDate(timestamp)
|
|
26342
26381
|
}
|
|
26343
26382
|
) : /* @__PURE__ */ jsxRuntime.jsx("span", {}),
|
|
26344
|
-
renderItemActions(itemData)
|
|
26383
|
+
renderItemActions(itemData, isSent)
|
|
26345
26384
|
] })
|
|
26346
26385
|
]
|
|
26347
26386
|
}
|
|
@@ -26434,7 +26473,7 @@ function DataList({
|
|
|
26434
26473
|
if (val === void 0 || val === null) return null;
|
|
26435
26474
|
return /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "xs", className: "items-center flex-shrink-0", children: [
|
|
26436
26475
|
field.icon && renderIconInput2(field.icon, { size: "xs" }),
|
|
26437
|
-
/* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: statusVariant3(String(val)), children:
|
|
26476
|
+
/* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: statusVariant3(String(val)), children: formatValue2(val, field.format) })
|
|
26438
26477
|
] }, field.name);
|
|
26439
26478
|
})
|
|
26440
26479
|
] }),
|
|
@@ -26673,6 +26712,182 @@ var init_FormSection = __esm({
|
|
|
26673
26712
|
FormActions.displayName = "FormActions";
|
|
26674
26713
|
}
|
|
26675
26714
|
});
|
|
26715
|
+
var ALL_CATEGORY, MAX_RENDERED, GridPicker;
|
|
26716
|
+
var init_GridPicker = __esm({
|
|
26717
|
+
"components/core/molecules/GridPicker.tsx"() {
|
|
26718
|
+
"use client";
|
|
26719
|
+
init_cn();
|
|
26720
|
+
init_Input();
|
|
26721
|
+
init_Badge();
|
|
26722
|
+
init_Stack();
|
|
26723
|
+
ALL_CATEGORY = "__all__";
|
|
26724
|
+
MAX_RENDERED = 300;
|
|
26725
|
+
GridPicker = ({
|
|
26726
|
+
items,
|
|
26727
|
+
value,
|
|
26728
|
+
onChange,
|
|
26729
|
+
categories,
|
|
26730
|
+
searchPlaceholder,
|
|
26731
|
+
renderThumbnail,
|
|
26732
|
+
cellSize = 32,
|
|
26733
|
+
className
|
|
26734
|
+
}) => {
|
|
26735
|
+
const [search, setSearch] = React92.useState("");
|
|
26736
|
+
const [activeCategory, setActiveCategory] = React92.useState(ALL_CATEGORY);
|
|
26737
|
+
const gridRef = React92.useRef(null);
|
|
26738
|
+
const categoryChips = React92.useMemo(() => {
|
|
26739
|
+
if (categories !== void 0) return categories;
|
|
26740
|
+
const seen = [];
|
|
26741
|
+
for (const item of items) {
|
|
26742
|
+
if (!seen.includes(item.category)) seen.push(item.category);
|
|
26743
|
+
}
|
|
26744
|
+
return seen;
|
|
26745
|
+
}, [categories, items]);
|
|
26746
|
+
const filtered = React92.useMemo(() => {
|
|
26747
|
+
const needle = search.trim().toLowerCase();
|
|
26748
|
+
return items.filter((item) => {
|
|
26749
|
+
const matchesCategory = activeCategory === ALL_CATEGORY || item.category === activeCategory;
|
|
26750
|
+
const matchesSearch = needle === "" || item.label.toLowerCase().includes(needle) || item.keywords !== void 0 && item.keywords.some((k) => k.toLowerCase().includes(needle));
|
|
26751
|
+
return matchesCategory && matchesSearch;
|
|
26752
|
+
});
|
|
26753
|
+
}, [items, search, activeCategory]);
|
|
26754
|
+
const visible = React92.useMemo(() => filtered.slice(0, MAX_RENDERED), [filtered]);
|
|
26755
|
+
const truncated = filtered.length - visible.length;
|
|
26756
|
+
const select = React92.useCallback(
|
|
26757
|
+
(item) => {
|
|
26758
|
+
onChange(item.id);
|
|
26759
|
+
},
|
|
26760
|
+
[onChange]
|
|
26761
|
+
);
|
|
26762
|
+
const handleKeyDown = React92.useCallback(
|
|
26763
|
+
(e, index) => {
|
|
26764
|
+
const cells = gridRef.current?.querySelectorAll(
|
|
26765
|
+
"[data-gridpicker-cell]"
|
|
26766
|
+
);
|
|
26767
|
+
if (cells === void 0 || cells.length === 0) return;
|
|
26768
|
+
const columns = (() => {
|
|
26769
|
+
const grid = gridRef.current;
|
|
26770
|
+
if (grid === null) return 1;
|
|
26771
|
+
const style = window.getComputedStyle(grid);
|
|
26772
|
+
const cols = style.gridTemplateColumns.split(" ").filter(Boolean).length;
|
|
26773
|
+
return cols > 0 ? cols : 1;
|
|
26774
|
+
})();
|
|
26775
|
+
let next = -1;
|
|
26776
|
+
if (e.key === "ArrowRight") next = index + 1;
|
|
26777
|
+
else if (e.key === "ArrowLeft") next = index - 1;
|
|
26778
|
+
else if (e.key === "ArrowDown") next = index + columns;
|
|
26779
|
+
else if (e.key === "ArrowUp") next = index - columns;
|
|
26780
|
+
else if (e.key === "Enter" || e.key === " ") {
|
|
26781
|
+
e.preventDefault();
|
|
26782
|
+
select(filtered[index]);
|
|
26783
|
+
return;
|
|
26784
|
+
} else {
|
|
26785
|
+
return;
|
|
26786
|
+
}
|
|
26787
|
+
e.preventDefault();
|
|
26788
|
+
if (next >= 0 && next < cells.length) {
|
|
26789
|
+
cells[next].focus();
|
|
26790
|
+
}
|
|
26791
|
+
},
|
|
26792
|
+
[filtered, select]
|
|
26793
|
+
);
|
|
26794
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "sm", className: cn("w-full", className), children: [
|
|
26795
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
26796
|
+
Input,
|
|
26797
|
+
{
|
|
26798
|
+
type: "search",
|
|
26799
|
+
icon: "search",
|
|
26800
|
+
value: search,
|
|
26801
|
+
placeholder: searchPlaceholder,
|
|
26802
|
+
clearable: true,
|
|
26803
|
+
onClear: () => setSearch(""),
|
|
26804
|
+
onChange: (e) => setSearch(e.target.value)
|
|
26805
|
+
}
|
|
26806
|
+
),
|
|
26807
|
+
categoryChips.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "xs", wrap: true, children: [
|
|
26808
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
26809
|
+
Badge,
|
|
26810
|
+
{
|
|
26811
|
+
variant: activeCategory === ALL_CATEGORY ? "primary" : "neutral",
|
|
26812
|
+
size: "sm",
|
|
26813
|
+
role: "button",
|
|
26814
|
+
tabIndex: 0,
|
|
26815
|
+
"aria-pressed": activeCategory === ALL_CATEGORY,
|
|
26816
|
+
className: "cursor-pointer",
|
|
26817
|
+
onClick: () => setActiveCategory(ALL_CATEGORY),
|
|
26818
|
+
onKeyDown: (e) => {
|
|
26819
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
26820
|
+
e.preventDefault();
|
|
26821
|
+
setActiveCategory(ALL_CATEGORY);
|
|
26822
|
+
}
|
|
26823
|
+
},
|
|
26824
|
+
children: "All"
|
|
26825
|
+
}
|
|
26826
|
+
),
|
|
26827
|
+
categoryChips.map((category) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
26828
|
+
Badge,
|
|
26829
|
+
{
|
|
26830
|
+
variant: activeCategory === category ? "primary" : "neutral",
|
|
26831
|
+
size: "sm",
|
|
26832
|
+
role: "button",
|
|
26833
|
+
tabIndex: 0,
|
|
26834
|
+
"aria-pressed": activeCategory === category,
|
|
26835
|
+
className: "cursor-pointer",
|
|
26836
|
+
onClick: () => setActiveCategory(category),
|
|
26837
|
+
onKeyDown: (e) => {
|
|
26838
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
26839
|
+
e.preventDefault();
|
|
26840
|
+
setActiveCategory(category);
|
|
26841
|
+
}
|
|
26842
|
+
},
|
|
26843
|
+
children: category
|
|
26844
|
+
},
|
|
26845
|
+
category
|
|
26846
|
+
))
|
|
26847
|
+
] }),
|
|
26848
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
26849
|
+
"div",
|
|
26850
|
+
{
|
|
26851
|
+
ref: gridRef,
|
|
26852
|
+
role: "listbox",
|
|
26853
|
+
className: "grid gap-1 overflow-y-auto max-h-64 p-1",
|
|
26854
|
+
style: {
|
|
26855
|
+
gridTemplateColumns: `repeat(auto-fill, minmax(${cellSize}px, 1fr))`
|
|
26856
|
+
},
|
|
26857
|
+
children: visible.map((item, index) => {
|
|
26858
|
+
const selected = item.id === value;
|
|
26859
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
26860
|
+
"button",
|
|
26861
|
+
{
|
|
26862
|
+
type: "button",
|
|
26863
|
+
role: "option",
|
|
26864
|
+
"aria-selected": selected,
|
|
26865
|
+
"aria-label": item.label,
|
|
26866
|
+
title: item.label,
|
|
26867
|
+
"data-gridpicker-cell": true,
|
|
26868
|
+
tabIndex: selected || value === void 0 && index === 0 ? 0 : -1,
|
|
26869
|
+
onClick: () => select(item),
|
|
26870
|
+
onKeyDown: (e) => handleKeyDown(e, index),
|
|
26871
|
+
className: cn(
|
|
26872
|
+
"flex items-center justify-center rounded-sm",
|
|
26873
|
+
"transition-colors hover:bg-muted",
|
|
26874
|
+
"focus:outline-none focus:ring-1 focus:ring-ring",
|
|
26875
|
+
selected && "bg-primary/10 ring-1 ring-primary"
|
|
26876
|
+
),
|
|
26877
|
+
style: { width: cellSize, height: cellSize },
|
|
26878
|
+
children: renderThumbnail(item)
|
|
26879
|
+
},
|
|
26880
|
+
item.id
|
|
26881
|
+
);
|
|
26882
|
+
})
|
|
26883
|
+
}
|
|
26884
|
+
),
|
|
26885
|
+
truncated > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-1 text-xs text-muted-foreground", children: `+${truncated} more \u2014 refine your search` })
|
|
26886
|
+
] });
|
|
26887
|
+
};
|
|
26888
|
+
GridPicker.displayName = "GridPicker";
|
|
26889
|
+
}
|
|
26890
|
+
});
|
|
26676
26891
|
function fileIcon(name) {
|
|
26677
26892
|
const ext = name.split(".").pop()?.toLowerCase() ?? "";
|
|
26678
26893
|
switch (ext) {
|
|
@@ -27701,9 +27916,16 @@ var init_Popover = __esm({
|
|
|
27701
27916
|
position = "bottom",
|
|
27702
27917
|
trigger = "click",
|
|
27703
27918
|
showArrow = true,
|
|
27919
|
+
open,
|
|
27920
|
+
onOpenChange,
|
|
27704
27921
|
className
|
|
27705
27922
|
}) => {
|
|
27706
|
-
const [
|
|
27923
|
+
const [uncontrolledOpen, setUncontrolledOpen] = React92.useState(false);
|
|
27924
|
+
const isOpen = open !== void 0 ? open : uncontrolledOpen;
|
|
27925
|
+
const setIsOpen = (next) => {
|
|
27926
|
+
if (open === void 0) setUncontrolledOpen(next);
|
|
27927
|
+
onOpenChange?.(next);
|
|
27928
|
+
};
|
|
27707
27929
|
const [triggerRect, setTriggerRect] = React92.useState(null);
|
|
27708
27930
|
const [popoverWidth, setPopoverWidth] = React92.useState(0);
|
|
27709
27931
|
const triggerRef = React92.useRef(null);
|
|
@@ -27736,6 +27958,23 @@ var init_Popover = __esm({
|
|
|
27736
27958
|
updatePosition();
|
|
27737
27959
|
}
|
|
27738
27960
|
}, [isOpen]);
|
|
27961
|
+
React92.useEffect(() => {
|
|
27962
|
+
if (!isOpen) return;
|
|
27963
|
+
let raf = 0;
|
|
27964
|
+
let lastTop = Number.NaN;
|
|
27965
|
+
let lastLeft = Number.NaN;
|
|
27966
|
+
const track = () => {
|
|
27967
|
+
const rect = triggerRef.current?.getBoundingClientRect();
|
|
27968
|
+
if (rect && (rect.top !== lastTop || rect.left !== lastLeft)) {
|
|
27969
|
+
lastTop = rect.top;
|
|
27970
|
+
lastLeft = rect.left;
|
|
27971
|
+
updatePosition();
|
|
27972
|
+
}
|
|
27973
|
+
raf = requestAnimationFrame(track);
|
|
27974
|
+
};
|
|
27975
|
+
raf = requestAnimationFrame(track);
|
|
27976
|
+
return () => cancelAnimationFrame(raf);
|
|
27977
|
+
}, [isOpen]);
|
|
27739
27978
|
React92.useEffect(() => {
|
|
27740
27979
|
if (!mounted) setPopoverWidth(0);
|
|
27741
27980
|
}, [mounted]);
|
|
@@ -29084,6 +29323,80 @@ var init_FlipCard = __esm({
|
|
|
29084
29323
|
FlipCard.displayName = "FlipCard";
|
|
29085
29324
|
}
|
|
29086
29325
|
});
|
|
29326
|
+
var EMOJI_ITEMS, EmojiPicker;
|
|
29327
|
+
var init_EmojiPicker = __esm({
|
|
29328
|
+
"components/core/molecules/EmojiPicker.tsx"() {
|
|
29329
|
+
"use client";
|
|
29330
|
+
init_useEventBus();
|
|
29331
|
+
init_Button();
|
|
29332
|
+
init_GridPicker();
|
|
29333
|
+
init_Popover();
|
|
29334
|
+
EMOJI_ITEMS = (() => {
|
|
29335
|
+
const items = [];
|
|
29336
|
+
for (const name of emojilib.ordered) {
|
|
29337
|
+
const entry = emojilib.lib[name];
|
|
29338
|
+
if (entry === void 0 || entry.char === null || entry.char === "") continue;
|
|
29339
|
+
items.push({
|
|
29340
|
+
id: entry.char,
|
|
29341
|
+
label: name.replace(/_/g, " "),
|
|
29342
|
+
category: entry.category.replace(/_/g, " "),
|
|
29343
|
+
keywords: entry.keywords
|
|
29344
|
+
});
|
|
29345
|
+
}
|
|
29346
|
+
return items;
|
|
29347
|
+
})();
|
|
29348
|
+
EmojiPicker = ({
|
|
29349
|
+
pickEvent,
|
|
29350
|
+
position = "top",
|
|
29351
|
+
triggerIcon = "smile",
|
|
29352
|
+
triggerLabel = "Add emoji",
|
|
29353
|
+
className
|
|
29354
|
+
}) => {
|
|
29355
|
+
const eventBus = useEventBus();
|
|
29356
|
+
const [open, setOpen] = React92.useState(false);
|
|
29357
|
+
const handlePick = (glyph) => {
|
|
29358
|
+
if (pickEvent !== void 0) {
|
|
29359
|
+
const payload = { emoji: glyph };
|
|
29360
|
+
eventBus.emit(`UI:${pickEvent}`, payload);
|
|
29361
|
+
}
|
|
29362
|
+
setOpen(false);
|
|
29363
|
+
};
|
|
29364
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
29365
|
+
Popover,
|
|
29366
|
+
{
|
|
29367
|
+
position,
|
|
29368
|
+
trigger: "click",
|
|
29369
|
+
showArrow: false,
|
|
29370
|
+
open,
|
|
29371
|
+
onOpenChange: setOpen,
|
|
29372
|
+
content: /* @__PURE__ */ jsxRuntime.jsx(
|
|
29373
|
+
GridPicker,
|
|
29374
|
+
{
|
|
29375
|
+
items: EMOJI_ITEMS,
|
|
29376
|
+
onChange: handlePick,
|
|
29377
|
+
searchPlaceholder: "Search emoji\u2026",
|
|
29378
|
+
renderThumbnail: (item) => /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xl leading-none", "aria-hidden": "true", children: item.id }),
|
|
29379
|
+
cellSize: 32,
|
|
29380
|
+
className: "w-80"
|
|
29381
|
+
}
|
|
29382
|
+
),
|
|
29383
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
29384
|
+
Button,
|
|
29385
|
+
{
|
|
29386
|
+
variant: "ghost",
|
|
29387
|
+
icon: triggerIcon,
|
|
29388
|
+
"aria-label": triggerLabel,
|
|
29389
|
+
title: triggerLabel,
|
|
29390
|
+
className,
|
|
29391
|
+
"data-testid": "emoji-picker-trigger"
|
|
29392
|
+
}
|
|
29393
|
+
)
|
|
29394
|
+
}
|
|
29395
|
+
);
|
|
29396
|
+
};
|
|
29397
|
+
EmojiPicker.displayName = "EmojiPicker";
|
|
29398
|
+
}
|
|
29399
|
+
});
|
|
29087
29400
|
function toISODate(d) {
|
|
29088
29401
|
return d.toISOString().slice(0, 10);
|
|
29089
29402
|
}
|
|
@@ -30036,13 +30349,13 @@ var init_MapView = __esm({
|
|
|
30036
30349
|
shadowSize: [41, 41]
|
|
30037
30350
|
});
|
|
30038
30351
|
L.Marker.prototype.options.icon = defaultIcon;
|
|
30039
|
-
const { useEffect:
|
|
30352
|
+
const { useEffect: useEffect63, useRef: useRef63, useCallback: useCallback95, useState: useState99 } = React92__namespace.default;
|
|
30040
30353
|
const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
|
|
30041
30354
|
const { useEventBus: useEventBus2 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
|
|
30042
30355
|
function MapUpdater({ centerLat, centerLng, zoom }) {
|
|
30043
30356
|
const map = useMap();
|
|
30044
30357
|
const prevRef = useRef63({ centerLat, centerLng, zoom });
|
|
30045
|
-
|
|
30358
|
+
useEffect63(() => {
|
|
30046
30359
|
const prev = prevRef.current;
|
|
30047
30360
|
if (prev.centerLat !== centerLat || prev.centerLng !== centerLng || prev.zoom !== zoom) {
|
|
30048
30361
|
map.setView([centerLat, centerLng], zoom);
|
|
@@ -30053,7 +30366,7 @@ var init_MapView = __esm({
|
|
|
30053
30366
|
}
|
|
30054
30367
|
function MapClickHandler({ onMapClick }) {
|
|
30055
30368
|
const map = useMap();
|
|
30056
|
-
|
|
30369
|
+
useEffect63(() => {
|
|
30057
30370
|
if (!onMapClick) return;
|
|
30058
30371
|
const handler = (e) => {
|
|
30059
30372
|
onMapClick(e.latlng.lat, e.latlng.lng);
|
|
@@ -30081,7 +30394,7 @@ var init_MapView = __esm({
|
|
|
30081
30394
|
showAttribution = true
|
|
30082
30395
|
}) {
|
|
30083
30396
|
const eventBus = useEventBus2();
|
|
30084
|
-
const [clickedPosition, setClickedPosition] =
|
|
30397
|
+
const [clickedPosition, setClickedPosition] = useState99(null);
|
|
30085
30398
|
const handleMapClick = useCallback95((lat, lng) => {
|
|
30086
30399
|
if (showClickedPin) {
|
|
30087
30400
|
setClickedPosition({ lat, lng });
|
|
@@ -30926,6 +31239,7 @@ function TableView({
|
|
|
30926
31239
|
fields,
|
|
30927
31240
|
itemActions,
|
|
30928
31241
|
maxInlineActions,
|
|
31242
|
+
itemClickEvent,
|
|
30929
31243
|
selectable = false,
|
|
30930
31244
|
selectEvent,
|
|
30931
31245
|
selectedIds,
|
|
@@ -30970,9 +31284,9 @@ function TableView({
|
|
|
30970
31284
|
dndItemIdField,
|
|
30971
31285
|
dndRoot
|
|
30972
31286
|
});
|
|
30973
|
-
const
|
|
30974
|
-
const data = pageSize > 0 ?
|
|
30975
|
-
const hasMore = pageSize > 0 && visibleCount <
|
|
31287
|
+
const ordered2 = dnd.orderedItems;
|
|
31288
|
+
const data = pageSize > 0 ? ordered2.slice(0, visibleCount) : ordered2;
|
|
31289
|
+
const hasMore = pageSize > 0 && visibleCount < ordered2.length;
|
|
30976
31290
|
const hasRenderProp = typeof children === "function";
|
|
30977
31291
|
const idField = dndItemIdField ?? "id";
|
|
30978
31292
|
const isCoarsePointer = useMediaQuery("(pointer: coarse)");
|
|
@@ -31025,6 +31339,14 @@ function TableView({
|
|
|
31025
31339
|
};
|
|
31026
31340
|
eventBus.emit(`UI:${action.event}`, payload);
|
|
31027
31341
|
};
|
|
31342
|
+
const handleRowClick = (row) => () => {
|
|
31343
|
+
if (!itemClickEvent) return;
|
|
31344
|
+
const payload = {
|
|
31345
|
+
id: row.id,
|
|
31346
|
+
row
|
|
31347
|
+
};
|
|
31348
|
+
eventBus.emit(`UI:${itemClickEvent}`, payload);
|
|
31349
|
+
};
|
|
31028
31350
|
const colFloors = React92__namespace.default.useMemo(
|
|
31029
31351
|
() => colDefs.map((col) => {
|
|
31030
31352
|
const longest = data.reduce((widest, row) => {
|
|
@@ -31101,10 +31423,12 @@ function TableView({
|
|
|
31101
31423
|
role: "row",
|
|
31102
31424
|
"data-entity-row": true,
|
|
31103
31425
|
"data-entity-id": id,
|
|
31426
|
+
onClick: itemClickEvent ? handleRowClick(row) : void 0,
|
|
31104
31427
|
style: !hasRenderProp ? { gridTemplateColumns } : void 0,
|
|
31105
31428
|
className: cn(
|
|
31106
31429
|
"group items-center gap-3 transition-colors duration-fast",
|
|
31107
31430
|
hasRenderProp ? "flex" : "grid",
|
|
31431
|
+
itemClickEvent && "cursor-pointer",
|
|
31108
31432
|
lk.rowPad,
|
|
31109
31433
|
lk.divider && "border-b border-[var(--color-border)]",
|
|
31110
31434
|
lk.striped && index % 2 === 1 && "bg-[var(--color-surface-subtle)]",
|
|
@@ -31112,7 +31436,7 @@ function TableView({
|
|
|
31112
31436
|
look === "bordered" && "[&>*]:border-r [&>*]:border-[var(--color-border)] [&>*:last-child]:border-r-0"
|
|
31113
31437
|
),
|
|
31114
31438
|
children: [
|
|
31115
|
-
selectable && /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "flex items-center", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
31439
|
+
selectable && /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "flex items-center", onClick: itemClickEvent ? (e) => e.stopPropagation() : void 0, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
31116
31440
|
Checkbox,
|
|
31117
31441
|
{
|
|
31118
31442
|
checked: selected.has(id),
|
|
@@ -31137,6 +31461,7 @@ function TableView({
|
|
|
31137
31461
|
HStack,
|
|
31138
31462
|
{
|
|
31139
31463
|
gap: "xs",
|
|
31464
|
+
onClick: itemClickEvent ? (e) => e.stopPropagation() : void 0,
|
|
31140
31465
|
className: cn(
|
|
31141
31466
|
// Pinned: the fixed column tracks routinely overflow the caller's
|
|
31142
31467
|
// scroll container, which used to leave the actions off-screen.
|
|
@@ -31206,7 +31531,7 @@ function TableView({
|
|
|
31206
31531
|
/* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "chevron-down", size: "xs", className: "mr-1" }),
|
|
31207
31532
|
t("common.showMore"),
|
|
31208
31533
|
" (",
|
|
31209
|
-
t("common.remaining", { count:
|
|
31534
|
+
t("common.remaining", { count: ordered2.length - visibleCount }),
|
|
31210
31535
|
")"
|
|
31211
31536
|
] }) })
|
|
31212
31537
|
]
|
|
@@ -40236,6 +40561,16 @@ var init_DetailPanel = __esm({
|
|
|
40236
40561
|
DetailPanel.displayName = "DetailPanel";
|
|
40237
40562
|
}
|
|
40238
40563
|
});
|
|
40564
|
+
|
|
40565
|
+
// components/game/atoms/DrawGroup.tsx
|
|
40566
|
+
function DrawGroup(_props) {
|
|
40567
|
+
return null;
|
|
40568
|
+
}
|
|
40569
|
+
var init_DrawGroup = __esm({
|
|
40570
|
+
"components/game/atoms/DrawGroup.tsx"() {
|
|
40571
|
+
"use client";
|
|
40572
|
+
}
|
|
40573
|
+
});
|
|
40239
40574
|
function extractTitle(children) {
|
|
40240
40575
|
if (!React92__namespace.default.isValidElement(children)) return void 0;
|
|
40241
40576
|
const props = children.props;
|
|
@@ -45958,6 +46293,7 @@ var init_component_registry_generated = __esm({
|
|
|
45958
46293
|
init_DocSidebar();
|
|
45959
46294
|
init_DocTOC();
|
|
45960
46295
|
init_DocumentViewer();
|
|
46296
|
+
init_DrawGroup();
|
|
45961
46297
|
init_DrawShape();
|
|
45962
46298
|
init_DrawShapeLayer();
|
|
45963
46299
|
init_DrawSprite();
|
|
@@ -45967,6 +46303,7 @@ var init_component_registry_generated = __esm({
|
|
|
45967
46303
|
init_Drawer();
|
|
45968
46304
|
init_DrawerSlot();
|
|
45969
46305
|
init_EdgeDecoration();
|
|
46306
|
+
init_EmojiPicker();
|
|
45970
46307
|
init_EmptyState();
|
|
45971
46308
|
init_ErrorBoundary();
|
|
45972
46309
|
init_ErrorState();
|
|
@@ -46101,10 +46438,6 @@ var init_component_registry_generated = __esm({
|
|
|
46101
46438
|
init_SubagentTracePanel();
|
|
46102
46439
|
init_SvgBranch();
|
|
46103
46440
|
init_SvgConnection();
|
|
46104
|
-
init_SvgDrawGroup();
|
|
46105
|
-
init_SvgDrawShape();
|
|
46106
|
-
init_SvgDrawShapeLayer();
|
|
46107
|
-
init_SvgDrawText();
|
|
46108
46441
|
init_SvgFlow();
|
|
46109
46442
|
init_SvgGrid();
|
|
46110
46443
|
init_SvgLobe();
|
|
@@ -46115,7 +46448,6 @@ var init_component_registry_generated = __esm({
|
|
|
46115
46448
|
init_SvgRing();
|
|
46116
46449
|
init_SvgShield();
|
|
46117
46450
|
init_SvgStack();
|
|
46118
|
-
init_SvgStage();
|
|
46119
46451
|
init_SwipeableRow();
|
|
46120
46452
|
init_Switch();
|
|
46121
46453
|
init_TabbedContainer();
|
|
@@ -46229,6 +46561,7 @@ var init_component_registry_generated = __esm({
|
|
|
46229
46561
|
"DocSidebar": DocSidebar,
|
|
46230
46562
|
"DocTOC": DocTOC,
|
|
46231
46563
|
"DocumentViewer": DocumentViewer,
|
|
46564
|
+
"DrawGroup": DrawGroup,
|
|
46232
46565
|
"DrawShape": DrawShape,
|
|
46233
46566
|
"DrawShapeLayer": DrawShapeLayer,
|
|
46234
46567
|
"DrawSprite": DrawSprite,
|
|
@@ -46238,6 +46571,7 @@ var init_component_registry_generated = __esm({
|
|
|
46238
46571
|
"Drawer": Drawer,
|
|
46239
46572
|
"DrawerSlot": DrawerSlot,
|
|
46240
46573
|
"EdgeDecoration": EdgeDecoration,
|
|
46574
|
+
"EmojiPicker": EmojiPicker,
|
|
46241
46575
|
"EmptyState": EmptyState,
|
|
46242
46576
|
"ErrorBoundary": ErrorBoundary,
|
|
46243
46577
|
"ErrorState": ErrorState,
|
|
@@ -46377,10 +46711,6 @@ var init_component_registry_generated = __esm({
|
|
|
46377
46711
|
"SubagentTracePanel": SubagentTracePanel,
|
|
46378
46712
|
"SvgBranch": SvgBranch,
|
|
46379
46713
|
"SvgConnection": SvgConnection,
|
|
46380
|
-
"SvgDrawGroup": SvgDrawGroup,
|
|
46381
|
-
"SvgDrawShape": SvgDrawShape,
|
|
46382
|
-
"SvgDrawShapeLayer": SvgDrawShapeLayer,
|
|
46383
|
-
"SvgDrawText": SvgDrawText,
|
|
46384
46714
|
"SvgFlow": SvgFlow,
|
|
46385
46715
|
"SvgGrid": SvgGrid,
|
|
46386
46716
|
"SvgLobe": SvgLobe,
|
|
@@ -46391,7 +46721,6 @@ var init_component_registry_generated = __esm({
|
|
|
46391
46721
|
"SvgRing": SvgRing,
|
|
46392
46722
|
"SvgShield": SvgShield,
|
|
46393
46723
|
"SvgStack": SvgStack,
|
|
46394
|
-
"SvgStage": SvgStage,
|
|
46395
46724
|
"SwipeableRow": SwipeableRow,
|
|
46396
46725
|
"Switch": Switch,
|
|
46397
46726
|
"TabbedContainer": TabbedContainer,
|
|
@@ -46670,7 +46999,19 @@ function UISlotComponent({
|
|
|
46670
46999
|
const suspenseConfig = React92.useContext(SuspenseConfigContext);
|
|
46671
47000
|
const contained = React92.useContext(SlotContainedContext);
|
|
46672
47001
|
const schemaCtx = providers.useEntitySchemaOptional();
|
|
46673
|
-
const
|
|
47002
|
+
const rawContent = slots[slot];
|
|
47003
|
+
const binding = providers.useEntityBindingSnapshot(rawContent?.sourceTrait);
|
|
47004
|
+
const content = React92.useMemo(() => {
|
|
47005
|
+
if (!rawContent) return rawContent;
|
|
47006
|
+
const resolvedProps = resolveRenderBindingMarkers(
|
|
47007
|
+
rawContent.props,
|
|
47008
|
+
rawContent.sourceTrait,
|
|
47009
|
+
binding.entity,
|
|
47010
|
+
binding.config,
|
|
47011
|
+
binding.state
|
|
47012
|
+
);
|
|
47013
|
+
return resolvedProps === rawContent.props ? rawContent : { ...rawContent, props: resolvedProps };
|
|
47014
|
+
}, [rawContent, binding.entity, binding.config, binding.state]);
|
|
46674
47015
|
if (children !== void 0) {
|
|
46675
47016
|
if (pattern === "clear") {
|
|
46676
47017
|
return null;
|
|
@@ -47014,6 +47355,7 @@ function isPlainConfigObject(value) {
|
|
|
47014
47355
|
return proto === Object.prototype || proto === null;
|
|
47015
47356
|
}
|
|
47016
47357
|
function substituteTraitRefsDeep(value, pathKey) {
|
|
47358
|
+
if (core.isRenderBindingMarker(value)) return value;
|
|
47017
47359
|
if (typeof value === "string") {
|
|
47018
47360
|
const match = TRAIT_BINDING_RE.exec(value);
|
|
47019
47361
|
if (match) {
|
|
@@ -47086,7 +47428,14 @@ function SlotContentRenderer({
|
|
|
47086
47428
|
onDismiss,
|
|
47087
47429
|
patternPath
|
|
47088
47430
|
}) {
|
|
47089
|
-
const
|
|
47431
|
+
const ambientScope = providers.useTraitScope();
|
|
47432
|
+
const bindingTrait = content.sourceTrait ?? ambientScope?.trait;
|
|
47433
|
+
const binding = providers.useEntityBindingSnapshot(bindingTrait);
|
|
47434
|
+
const liveProps = React92.useMemo(
|
|
47435
|
+
() => resolveRenderBindingMarkers(content.props, bindingTrait, binding.entity, binding.config, binding.state),
|
|
47436
|
+
[content.props, bindingTrait, binding.entity, binding.config, binding.state]
|
|
47437
|
+
);
|
|
47438
|
+
const entityProp = liveProps.entity;
|
|
47090
47439
|
if (content.pattern === "form-section") {
|
|
47091
47440
|
slotLog.debug("SlotContentRenderer:form-section-render", {
|
|
47092
47441
|
contentId: content.id,
|
|
@@ -47117,7 +47466,7 @@ function SlotContentRenderer({
|
|
|
47117
47466
|
const orbitalName = schemaCtx && content.sourceTrait !== void 0 ? schemaCtx.orbitalsByTrait.get(content.sourceTrait) : void 0;
|
|
47118
47467
|
const PatternComponent = getComponentForPattern(content.pattern);
|
|
47119
47468
|
if (PatternComponent) {
|
|
47120
|
-
const childrenConfig =
|
|
47469
|
+
const childrenConfig = liveProps.children;
|
|
47121
47470
|
const isSingleChild = typeof childrenConfig === "string" || typeof childrenConfig === "object" && childrenConfig !== null && !Array.isArray(childrenConfig) && "type" in childrenConfig;
|
|
47122
47471
|
const hasChildren = PATTERNS_WITH_CHILDREN.has(content.pattern) || Array.isArray(childrenConfig) && childrenConfig.length > 0 || isSingleChild;
|
|
47123
47472
|
const isDrawHost = patterns.isDrawHostPattern(content.pattern);
|
|
@@ -47128,9 +47477,9 @@ function SlotContentRenderer({
|
|
|
47128
47477
|
fromState: content.fromState,
|
|
47129
47478
|
entity: content.entity
|
|
47130
47479
|
}) : void 0;
|
|
47131
|
-
const incomingChildren =
|
|
47480
|
+
const incomingChildren = liveProps.children;
|
|
47132
47481
|
const childrenIsRenderFn = typeof incomingChildren === "function";
|
|
47133
|
-
const { children: _childrenConfig, ...restPropsNoChildren } =
|
|
47482
|
+
const { children: _childrenConfig, ...restPropsNoChildren } = liveProps;
|
|
47134
47483
|
const restProps = childrenIsRenderFn ? { ...restPropsNoChildren, children: incomingChildren } : restPropsNoChildren;
|
|
47135
47484
|
const nodeSlotOverrides = {};
|
|
47136
47485
|
for (const slotKey of CONTENT_NODE_SLOTS) {
|
|
@@ -47239,7 +47588,7 @@ function SlotContentRenderer({
|
|
|
47239
47588
|
"data-orb-path": patternPath ?? "root",
|
|
47240
47589
|
"data-orb-pattern": content.pattern,
|
|
47241
47590
|
"data-orb-orbital": orbitalName,
|
|
47242
|
-
children:
|
|
47591
|
+
children: liveProps.children ?? /* @__PURE__ */ jsxRuntime.jsxs(Box, { className: "p-4 text-sm text-muted-foreground border border-dashed border-border rounded", children: [
|
|
47243
47592
|
"Unknown pattern: ",
|
|
47244
47593
|
content.pattern,
|
|
47245
47594
|
content.sourceTrait && /* @__PURE__ */ jsxRuntime.jsxs(Typography, { variant: "small", className: "ml-2", children: [
|
|
@@ -47311,6 +47660,7 @@ var scopeWrapLog, TRAIT_BINDING_RE, SuspenseConfigContext, SlotContainedContext,
|
|
|
47311
47660
|
var init_UISlotRenderer = __esm({
|
|
47312
47661
|
"components/core/organisms/UISlotRenderer.tsx"() {
|
|
47313
47662
|
"use client";
|
|
47663
|
+
init_resolve_render_bindings();
|
|
47314
47664
|
init_Modal();
|
|
47315
47665
|
init_Drawer();
|
|
47316
47666
|
init_Toast();
|
|
@@ -50812,6 +51162,9 @@ function resolveLambdaBindings(body, params, item, index) {
|
|
|
50812
51162
|
const arr = body;
|
|
50813
51163
|
const substituted = arr.map((b) => recur(b));
|
|
50814
51164
|
if (isOperatorCall(substituted) && core.isSExpr(substituted)) {
|
|
51165
|
+
if (core.containsEntityBinding(substituted)) {
|
|
51166
|
+
return substituted;
|
|
51167
|
+
}
|
|
50815
51168
|
const evaluated = evaluator.evaluate(substituted, evaluator.createMinimalContext());
|
|
50816
51169
|
return core.isEventPayloadValue(evaluated) ? evaluated : String(evaluated);
|
|
50817
51170
|
}
|
|
@@ -50833,9 +51186,37 @@ function getSlotContentRenderer2() {
|
|
|
50833
51186
|
_slotContentRenderer2 = mod.SlotContentRenderer;
|
|
50834
51187
|
return _slotContentRenderer2;
|
|
50835
51188
|
}
|
|
51189
|
+
function deferLambdaEntityExprs(value) {
|
|
51190
|
+
if (typeof value === "string") {
|
|
51191
|
+
if (core.containsEntityBinding(value)) {
|
|
51192
|
+
const marker = { [core.RENDER_BINDING_MARKER]: true, expression: value };
|
|
51193
|
+
return marker;
|
|
51194
|
+
}
|
|
51195
|
+
return value;
|
|
51196
|
+
}
|
|
51197
|
+
if (Array.isArray(value)) {
|
|
51198
|
+
if (isFnFormLambda(value)) return value;
|
|
51199
|
+
const arr = value;
|
|
51200
|
+
if (isOperatorCall(arr) && core.isSExpr(arr) && core.containsEntityBinding(arr)) {
|
|
51201
|
+
const marker = { [core.RENDER_BINDING_MARKER]: true, expression: arr };
|
|
51202
|
+
return marker;
|
|
51203
|
+
}
|
|
51204
|
+
return arr.map((v) => deferLambdaEntityExprs(v));
|
|
51205
|
+
}
|
|
51206
|
+
if (value !== null && typeof value === "object" && !React92__namespace.default.isValidElement(value) && !(value instanceof Date) && typeof value !== "function" && !core.isRenderBindingMarker(value)) {
|
|
51207
|
+
const out = {};
|
|
51208
|
+
for (const [k, v] of Object.entries(value)) {
|
|
51209
|
+
out[k] = deferLambdaEntityExprs(v);
|
|
51210
|
+
}
|
|
51211
|
+
return out;
|
|
51212
|
+
}
|
|
51213
|
+
return value;
|
|
51214
|
+
}
|
|
50836
51215
|
function makeLambdaFn(params, lambdaBody, callerKey) {
|
|
50837
51216
|
return (item, index) => {
|
|
50838
|
-
const resolvedBody =
|
|
51217
|
+
const resolvedBody = deferLambdaEntityExprs(
|
|
51218
|
+
resolveLambdaBindings(lambdaBody, params, item, index)
|
|
51219
|
+
);
|
|
50839
51220
|
if (resolvedBody === null || typeof resolvedBody !== "object" || Array.isArray(resolvedBody) || typeof resolvedBody === "function" || React92__namespace.default.isValidElement(resolvedBody) || resolvedBody instanceof Date) {
|
|
50840
51221
|
return null;
|
|
50841
51222
|
}
|
|
@@ -50860,6 +51241,7 @@ function makeLambdaFn(params, lambdaBody, callerKey) {
|
|
|
50860
51241
|
}
|
|
50861
51242
|
function convertNode(node, callerKey) {
|
|
50862
51243
|
if (node === null || node === void 0) return node;
|
|
51244
|
+
if (core.isRenderBindingMarker(node)) return node;
|
|
50863
51245
|
if (Array.isArray(node)) {
|
|
50864
51246
|
if (isFnFormLambda(node)) {
|
|
50865
51247
|
const arr2 = node;
|
|
@@ -51033,6 +51415,7 @@ var tickLog = logger.createLogger("almadar:ui:tick-effects");
|
|
|
51033
51415
|
logger.setNamespaceLevel("almadar:ui:tick-effects", "WARN");
|
|
51034
51416
|
var sharedEntityLog = logger.createLogger("almadar:ui:shared-entity");
|
|
51035
51417
|
logger.setNamespaceLevel("almadar:ui:shared-entity", "WARN");
|
|
51418
|
+
var EMPTY_BINDING_SNAPSHOT = {};
|
|
51036
51419
|
var SYNC_TICK_OPERATORS = /* @__PURE__ */ new Set([
|
|
51037
51420
|
"set",
|
|
51038
51421
|
"emit",
|
|
@@ -51053,11 +51436,6 @@ var SYNC_TICK_OPERATORS = /* @__PURE__ */ new Set([
|
|
|
51053
51436
|
"do",
|
|
51054
51437
|
"when"
|
|
51055
51438
|
]);
|
|
51056
|
-
var REACTIVE_REPAINT_PATTERN_TYPES = /* @__PURE__ */ new Set([
|
|
51057
|
-
"canvas",
|
|
51058
|
-
"game-hud",
|
|
51059
|
-
"game-shell"
|
|
51060
|
-
]);
|
|
51061
51439
|
var LIFECYCLE_EVENTS = ["INIT", "LOAD", "$MOUNT"];
|
|
51062
51440
|
function toTraitDefinition(binding) {
|
|
51063
51441
|
return {
|
|
@@ -51098,6 +51476,27 @@ function classifySharedTick(tick) {
|
|
|
51098
51476
|
if (renders) return "renderer";
|
|
51099
51477
|
return "neither";
|
|
51100
51478
|
}
|
|
51479
|
+
function buildTraitRenderConfig(binding, traitConfigsByName, payload) {
|
|
51480
|
+
const declaredDefaults = runtime.collectDeclaredConfigDefaults(binding.trait);
|
|
51481
|
+
const resolvedDefaults = traitConfigsByName?.[binding.trait.name];
|
|
51482
|
+
const callSiteConfig = getBindingConfig(binding);
|
|
51483
|
+
const callSiteOverrides = callSiteConfig ? runtime.resolveCallSitePayloadCaptures(
|
|
51484
|
+
Object.fromEntries(
|
|
51485
|
+
Object.entries(callSiteConfig).filter(
|
|
51486
|
+
([, v]) => !containsConfigForward(v)
|
|
51487
|
+
)
|
|
51488
|
+
),
|
|
51489
|
+
payload
|
|
51490
|
+
) : void 0;
|
|
51491
|
+
if (declaredDefaults || resolvedDefaults || callSiteOverrides) {
|
|
51492
|
+
return {
|
|
51493
|
+
...declaredDefaults ?? {},
|
|
51494
|
+
...resolvedDefaults ?? {},
|
|
51495
|
+
...callSiteOverrides ?? {}
|
|
51496
|
+
};
|
|
51497
|
+
}
|
|
51498
|
+
return void 0;
|
|
51499
|
+
}
|
|
51101
51500
|
function createSharedEntityWriter(binding, tick, traitStatesRef, emit) {
|
|
51102
51501
|
return (scratch) => {
|
|
51103
51502
|
const traitName = binding.trait.name;
|
|
@@ -51318,8 +51717,24 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
51318
51717
|
}, [traitStates]);
|
|
51319
51718
|
const traitSnapshotDataRef = React92.useRef(/* @__PURE__ */ new Map());
|
|
51320
51719
|
const traitFieldStatesRef = React92.useRef(/* @__PURE__ */ new Map());
|
|
51321
|
-
const
|
|
51322
|
-
const
|
|
51720
|
+
const bridgeEchoPendingRef = React92.useRef(/* @__PURE__ */ new Map());
|
|
51721
|
+
const bindingSnapshotsRef = React92.useRef(/* @__PURE__ */ new Map());
|
|
51722
|
+
const bindingListenersRef = React92.useRef(/* @__PURE__ */ new Map());
|
|
51723
|
+
const publishBindingSnapshot = React92.useCallback((traitName, row) => {
|
|
51724
|
+
bindingSnapshotsRef.current.set(traitName, { ...row });
|
|
51725
|
+
const listeners7 = bindingListenersRef.current.get(traitName);
|
|
51726
|
+
if (!listeners7) return;
|
|
51727
|
+
listeners7.forEach((callback) => {
|
|
51728
|
+
try {
|
|
51729
|
+
callback();
|
|
51730
|
+
} catch (error) {
|
|
51731
|
+
stateLog.error("binding-snapshot listener error", {
|
|
51732
|
+
traitName,
|
|
51733
|
+
error: error instanceof Error ? error.message : String(error)
|
|
51734
|
+
});
|
|
51735
|
+
}
|
|
51736
|
+
});
|
|
51737
|
+
}, []);
|
|
51323
51738
|
React92.useEffect(() => {
|
|
51324
51739
|
const mgr = managerRef.current;
|
|
51325
51740
|
const bindings = traitBindingsRef.current;
|
|
@@ -51447,15 +51862,6 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
51447
51862
|
const existing = pendingSlots.get(slot) || [];
|
|
51448
51863
|
existing.push({ pattern, props: props || {} });
|
|
51449
51864
|
pendingSlots.set(slot, existing);
|
|
51450
|
-
const patternType = pattern?.type;
|
|
51451
|
-
if (patternType !== void 0 && REACTIVE_REPAINT_PATTERN_TYPES.has(patternType)) {
|
|
51452
|
-
const rawForSlot = effects.filter(
|
|
51453
|
-
(e) => Array.isArray(e) && (e[0] === "render-ui" || e[0] === "render") && e[1] === slot
|
|
51454
|
-
);
|
|
51455
|
-
if (rawForSlot.length > 0) {
|
|
51456
|
-
lastCanvasRenderUiRef.current.set(traitName, rawForSlot);
|
|
51457
|
-
}
|
|
51458
|
-
}
|
|
51459
51865
|
},
|
|
51460
51866
|
clearSlot: (slot) => {
|
|
51461
51867
|
pendingSlots.set(slot, []);
|
|
@@ -51527,11 +51933,13 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
51527
51933
|
};
|
|
51528
51934
|
}
|
|
51529
51935
|
const sharedWrites = [];
|
|
51936
|
+
let didWrite = false;
|
|
51530
51937
|
const baseSet = handlers.set;
|
|
51531
51938
|
handlers = {
|
|
51532
51939
|
...handlers,
|
|
51533
51940
|
set: async (targetId, field, value) => {
|
|
51534
51941
|
if (baseSet) await baseSet(targetId, field, value);
|
|
51942
|
+
didWrite = true;
|
|
51535
51943
|
if (sharedKey !== void 0) {
|
|
51536
51944
|
sharedWrites.push({ field, value });
|
|
51537
51945
|
}
|
|
@@ -51548,23 +51956,9 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
51548
51956
|
payload: payload || {},
|
|
51549
51957
|
state: previousState
|
|
51550
51958
|
};
|
|
51551
|
-
const
|
|
51552
|
-
|
|
51553
|
-
|
|
51554
|
-
const callSiteOverrides = callSiteConfig ? runtime.resolveCallSitePayloadCaptures(
|
|
51555
|
-
Object.fromEntries(
|
|
51556
|
-
Object.entries(callSiteConfig).filter(
|
|
51557
|
-
([, v]) => !containsConfigForward(v)
|
|
51558
|
-
)
|
|
51559
|
-
),
|
|
51560
|
-
payload || {}
|
|
51561
|
-
) : void 0;
|
|
51562
|
-
if (declaredDefaults || resolvedDefaults || callSiteOverrides) {
|
|
51563
|
-
bindingCtx.config = {
|
|
51564
|
-
...declaredDefaults ?? {},
|
|
51565
|
-
...resolvedDefaults ?? {},
|
|
51566
|
-
...callSiteOverrides ?? {}
|
|
51567
|
-
};
|
|
51959
|
+
const renderConfig = buildTraitRenderConfig(binding, traitConfigsByName, payload || {});
|
|
51960
|
+
if (renderConfig !== void 0) {
|
|
51961
|
+
bindingCtx.config = renderConfig;
|
|
51568
51962
|
}
|
|
51569
51963
|
if (traitName === "Authority" || traitName === "Hero") {
|
|
51570
51964
|
sharedEntityLog.debug("executeTransitionEffects config tiles", {
|
|
@@ -51598,7 +51992,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
51598
51992
|
effectHeads: effects.map((e) => Array.isArray(e) ? String(e[0]) : "??")
|
|
51599
51993
|
});
|
|
51600
51994
|
}
|
|
51601
|
-
const executor = new runtime.EffectExecutor({ handlers: trackingHandlers, bindings: bindingCtx, context: effectContext });
|
|
51995
|
+
const executor = new runtime.EffectExecutor({ handlers: trackingHandlers, bindings: bindingCtx, context: effectContext, deferRenderBindings: true });
|
|
51602
51996
|
try {
|
|
51603
51997
|
await executor.executeAll(effects);
|
|
51604
51998
|
if (traitName === "Authority" || traitName === "Hero") {
|
|
@@ -51639,37 +52033,8 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
51639
52033
|
entity: binding.linkedEntity
|
|
51640
52034
|
});
|
|
51641
52035
|
}
|
|
51642
|
-
if (
|
|
51643
|
-
|
|
51644
|
-
if (stashed !== void 0 && stashed.length > 0) {
|
|
51645
|
-
await executor.executeAll(stashed);
|
|
51646
|
-
for (const [slot, patterns] of pendingSlots) {
|
|
51647
|
-
flushSlot(traitName, slot, patterns, {
|
|
51648
|
-
event: flushEvent,
|
|
51649
|
-
state: previousState,
|
|
51650
|
-
entity: binding.linkedEntity
|
|
51651
|
-
});
|
|
51652
|
-
}
|
|
51653
|
-
}
|
|
51654
|
-
if (sharedKey !== void 0 && executeTransitionEffectsRef.current !== null) {
|
|
51655
|
-
for (const sibling of traitBindingsRef.current) {
|
|
51656
|
-
const siblingName = sibling.trait.name;
|
|
51657
|
-
if (siblingName === traitName) continue;
|
|
51658
|
-
if (sharedKeyByTraitNameRef.current.get(siblingName) !== sharedKey) continue;
|
|
51659
|
-
const siblingStash = lastCanvasRenderUiRef.current.get(siblingName);
|
|
51660
|
-
if (siblingStash === void 0 || siblingStash.length === 0) continue;
|
|
51661
|
-
const siblingState = traitStatesRef.current.get(siblingName)?.currentState ?? "";
|
|
51662
|
-
await executeTransitionEffectsRef.current({
|
|
51663
|
-
binding: sibling,
|
|
51664
|
-
effects: siblingStash,
|
|
51665
|
-
previousState: siblingState,
|
|
51666
|
-
newState: siblingState,
|
|
51667
|
-
flushEvent: `${flushEvent}:repaint`,
|
|
51668
|
-
syncOnly,
|
|
51669
|
-
log: log11
|
|
51670
|
-
});
|
|
51671
|
-
}
|
|
51672
|
-
}
|
|
52036
|
+
if (didWrite && sharedKey === void 0) {
|
|
52037
|
+
publishBindingSnapshot(traitName, liveEntity);
|
|
51673
52038
|
}
|
|
51674
52039
|
} catch (error) {
|
|
51675
52040
|
log11.error("effects:error", {
|
|
@@ -51681,10 +52046,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
51681
52046
|
});
|
|
51682
52047
|
}
|
|
51683
52048
|
return emittedDuringExec;
|
|
51684
|
-
}, [eventBus, flushSlot, sharedEntityStore]);
|
|
51685
|
-
React92.useEffect(() => {
|
|
51686
|
-
executeTransitionEffectsRef.current = executeTransitionEffects;
|
|
51687
|
-
}, [executeTransitionEffects]);
|
|
52049
|
+
}, [eventBus, flushSlot, sharedEntityStore, publishBindingSnapshot]);
|
|
51688
52050
|
const runTickEffects = React92.useCallback((tick, binding) => {
|
|
51689
52051
|
const traitName = binding.trait.name;
|
|
51690
52052
|
const currentState = traitStatesRef.current.get(traitName)?.currentState ?? "";
|
|
@@ -51747,24 +52109,6 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
51747
52109
|
({ binding, tick }) => createSharedEntityWriter(binding, tick, traitStatesRef, emitFromSharedWriter)
|
|
51748
52110
|
);
|
|
51749
52111
|
runTickFrame(group.storeKey, writers, sharedEntityStore);
|
|
51750
|
-
const repaint = executeTransitionEffectsRef.current;
|
|
51751
|
-
if (repaint !== null) {
|
|
51752
|
-
for (const renderBinding of group.renderBindings) {
|
|
51753
|
-
const renderTraitName = renderBinding.trait.name;
|
|
51754
|
-
const stash = lastCanvasRenderUiRef.current.get(renderTraitName);
|
|
51755
|
-
if (stash === void 0 || stash.length === 0) continue;
|
|
51756
|
-
const renderState = traitStatesRef.current.get(renderTraitName)?.currentState ?? "";
|
|
51757
|
-
void repaint({
|
|
51758
|
-
binding: renderBinding,
|
|
51759
|
-
effects: stash,
|
|
51760
|
-
previousState: renderState,
|
|
51761
|
-
newState: renderState,
|
|
51762
|
-
flushEvent: "tick:repaint",
|
|
51763
|
-
syncOnly: true,
|
|
51764
|
-
log: sharedEntityLog
|
|
51765
|
-
});
|
|
51766
|
-
}
|
|
51767
|
-
}
|
|
51768
52112
|
};
|
|
51769
52113
|
if (interval === "frame") {
|
|
51770
52114
|
scheduler.add(0, onDue);
|
|
@@ -51835,6 +52179,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
51835
52179
|
executedTraits: results.map((r2) => r2.traitName).join(",")
|
|
51836
52180
|
});
|
|
51837
52181
|
const emittedByTrait = /* @__PURE__ */ new Map();
|
|
52182
|
+
bridgeEchoPendingRef.current.clear();
|
|
51838
52183
|
for (const { traitName, result } of results) {
|
|
51839
52184
|
const binding = bindingMap.get(traitName);
|
|
51840
52185
|
const traitState = currentManager.getState(traitName);
|
|
@@ -51889,6 +52234,12 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
51889
52234
|
log: stateLog
|
|
51890
52235
|
});
|
|
51891
52236
|
emittedByTrait.set(traitName, emittedDuringExec);
|
|
52237
|
+
for (const emittedKey of emittedDuringExec) {
|
|
52238
|
+
bridgeEchoPendingRef.current.set(
|
|
52239
|
+
emittedKey,
|
|
52240
|
+
(bridgeEchoPendingRef.current.get(emittedKey) ?? 0) + 1
|
|
52241
|
+
);
|
|
52242
|
+
}
|
|
51892
52243
|
} else if (!result.executed) {
|
|
51893
52244
|
if (result.guardResult === false) {
|
|
51894
52245
|
stateLog.debug("guard-blocked-transition", {
|
|
@@ -52038,8 +52389,13 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
52038
52389
|
crossTraitLog.debug("self:subscribe", { traitName, busKey: selfBusKey, eventKey });
|
|
52039
52390
|
const unsub = eventBus.on(selfBusKey, (event) => {
|
|
52040
52391
|
if (event.source && event.source.dispatched) {
|
|
52041
|
-
|
|
52042
|
-
|
|
52392
|
+
const pendingEchoes = bridgeEchoPendingRef.current.get(eventKey) ?? 0;
|
|
52393
|
+
if (pendingEchoes > 0) {
|
|
52394
|
+
bridgeEchoPendingRef.current.set(eventKey, pendingEchoes - 1);
|
|
52395
|
+
crossTraitLog.debug("self:fire-skipped-bridge-echo", { traitName, busKey: selfBusKey, eventKey });
|
|
52396
|
+
return;
|
|
52397
|
+
}
|
|
52398
|
+
crossTraitLog.debug("self:fire-server-cascade", { traitName, busKey: selfBusKey, eventKey });
|
|
52043
52399
|
}
|
|
52044
52400
|
crossTraitLog.debug("self:fire", { traitName, busKey: selfBusKey, eventKey });
|
|
52045
52401
|
enqueueAndDrain(eventKey, event.payload, traitName);
|
|
@@ -52131,11 +52487,47 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
52131
52487
|
initedTraitsRef.current = /* @__PURE__ */ new Set();
|
|
52132
52488
|
};
|
|
52133
52489
|
}, [traitBindings, enqueueAndDrain]);
|
|
52490
|
+
const entityBindingSource = React92.useMemo(() => ({
|
|
52491
|
+
getEntitySnapshot: (traitName) => {
|
|
52492
|
+
const sharedKey = sharedKeyByTraitNameRef.current.get(traitName);
|
|
52493
|
+
if (sharedKey !== void 0) {
|
|
52494
|
+
return sharedEntityStore.getSnapshot(sharedKey);
|
|
52495
|
+
}
|
|
52496
|
+
return bindingSnapshotsRef.current.get(traitName) ?? EMPTY_BINDING_SNAPSHOT;
|
|
52497
|
+
},
|
|
52498
|
+
getConfig: (traitName) => {
|
|
52499
|
+
const binding = traitBindingsRef.current.find((b) => b.trait.name === traitName);
|
|
52500
|
+
if (binding === void 0) return void 0;
|
|
52501
|
+
return buildTraitRenderConfig(binding, traitConfigsByName, {});
|
|
52502
|
+
},
|
|
52503
|
+
getState: (traitName) => traitStatesRef.current.get(traitName)?.currentState ?? "",
|
|
52504
|
+
subscribe: (traitName, callback) => {
|
|
52505
|
+
const sharedKey = sharedKeyByTraitNameRef.current.get(traitName);
|
|
52506
|
+
if (sharedKey !== void 0) {
|
|
52507
|
+
return sharedEntityStore.subscribe(sharedKey, callback);
|
|
52508
|
+
}
|
|
52509
|
+
let listeners7 = bindingListenersRef.current.get(traitName);
|
|
52510
|
+
if (!listeners7) {
|
|
52511
|
+
listeners7 = /* @__PURE__ */ new Set();
|
|
52512
|
+
bindingListenersRef.current.set(traitName, listeners7);
|
|
52513
|
+
}
|
|
52514
|
+
listeners7.add(callback);
|
|
52515
|
+
return () => {
|
|
52516
|
+
const current = bindingListenersRef.current.get(traitName);
|
|
52517
|
+
if (!current) return;
|
|
52518
|
+
current.delete(callback);
|
|
52519
|
+
if (current.size === 0) {
|
|
52520
|
+
bindingListenersRef.current.delete(traitName);
|
|
52521
|
+
}
|
|
52522
|
+
};
|
|
52523
|
+
}
|
|
52524
|
+
}), [sharedEntityStore, traitConfigsByName]);
|
|
52134
52525
|
return {
|
|
52135
52526
|
traitStates,
|
|
52136
52527
|
sendEvent,
|
|
52137
52528
|
getTraitState,
|
|
52138
|
-
canHandleEvent
|
|
52529
|
+
canHandleEvent,
|
|
52530
|
+
entityBindingSource
|
|
52139
52531
|
};
|
|
52140
52532
|
}
|
|
52141
52533
|
|
|
@@ -52224,7 +52616,7 @@ function collectServerActiveTraits(ir, allTraits, mountedTraitNames) {
|
|
|
52224
52616
|
}
|
|
52225
52617
|
return active;
|
|
52226
52618
|
}
|
|
52227
|
-
function TraitInitializer({ traits: traits2, routeParams, orbitalNames, onNavigate, onLocalFallback, persistence, traitConfigsByName, orbitalsByTrait, embeddedTraits, serverActiveTraits }) {
|
|
52619
|
+
function TraitInitializer({ traits: traits2, routeParams, orbitalNames, onNavigate, onLocalFallback, persistence, traitConfigsByName, orbitalsByTrait, embeddedTraits, serverActiveTraits, children }) {
|
|
52228
52620
|
const bridge = providers.useServerBridge();
|
|
52229
52621
|
const activeTraitNames = React92.useMemo(
|
|
52230
52622
|
() => new Set(traits2.map((b) => b.trait.name).filter((n) => !!n)),
|
|
@@ -52254,7 +52646,7 @@ function TraitInitializer({ traits: traits2, routeParams, orbitalNames, onNaviga
|
|
|
52254
52646
|
}
|
|
52255
52647
|
}, [bridge.connected, bridge.sendEvent, orbitalNames, uiSlots, onNavigate, embeddedTraits, activeTraitNames, withActiveTraits]);
|
|
52256
52648
|
const opts = orbitalNames ? { onEventProcessed, navigate: onNavigate, traitConfigsByName, orbitalsByTrait, embeddedTraits, initPayload: routeParams } : { navigate: onNavigate, persistence, traitConfigsByName, orbitalsByTrait, embeddedTraits, initPayload: routeParams };
|
|
52257
|
-
const { sendEvent } = useTraitStateMachine(traits2, uiSlots, opts);
|
|
52649
|
+
const { sendEvent, entityBindingSource } = useTraitStateMachine(traits2, uiSlots, opts);
|
|
52258
52650
|
const initSentRef = React92.useRef(false);
|
|
52259
52651
|
const prevTraitsRef = React92.useRef(void 0);
|
|
52260
52652
|
const paramsKey = JSON.stringify(routeParams ?? {});
|
|
@@ -52300,7 +52692,7 @@ function TraitInitializer({ traits: traits2, routeParams, orbitalNames, onNaviga
|
|
|
52300
52692
|
{ type: "fetch", args: [], status: "executed" },
|
|
52301
52693
|
...effects.map((eff) => ({
|
|
52302
52694
|
type: eff.type,
|
|
52303
|
-
args: eff.type === "render-ui" ? [eff.slot] : [],
|
|
52695
|
+
args: eff.type === "render-ui" && eff.slot !== void 0 ? [eff.slot] : [],
|
|
52304
52696
|
status: "executed"
|
|
52305
52697
|
}))
|
|
52306
52698
|
];
|
|
@@ -52316,7 +52708,7 @@ function TraitInitializer({ traits: traits2, routeParams, orbitalNames, onNaviga
|
|
|
52316
52708
|
}
|
|
52317
52709
|
})();
|
|
52318
52710
|
}, [bridge.connected, orbitalNames, bridge.sendEvent, uiSlots, onNavigate, embeddedTraits, activeTraitNames, withActiveTraits, routeParams]);
|
|
52319
|
-
return
|
|
52711
|
+
return /* @__PURE__ */ jsxRuntime.jsx(providers.EntityBindingContext.Provider, { value: entityBindingSource, children });
|
|
52320
52712
|
}
|
|
52321
52713
|
function SchemaRunner({ schema, serverUrl, transport, mockData, pageName, routeParams, onNavigate, onLocalFallback, persistence }) {
|
|
52322
52714
|
const { traits: traits2, allEntities, allTraits, ir } = useResolvedSchema(schema, pageName);
|
|
@@ -52449,30 +52841,28 @@ function SchemaRunner({ schema, serverUrl, transport, mockData, pageName, routeP
|
|
|
52449
52841
|
}
|
|
52450
52842
|
return schema.orbitals[0]?.theme;
|
|
52451
52843
|
}, [schema, pageName]);
|
|
52452
|
-
const inner = /* @__PURE__ */ jsxRuntime.jsx(providers.VerificationProvider, { enabled: true, children: /* @__PURE__ */ jsxRuntime.
|
|
52844
|
+
const inner = /* @__PURE__ */ jsxRuntime.jsx(providers.VerificationProvider, { enabled: true, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
52453
52845
|
providers.EntitySchemaProvider,
|
|
52454
52846
|
{
|
|
52455
52847
|
entities: entitiesArray,
|
|
52456
52848
|
traitLinkedEntities: traitLinkedEntitiesMap,
|
|
52457
52849
|
orbitalsByTrait: orbitalsByTraitMap,
|
|
52458
|
-
children:
|
|
52459
|
-
|
|
52460
|
-
|
|
52461
|
-
|
|
52462
|
-
|
|
52463
|
-
|
|
52464
|
-
|
|
52465
|
-
|
|
52466
|
-
|
|
52467
|
-
|
|
52468
|
-
|
|
52469
|
-
|
|
52470
|
-
|
|
52471
|
-
|
|
52472
|
-
|
|
52473
|
-
|
|
52474
|
-
/* @__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 }) }) })
|
|
52475
|
-
]
|
|
52850
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
52851
|
+
TraitInitializer,
|
|
52852
|
+
{
|
|
52853
|
+
traits: allPageTraits,
|
|
52854
|
+
routeParams,
|
|
52855
|
+
orbitalNames: serverUrl || transport ? pageOrbitalNames : void 0,
|
|
52856
|
+
traitConfigsByName,
|
|
52857
|
+
orbitalsByTrait,
|
|
52858
|
+
embeddedTraits,
|
|
52859
|
+
serverActiveTraits,
|
|
52860
|
+
onNavigate,
|
|
52861
|
+
onLocalFallback,
|
|
52862
|
+
persistence,
|
|
52863
|
+
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 }) }) })
|
|
52864
|
+
}
|
|
52865
|
+
)
|
|
52476
52866
|
}
|
|
52477
52867
|
) });
|
|
52478
52868
|
if (serverUrl || transport) {
|