@almadar/ui 2.16.0 → 2.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/avl/index.cjs +91 -1
- package/dist/avl/index.d.cts +7 -5
- package/dist/avl/index.js +91 -1
- package/dist/components/index.cjs +131 -2411
- package/dist/components/index.css +0 -508
- package/dist/components/index.js +132 -2411
- package/dist/components/molecules/avl/AvlSlotMap.d.ts +5 -4
- package/dist/components/molecules/avl/avl-layout.d.ts +2 -1
- package/dist/components/organisms/component-registry.generated.d.ts +1 -1
- package/dist/components/organisms/game/three/index.cjs +1067 -0
- package/dist/components/organisms/game/three/index.css +192 -0
- package/dist/components/organisms/game/three/index.d.ts +4 -0
- package/dist/components/organisms/game/three/index.js +1068 -5
- package/dist/illustrations/index.cjs +91 -1
- package/dist/illustrations/index.d.cts +5 -4
- package/dist/illustrations/index.js +91 -1
- package/dist/providers/index.cjs +152 -1521
- package/dist/providers/index.css +0 -508
- package/dist/providers/index.js +62 -1430
- package/dist/runtime/index.cjs +145 -1514
- package/dist/runtime/index.css +0 -508
- package/dist/runtime/index.js +63 -1431
- package/package.json +1 -1
package/dist/runtime/index.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var React110 = require('react');
|
|
4
4
|
var jsxRuntime = require('react/jsx-runtime');
|
|
5
5
|
require('@tanstack/react-query');
|
|
6
6
|
require('react-dom');
|
|
@@ -20,12 +20,6 @@ var remarkMath = require('remark-math');
|
|
|
20
20
|
var rehypeKatex = require('rehype-katex');
|
|
21
21
|
var SyntaxHighlighter = require('react-syntax-highlighter/dist/esm/prism');
|
|
22
22
|
var dark = require('react-syntax-highlighter/dist/esm/styles/prism/vsc-dark-plus');
|
|
23
|
-
var fiber = require('@react-three/fiber');
|
|
24
|
-
var drei = require('@react-three/drei');
|
|
25
|
-
var THREE = require('three');
|
|
26
|
-
var GLTFLoader = require('three/examples/jsm/loaders/GLTFLoader');
|
|
27
|
-
var GLTFLoader_js = require('three/examples/jsm/loaders/GLTFLoader.js');
|
|
28
|
-
var OBJLoader_js = require('three/examples/jsm/loaders/OBJLoader.js');
|
|
29
23
|
var core = require('@almadar/core');
|
|
30
24
|
var runtime = require('@almadar/runtime');
|
|
31
25
|
|
|
@@ -49,7 +43,7 @@ function _interopNamespace(e) {
|
|
|
49
43
|
return Object.freeze(n);
|
|
50
44
|
}
|
|
51
45
|
|
|
52
|
-
var
|
|
46
|
+
var React110__namespace = /*#__PURE__*/_interopNamespace(React110);
|
|
53
47
|
var LucideIcons__namespace = /*#__PURE__*/_interopNamespace(LucideIcons);
|
|
54
48
|
var L__default = /*#__PURE__*/_interopDefault(L);
|
|
55
49
|
var ReactMarkdown__default = /*#__PURE__*/_interopDefault(ReactMarkdown);
|
|
@@ -58,12 +52,11 @@ var remarkMath__default = /*#__PURE__*/_interopDefault(remarkMath);
|
|
|
58
52
|
var rehypeKatex__default = /*#__PURE__*/_interopDefault(rehypeKatex);
|
|
59
53
|
var SyntaxHighlighter__default = /*#__PURE__*/_interopDefault(SyntaxHighlighter);
|
|
60
54
|
var dark__default = /*#__PURE__*/_interopDefault(dark);
|
|
61
|
-
var THREE__namespace = /*#__PURE__*/_interopNamespace(THREE);
|
|
62
55
|
|
|
63
56
|
var __defProp = Object.defineProperty;
|
|
64
57
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
65
58
|
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
66
|
-
var EventBusContext =
|
|
59
|
+
var EventBusContext = React110.createContext(null);
|
|
67
60
|
function getGlobalEventBus() {
|
|
68
61
|
if (typeof window !== "undefined") {
|
|
69
62
|
return window.__kflowEventBus ?? null;
|
|
@@ -131,20 +124,11 @@ var fallbackEventBus = {
|
|
|
131
124
|
}
|
|
132
125
|
};
|
|
133
126
|
function useEventBus() {
|
|
134
|
-
const context =
|
|
127
|
+
const context = React110.useContext(EventBusContext);
|
|
135
128
|
return context ?? getGlobalEventBus() ?? fallbackEventBus;
|
|
136
129
|
}
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
return React113.useCallback(
|
|
140
|
-
(type, payload) => {
|
|
141
|
-
eventBus.emit(type, payload);
|
|
142
|
-
},
|
|
143
|
-
[eventBus]
|
|
144
|
-
);
|
|
145
|
-
}
|
|
146
|
-
React113.createContext(null);
|
|
147
|
-
React113.createContext(null);
|
|
130
|
+
React110.createContext(null);
|
|
131
|
+
React110.createContext(null);
|
|
148
132
|
|
|
149
133
|
// lib/api-client.ts
|
|
150
134
|
typeof process !== "undefined" && process.env?.VITE_API_URL ? process.env.VITE_API_URL : "/api";
|
|
@@ -258,7 +242,7 @@ var en_default = {
|
|
|
258
242
|
// hooks/useTranslate.ts
|
|
259
243
|
var { $meta: _meta, ...coreMessages } = en_default;
|
|
260
244
|
var coreLocale = coreMessages;
|
|
261
|
-
var I18nContext =
|
|
245
|
+
var I18nContext = React110.createContext({
|
|
262
246
|
locale: "en",
|
|
263
247
|
direction: "ltr",
|
|
264
248
|
t: (key) => coreLocale[key] ?? key
|
|
@@ -267,13 +251,13 @@ var I18nContext = React113.createContext({
|
|
|
267
251
|
I18nContext.displayName = "I18nContext";
|
|
268
252
|
I18nContext.Provider;
|
|
269
253
|
function useTranslate() {
|
|
270
|
-
return
|
|
254
|
+
return React110.useContext(I18nContext);
|
|
271
255
|
}
|
|
272
256
|
typeof process !== "undefined" && process.env?.VITE_API_URL ? process.env.VITE_API_URL : "http://localhost:3000";
|
|
273
|
-
|
|
274
|
-
var FetchedDataContext =
|
|
257
|
+
React110.createContext(void 0);
|
|
258
|
+
var FetchedDataContext = React110.createContext(null);
|
|
275
259
|
function useFetchedDataContext() {
|
|
276
|
-
return
|
|
260
|
+
return React110.useContext(FetchedDataContext);
|
|
277
261
|
}
|
|
278
262
|
function cn(...inputs) {
|
|
279
263
|
return tailwindMerge.twMerge(clsx.clsx(inputs));
|
|
@@ -415,7 +399,7 @@ var positionStyles = {
|
|
|
415
399
|
fixed: "fixed",
|
|
416
400
|
sticky: "sticky"
|
|
417
401
|
};
|
|
418
|
-
var Box =
|
|
402
|
+
var Box = React110__namespace.default.forwardRef(
|
|
419
403
|
({
|
|
420
404
|
padding,
|
|
421
405
|
paddingX,
|
|
@@ -434,7 +418,7 @@ var Box = React113__namespace.default.forwardRef(
|
|
|
434
418
|
position,
|
|
435
419
|
className,
|
|
436
420
|
children,
|
|
437
|
-
as:
|
|
421
|
+
as: Component = "div",
|
|
438
422
|
action,
|
|
439
423
|
actionPayload,
|
|
440
424
|
hoverEvent,
|
|
@@ -444,27 +428,27 @@ var Box = React113__namespace.default.forwardRef(
|
|
|
444
428
|
...rest
|
|
445
429
|
}, ref) => {
|
|
446
430
|
const eventBus = useEventBus();
|
|
447
|
-
const handleClick =
|
|
431
|
+
const handleClick = React110.useCallback((e) => {
|
|
448
432
|
if (action) {
|
|
449
433
|
e.stopPropagation();
|
|
450
434
|
eventBus.emit(`UI:${action}`, actionPayload ?? {});
|
|
451
435
|
}
|
|
452
436
|
onClick?.(e);
|
|
453
437
|
}, [action, actionPayload, eventBus, onClick]);
|
|
454
|
-
const handleMouseEnter =
|
|
438
|
+
const handleMouseEnter = React110.useCallback((e) => {
|
|
455
439
|
if (hoverEvent) {
|
|
456
440
|
eventBus.emit(`UI:${hoverEvent}`, { hovered: true });
|
|
457
441
|
}
|
|
458
442
|
onMouseEnter?.(e);
|
|
459
443
|
}, [hoverEvent, eventBus, onMouseEnter]);
|
|
460
|
-
const handleMouseLeave =
|
|
444
|
+
const handleMouseLeave = React110.useCallback((e) => {
|
|
461
445
|
if (hoverEvent) {
|
|
462
446
|
eventBus.emit(`UI:${hoverEvent}`, { hovered: false });
|
|
463
447
|
}
|
|
464
448
|
onMouseLeave?.(e);
|
|
465
449
|
}, [hoverEvent, eventBus, onMouseLeave]);
|
|
466
450
|
const isClickable = action || onClick;
|
|
467
|
-
const Comp =
|
|
451
|
+
const Comp = Component;
|
|
468
452
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
469
453
|
Comp,
|
|
470
454
|
{
|
|
@@ -594,8 +578,8 @@ var Typography = ({
|
|
|
594
578
|
children
|
|
595
579
|
}) => {
|
|
596
580
|
const variant = variantProp ?? (level ? `h${level}` : "body1");
|
|
597
|
-
const
|
|
598
|
-
const Comp =
|
|
581
|
+
const Component = as || defaultElements[variant];
|
|
582
|
+
const Comp = Component;
|
|
599
583
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
600
584
|
Comp,
|
|
601
585
|
{
|
|
@@ -685,7 +669,7 @@ function resolveIconProp(value, sizeClass) {
|
|
|
685
669
|
const IconComp = value;
|
|
686
670
|
return /* @__PURE__ */ jsxRuntime.jsx(IconComp, { className: sizeClass });
|
|
687
671
|
}
|
|
688
|
-
if (
|
|
672
|
+
if (React110__namespace.default.isValidElement(value)) {
|
|
689
673
|
return value;
|
|
690
674
|
}
|
|
691
675
|
if (typeof value === "object" && value !== null && "render" in value) {
|
|
@@ -694,7 +678,7 @@ function resolveIconProp(value, sizeClass) {
|
|
|
694
678
|
}
|
|
695
679
|
return value;
|
|
696
680
|
}
|
|
697
|
-
var Button =
|
|
681
|
+
var Button = React110__namespace.default.forwardRef(
|
|
698
682
|
({
|
|
699
683
|
className,
|
|
700
684
|
variant = "primary",
|
|
@@ -789,7 +773,7 @@ var sizeStyles3 = {
|
|
|
789
773
|
md: "px-2.5 py-1 text-sm",
|
|
790
774
|
lg: "px-3 py-1.5 text-base"
|
|
791
775
|
};
|
|
792
|
-
var Badge =
|
|
776
|
+
var Badge = React110__namespace.default.forwardRef(
|
|
793
777
|
({ className, variant = "default", size = "sm", amount, label, icon, children, ...props }, ref) => {
|
|
794
778
|
const iconSizes2 = { sm: "w-3 h-3", md: "w-3.5 h-3.5", lg: "w-4 h-4" };
|
|
795
779
|
const resolvedIcon = typeof icon === "string" ? (() => {
|
|
@@ -816,7 +800,7 @@ var Badge = React113__namespace.default.forwardRef(
|
|
|
816
800
|
}
|
|
817
801
|
);
|
|
818
802
|
Badge.displayName = "Badge";
|
|
819
|
-
var Input =
|
|
803
|
+
var Input = React110__namespace.default.forwardRef(
|
|
820
804
|
({
|
|
821
805
|
className,
|
|
822
806
|
inputType,
|
|
@@ -928,7 +912,7 @@ var Input = React113__namespace.default.forwardRef(
|
|
|
928
912
|
}
|
|
929
913
|
);
|
|
930
914
|
Input.displayName = "Input";
|
|
931
|
-
var Label =
|
|
915
|
+
var Label = React110__namespace.default.forwardRef(
|
|
932
916
|
({ className, required, children, ...props }, ref) => {
|
|
933
917
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
934
918
|
"label",
|
|
@@ -948,7 +932,7 @@ var Label = React113__namespace.default.forwardRef(
|
|
|
948
932
|
}
|
|
949
933
|
);
|
|
950
934
|
Label.displayName = "Label";
|
|
951
|
-
var Textarea =
|
|
935
|
+
var Textarea = React110__namespace.default.forwardRef(
|
|
952
936
|
({ className, error, ...props }, ref) => {
|
|
953
937
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
954
938
|
"textarea",
|
|
@@ -971,7 +955,7 @@ var Textarea = React113__namespace.default.forwardRef(
|
|
|
971
955
|
}
|
|
972
956
|
);
|
|
973
957
|
Textarea.displayName = "Textarea";
|
|
974
|
-
var Select =
|
|
958
|
+
var Select = React110__namespace.default.forwardRef(
|
|
975
959
|
({ className, options, placeholder, error, ...props }, ref) => {
|
|
976
960
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
|
|
977
961
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -1007,7 +991,7 @@ var Select = React113__namespace.default.forwardRef(
|
|
|
1007
991
|
}
|
|
1008
992
|
);
|
|
1009
993
|
Select.displayName = "Select";
|
|
1010
|
-
var Checkbox =
|
|
994
|
+
var Checkbox = React110__namespace.default.forwardRef(
|
|
1011
995
|
({ className, label, id, ...props }, ref) => {
|
|
1012
996
|
const inputId = id || `checkbox-${Math.random().toString(36).substr(2, 9)}`;
|
|
1013
997
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center", children: [
|
|
@@ -1081,7 +1065,7 @@ var shadowStyles2 = {
|
|
|
1081
1065
|
md: "shadow-[var(--shadow-main)]",
|
|
1082
1066
|
lg: "shadow-[var(--shadow-lg)]"
|
|
1083
1067
|
};
|
|
1084
|
-
var Card =
|
|
1068
|
+
var Card = React110__namespace.default.forwardRef(
|
|
1085
1069
|
({
|
|
1086
1070
|
className,
|
|
1087
1071
|
variant = "bordered",
|
|
@@ -1117,9 +1101,9 @@ var Card = React113__namespace.default.forwardRef(
|
|
|
1117
1101
|
}
|
|
1118
1102
|
);
|
|
1119
1103
|
Card.displayName = "Card";
|
|
1120
|
-
var CardHeader =
|
|
1104
|
+
var CardHeader = React110__namespace.default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx("div", { ref, className: cn("mb-4", className), ...props }));
|
|
1121
1105
|
CardHeader.displayName = "CardHeader";
|
|
1122
|
-
var CardTitle =
|
|
1106
|
+
var CardTitle = React110__namespace.default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
1123
1107
|
"h3",
|
|
1124
1108
|
{
|
|
1125
1109
|
ref,
|
|
@@ -1132,11 +1116,11 @@ var CardTitle = React113__namespace.default.forwardRef(({ className, ...props },
|
|
|
1132
1116
|
}
|
|
1133
1117
|
));
|
|
1134
1118
|
CardTitle.displayName = "CardTitle";
|
|
1135
|
-
var CardContent =
|
|
1119
|
+
var CardContent = React110__namespace.default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx("div", { ref, className: cn("", className), ...props }));
|
|
1136
1120
|
CardContent.displayName = "CardContent";
|
|
1137
1121
|
var CardBody = CardContent;
|
|
1138
1122
|
CardBody.displayName = "CardBody";
|
|
1139
|
-
var CardFooter =
|
|
1123
|
+
var CardFooter = React110__namespace.default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
1140
1124
|
"div",
|
|
1141
1125
|
{
|
|
1142
1126
|
ref,
|
|
@@ -1151,7 +1135,7 @@ var sizeStyles4 = {
|
|
|
1151
1135
|
md: "h-6 w-6",
|
|
1152
1136
|
lg: "h-8 w-8"
|
|
1153
1137
|
};
|
|
1154
|
-
var Spinner =
|
|
1138
|
+
var Spinner = React110__namespace.default.forwardRef(
|
|
1155
1139
|
({ className, size = "md", ...props }, ref) => {
|
|
1156
1140
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1157
1141
|
"div",
|
|
@@ -1165,7 +1149,7 @@ var Spinner = React113__namespace.default.forwardRef(
|
|
|
1165
1149
|
}
|
|
1166
1150
|
);
|
|
1167
1151
|
Spinner.displayName = "Spinner";
|
|
1168
|
-
var Radio =
|
|
1152
|
+
var Radio = React110__namespace.default.forwardRef(
|
|
1169
1153
|
({
|
|
1170
1154
|
label,
|
|
1171
1155
|
helperText,
|
|
@@ -1269,7 +1253,7 @@ var Radio = React113__namespace.default.forwardRef(
|
|
|
1269
1253
|
}
|
|
1270
1254
|
);
|
|
1271
1255
|
Radio.displayName = "Radio";
|
|
1272
|
-
var Switch =
|
|
1256
|
+
var Switch = React110__namespace.forwardRef(
|
|
1273
1257
|
({
|
|
1274
1258
|
checked,
|
|
1275
1259
|
defaultChecked = false,
|
|
@@ -1280,10 +1264,10 @@ var Switch = React113__namespace.forwardRef(
|
|
|
1280
1264
|
name,
|
|
1281
1265
|
className
|
|
1282
1266
|
}, ref) => {
|
|
1283
|
-
const [isChecked, setIsChecked] =
|
|
1267
|
+
const [isChecked, setIsChecked] = React110__namespace.useState(
|
|
1284
1268
|
checked !== void 0 ? checked : defaultChecked
|
|
1285
1269
|
);
|
|
1286
|
-
|
|
1270
|
+
React110__namespace.useEffect(() => {
|
|
1287
1271
|
if (checked !== void 0) {
|
|
1288
1272
|
setIsChecked(checked);
|
|
1289
1273
|
}
|
|
@@ -1377,7 +1361,7 @@ var Stack = ({
|
|
|
1377
1361
|
className,
|
|
1378
1362
|
style,
|
|
1379
1363
|
children,
|
|
1380
|
-
as:
|
|
1364
|
+
as: Component = "div",
|
|
1381
1365
|
onClick,
|
|
1382
1366
|
onKeyDown,
|
|
1383
1367
|
role,
|
|
@@ -1395,7 +1379,7 @@ var Stack = ({
|
|
|
1395
1379
|
};
|
|
1396
1380
|
const isHorizontal = direction === "horizontal";
|
|
1397
1381
|
const directionClass = responsive && isHorizontal ? reverse ? "flex-col-reverse md:flex-row-reverse" : "flex-col md:flex-row" : isHorizontal ? reverse ? "flex-row-reverse" : "flex-row" : reverse ? "flex-col-reverse" : "flex-col";
|
|
1398
|
-
const Comp =
|
|
1382
|
+
const Comp = Component;
|
|
1399
1383
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1400
1384
|
Comp,
|
|
1401
1385
|
{
|
|
@@ -1441,7 +1425,7 @@ var sizeStyles5 = {
|
|
|
1441
1425
|
md: "w-2.5 h-2.5",
|
|
1442
1426
|
lg: "w-3 h-3"
|
|
1443
1427
|
};
|
|
1444
|
-
var StatusDot =
|
|
1428
|
+
var StatusDot = React110__namespace.default.forwardRef(
|
|
1445
1429
|
({ className, status = "offline", pulse = false, size = "md", label, ...props }, ref) => {
|
|
1446
1430
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1447
1431
|
"span",
|
|
@@ -1488,7 +1472,7 @@ var iconMap2 = {
|
|
|
1488
1472
|
down: LucideIcons.TrendingDown,
|
|
1489
1473
|
flat: LucideIcons.ArrowRight
|
|
1490
1474
|
};
|
|
1491
|
-
var TrendIndicator =
|
|
1475
|
+
var TrendIndicator = React110__namespace.default.forwardRef(
|
|
1492
1476
|
({
|
|
1493
1477
|
className,
|
|
1494
1478
|
value,
|
|
@@ -1547,7 +1531,7 @@ var thumbSizes = {
|
|
|
1547
1531
|
md: "w-4 h-4",
|
|
1548
1532
|
lg: "w-5 h-5"
|
|
1549
1533
|
};
|
|
1550
|
-
var RangeSlider =
|
|
1534
|
+
var RangeSlider = React110__namespace.default.forwardRef(
|
|
1551
1535
|
({
|
|
1552
1536
|
className,
|
|
1553
1537
|
min = 0,
|
|
@@ -1565,14 +1549,14 @@ var RangeSlider = React113__namespace.default.forwardRef(
|
|
|
1565
1549
|
formatValue: formatValue5,
|
|
1566
1550
|
...props
|
|
1567
1551
|
}, ref) => {
|
|
1568
|
-
const [isDragging, setIsDragging] =
|
|
1569
|
-
const [showTip, setShowTip] =
|
|
1570
|
-
const inputRef =
|
|
1552
|
+
const [isDragging, setIsDragging] = React110.useState(false);
|
|
1553
|
+
const [showTip, setShowTip] = React110.useState(false);
|
|
1554
|
+
const inputRef = React110.useRef(null);
|
|
1571
1555
|
const eventBus = useSafeEventBus();
|
|
1572
1556
|
const percentage = max !== min ? (value - min) / (max - min) * 100 : 0;
|
|
1573
1557
|
const bufferedPercentage = buffered !== void 0 ? Math.min(buffered, 100) : void 0;
|
|
1574
1558
|
const displayValue = formatValue5 ? formatValue5(value) : String(value);
|
|
1575
|
-
const handleChange =
|
|
1559
|
+
const handleChange = React110.useCallback(
|
|
1576
1560
|
(e) => {
|
|
1577
1561
|
const newValue = Number(e.target.value);
|
|
1578
1562
|
onChange?.(newValue);
|
|
@@ -1750,7 +1734,7 @@ var paddingClasses = {
|
|
|
1750
1734
|
md: "py-16",
|
|
1751
1735
|
lg: "py-24"
|
|
1752
1736
|
};
|
|
1753
|
-
var ContentSection =
|
|
1737
|
+
var ContentSection = React110__namespace.default.forwardRef(
|
|
1754
1738
|
({ children, background = "default", padding = "lg", id, className }, ref) => {
|
|
1755
1739
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1756
1740
|
Box,
|
|
@@ -1803,7 +1787,7 @@ var ErrorState = ({
|
|
|
1803
1787
|
);
|
|
1804
1788
|
};
|
|
1805
1789
|
ErrorState.displayName = "ErrorState";
|
|
1806
|
-
var ErrorBoundary = class extends
|
|
1790
|
+
var ErrorBoundary = class extends React110__namespace.default.Component {
|
|
1807
1791
|
constructor(props) {
|
|
1808
1792
|
super(props);
|
|
1809
1793
|
__publicField(this, "reset", () => {
|
|
@@ -1844,9 +1828,9 @@ var ErrorBoundary = class extends React113__namespace.default.Component {
|
|
|
1844
1828
|
}
|
|
1845
1829
|
};
|
|
1846
1830
|
__publicField(ErrorBoundary, "displayName", "ErrorBoundary");
|
|
1847
|
-
var ClientEffectConfigContext =
|
|
1831
|
+
var ClientEffectConfigContext = React110.createContext(null);
|
|
1848
1832
|
ClientEffectConfigContext.Provider;
|
|
1849
|
-
|
|
1833
|
+
React110.createContext(null);
|
|
1850
1834
|
var defaultIcon = L__default.default.icon({
|
|
1851
1835
|
iconUrl: "https://unpkg.com/leaflet@1.9.4/dist/images/marker-icon.png",
|
|
1852
1836
|
iconRetinaUrl: "https://unpkg.com/leaflet@1.9.4/dist/images/marker-icon-2x.png",
|
|
@@ -1978,7 +1962,7 @@ function waitForTransition(event, timeoutMs = 1e4) {
|
|
|
1978
1962
|
});
|
|
1979
1963
|
}
|
|
1980
1964
|
exposeOnWindow();
|
|
1981
|
-
var MarkdownContent =
|
|
1965
|
+
var MarkdownContent = React110__namespace.default.memo(
|
|
1982
1966
|
({ content, direction, className }) => {
|
|
1983
1967
|
const { t: _t } = useTranslate();
|
|
1984
1968
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -2079,7 +2063,7 @@ var MarkdownContent = React113__namespace.default.memo(
|
|
|
2079
2063
|
(prev, next) => prev.content === next.content && prev.className === next.className && prev.direction === next.direction
|
|
2080
2064
|
);
|
|
2081
2065
|
MarkdownContent.displayName = "MarkdownContent";
|
|
2082
|
-
var CodeBlock =
|
|
2066
|
+
var CodeBlock = React110__namespace.default.memo(
|
|
2083
2067
|
({
|
|
2084
2068
|
code,
|
|
2085
2069
|
language = "text",
|
|
@@ -2090,20 +2074,20 @@ var CodeBlock = React113__namespace.default.memo(
|
|
|
2090
2074
|
}) => {
|
|
2091
2075
|
const eventBus = useEventBus();
|
|
2092
2076
|
const { t: _t } = useTranslate();
|
|
2093
|
-
const scrollRef =
|
|
2094
|
-
const savedScrollLeftRef =
|
|
2095
|
-
const [copied, setCopied] =
|
|
2096
|
-
|
|
2077
|
+
const scrollRef = React110.useRef(null);
|
|
2078
|
+
const savedScrollLeftRef = React110.useRef(0);
|
|
2079
|
+
const [copied, setCopied] = React110.useState(false);
|
|
2080
|
+
React110.useLayoutEffect(() => {
|
|
2097
2081
|
const el = scrollRef.current;
|
|
2098
2082
|
return () => {
|
|
2099
2083
|
if (el) savedScrollLeftRef.current = el.scrollLeft;
|
|
2100
2084
|
};
|
|
2101
2085
|
}, [language, code]);
|
|
2102
|
-
|
|
2086
|
+
React110.useLayoutEffect(() => {
|
|
2103
2087
|
const el = scrollRef.current;
|
|
2104
2088
|
if (el) el.scrollLeft = savedScrollLeftRef.current;
|
|
2105
2089
|
}, [language, code]);
|
|
2106
|
-
|
|
2090
|
+
React110.useEffect(() => {
|
|
2107
2091
|
const el = scrollRef.current;
|
|
2108
2092
|
if (!el) return;
|
|
2109
2093
|
const handle = () => {
|
|
@@ -2186,1394 +2170,12 @@ var CodeBlock = React113__namespace.default.memo(
|
|
|
2186
2170
|
(prev, next) => prev.language === next.language && prev.code === next.code && prev.showCopyButton === next.showCopyButton && prev.maxHeight === next.maxHeight
|
|
2187
2171
|
);
|
|
2188
2172
|
CodeBlock.displayName = "CodeBlock";
|
|
2189
|
-
var Camera3D = React113.forwardRef(
|
|
2190
|
-
({
|
|
2191
|
-
mode = "isometric",
|
|
2192
|
-
position = [10, 10, 10],
|
|
2193
|
-
target = [0, 0, 0],
|
|
2194
|
-
zoom = 1,
|
|
2195
|
-
fov = 45,
|
|
2196
|
-
enableOrbit = true,
|
|
2197
|
-
minDistance = 2,
|
|
2198
|
-
maxDistance = 100,
|
|
2199
|
-
onChange
|
|
2200
|
-
}, ref) => {
|
|
2201
|
-
const { camera, set, viewport } = fiber.useThree();
|
|
2202
|
-
const controlsRef = React113.useRef(null);
|
|
2203
|
-
const initialPosition = React113.useRef(new THREE__namespace.Vector3(...position));
|
|
2204
|
-
const initialTarget = React113.useRef(new THREE__namespace.Vector3(...target));
|
|
2205
|
-
React113.useEffect(() => {
|
|
2206
|
-
let newCamera;
|
|
2207
|
-
if (mode === "isometric") {
|
|
2208
|
-
const aspect = viewport.aspect;
|
|
2209
|
-
const size = 10 / zoom;
|
|
2210
|
-
newCamera = new THREE__namespace.OrthographicCamera(
|
|
2211
|
-
-size * aspect,
|
|
2212
|
-
size * aspect,
|
|
2213
|
-
size,
|
|
2214
|
-
-size,
|
|
2215
|
-
0.1,
|
|
2216
|
-
1e3
|
|
2217
|
-
);
|
|
2218
|
-
} else {
|
|
2219
|
-
newCamera = new THREE__namespace.PerspectiveCamera(fov, viewport.aspect, 0.1, 1e3);
|
|
2220
|
-
}
|
|
2221
|
-
newCamera.position.copy(initialPosition.current);
|
|
2222
|
-
newCamera.lookAt(initialTarget.current);
|
|
2223
|
-
set({ camera: newCamera });
|
|
2224
|
-
if (mode === "top-down") {
|
|
2225
|
-
newCamera.position.set(0, 20 / zoom, 0);
|
|
2226
|
-
newCamera.lookAt(0, 0, 0);
|
|
2227
|
-
}
|
|
2228
|
-
return () => {
|
|
2229
|
-
};
|
|
2230
|
-
}, [mode, fov, zoom, viewport.aspect, set]);
|
|
2231
|
-
fiber.useFrame(() => {
|
|
2232
|
-
if (onChange) {
|
|
2233
|
-
onChange(camera);
|
|
2234
|
-
}
|
|
2235
|
-
});
|
|
2236
|
-
React113.useImperativeHandle(ref, () => ({
|
|
2237
|
-
getCamera: () => camera,
|
|
2238
|
-
setPosition: (x, y, z) => {
|
|
2239
|
-
camera.position.set(x, y, z);
|
|
2240
|
-
if (controlsRef.current) {
|
|
2241
|
-
controlsRef.current.update();
|
|
2242
|
-
}
|
|
2243
|
-
},
|
|
2244
|
-
lookAt: (x, y, z) => {
|
|
2245
|
-
camera.lookAt(x, y, z);
|
|
2246
|
-
if (controlsRef.current) {
|
|
2247
|
-
controlsRef.current.target.set(x, y, z);
|
|
2248
|
-
controlsRef.current.update();
|
|
2249
|
-
}
|
|
2250
|
-
},
|
|
2251
|
-
reset: () => {
|
|
2252
|
-
camera.position.copy(initialPosition.current);
|
|
2253
|
-
camera.lookAt(initialTarget.current);
|
|
2254
|
-
if (controlsRef.current) {
|
|
2255
|
-
controlsRef.current.target.copy(initialTarget.current);
|
|
2256
|
-
controlsRef.current.update();
|
|
2257
|
-
}
|
|
2258
|
-
},
|
|
2259
|
-
getViewBounds: () => {
|
|
2260
|
-
const min = new THREE__namespace.Vector3(-10, -10, -10);
|
|
2261
|
-
const max = new THREE__namespace.Vector3(10, 10, 10);
|
|
2262
|
-
return { min, max };
|
|
2263
|
-
}
|
|
2264
|
-
}));
|
|
2265
|
-
const maxPolarAngle = mode === "top-down" ? 0.1 : Math.PI / 2 - 0.1;
|
|
2266
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2267
|
-
drei.OrbitControls,
|
|
2268
|
-
{
|
|
2269
|
-
ref: controlsRef,
|
|
2270
|
-
camera,
|
|
2271
|
-
enabled: enableOrbit,
|
|
2272
|
-
target: initialTarget.current,
|
|
2273
|
-
minDistance,
|
|
2274
|
-
maxDistance,
|
|
2275
|
-
maxPolarAngle,
|
|
2276
|
-
enableDamping: true,
|
|
2277
|
-
dampingFactor: 0.05
|
|
2278
|
-
}
|
|
2279
|
-
);
|
|
2280
|
-
}
|
|
2281
|
-
);
|
|
2282
|
-
Camera3D.displayName = "Camera3D";
|
|
2283
|
-
var Canvas3DErrorBoundary = class extends React113.Component {
|
|
2284
|
-
constructor(props) {
|
|
2285
|
-
super(props);
|
|
2286
|
-
__publicField(this, "handleReset", () => {
|
|
2287
|
-
this.setState({
|
|
2288
|
-
hasError: false,
|
|
2289
|
-
error: null,
|
|
2290
|
-
errorInfo: null
|
|
2291
|
-
});
|
|
2292
|
-
this.props.onReset?.();
|
|
2293
|
-
});
|
|
2294
|
-
this.state = {
|
|
2295
|
-
hasError: false,
|
|
2296
|
-
error: null,
|
|
2297
|
-
errorInfo: null
|
|
2298
|
-
};
|
|
2299
|
-
}
|
|
2300
|
-
static getDerivedStateFromError(error) {
|
|
2301
|
-
return {
|
|
2302
|
-
hasError: true,
|
|
2303
|
-
error,
|
|
2304
|
-
errorInfo: null
|
|
2305
|
-
};
|
|
2306
|
-
}
|
|
2307
|
-
componentDidCatch(error, errorInfo) {
|
|
2308
|
-
this.setState({ errorInfo });
|
|
2309
|
-
this.props.onError?.(error, errorInfo);
|
|
2310
|
-
console.error("[Canvas3DErrorBoundary] Error caught:", error);
|
|
2311
|
-
console.error("[Canvas3DErrorBoundary] Component stack:", errorInfo.componentStack);
|
|
2312
|
-
}
|
|
2313
|
-
render() {
|
|
2314
|
-
if (this.state.hasError) {
|
|
2315
|
-
if (this.props.fallback) {
|
|
2316
|
-
return this.props.fallback;
|
|
2317
|
-
}
|
|
2318
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "canvas-3d-error", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "canvas-3d-error__content", children: [
|
|
2319
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "canvas-3d-error__icon", children: "\u26A0\uFE0F" }),
|
|
2320
|
-
/* @__PURE__ */ jsxRuntime.jsx("h2", { className: "canvas-3d-error__title", children: "3D Scene Error" }),
|
|
2321
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "canvas-3d-error__message", children: "Something went wrong while rendering the 3D scene." }),
|
|
2322
|
-
this.state.error && /* @__PURE__ */ jsxRuntime.jsxs("details", { className: "canvas-3d-error__details", children: [
|
|
2323
|
-
/* @__PURE__ */ jsxRuntime.jsx("summary", { children: "Error Details" }),
|
|
2324
|
-
/* @__PURE__ */ jsxRuntime.jsxs("pre", { className: "error__stack", children: [
|
|
2325
|
-
this.state.error.message,
|
|
2326
|
-
"\n",
|
|
2327
|
-
this.state.error.stack
|
|
2328
|
-
] }),
|
|
2329
|
-
this.state.errorInfo && /* @__PURE__ */ jsxRuntime.jsx("pre", { className: "error__component-stack", children: this.state.errorInfo.componentStack })
|
|
2330
|
-
] }),
|
|
2331
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "canvas-3d-error__actions", children: [
|
|
2332
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2333
|
-
"button",
|
|
2334
|
-
{
|
|
2335
|
-
className: "error__button error__button--primary",
|
|
2336
|
-
onClick: this.handleReset,
|
|
2337
|
-
children: "Try Again"
|
|
2338
|
-
}
|
|
2339
|
-
),
|
|
2340
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2341
|
-
"button",
|
|
2342
|
-
{
|
|
2343
|
-
className: "error__button error__button--secondary",
|
|
2344
|
-
onClick: () => window.location.reload(),
|
|
2345
|
-
children: "Reload Page"
|
|
2346
|
-
}
|
|
2347
|
-
)
|
|
2348
|
-
] })
|
|
2349
|
-
] }) });
|
|
2350
|
-
}
|
|
2351
|
-
return this.props.children;
|
|
2352
|
-
}
|
|
2353
|
-
};
|
|
2354
|
-
function Canvas3DLoadingState({
|
|
2355
|
-
progress = 0,
|
|
2356
|
-
loaded = 0,
|
|
2357
|
-
total = 0,
|
|
2358
|
-
message = "Loading 3D Scene...",
|
|
2359
|
-
details,
|
|
2360
|
-
showSpinner = true,
|
|
2361
|
-
className
|
|
2362
|
-
}) {
|
|
2363
|
-
const clampedProgress = Math.max(0, Math.min(100, progress));
|
|
2364
|
-
const hasProgress = total > 0;
|
|
2365
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `canvas-3d-loading ${className || ""}`, children: [
|
|
2366
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "canvas-3d-loading__content", children: [
|
|
2367
|
-
showSpinner && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "canvas-3d-loading__spinner", children: [
|
|
2368
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "spinner__ring" }),
|
|
2369
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "spinner__ring spinner__ring--secondary" })
|
|
2370
|
-
] }),
|
|
2371
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "canvas-3d-loading__message", children: message }),
|
|
2372
|
-
details && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "canvas-3d-loading__details", children: details }),
|
|
2373
|
-
hasProgress && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "canvas-3d-loading__progress", children: [
|
|
2374
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "progress__bar", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2375
|
-
"div",
|
|
2376
|
-
{
|
|
2377
|
-
className: "progress__fill",
|
|
2378
|
-
style: { width: `${clampedProgress}%` }
|
|
2379
|
-
}
|
|
2380
|
-
) }),
|
|
2381
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "progress__text", children: [
|
|
2382
|
-
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "progress__percentage", children: [
|
|
2383
|
-
clampedProgress,
|
|
2384
|
-
"%"
|
|
2385
|
-
] }),
|
|
2386
|
-
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "progress__count", children: [
|
|
2387
|
-
"(",
|
|
2388
|
-
loaded,
|
|
2389
|
-
"/",
|
|
2390
|
-
total,
|
|
2391
|
-
")"
|
|
2392
|
-
] })
|
|
2393
|
-
] })
|
|
2394
|
-
] })
|
|
2395
|
-
] }),
|
|
2396
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "canvas-3d-loading__background", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "bg__grid" }) })
|
|
2397
|
-
] });
|
|
2398
|
-
}
|
|
2399
2173
|
|
|
2400
2174
|
// lib/debug.ts
|
|
2401
2175
|
typeof window !== "undefined" && (localStorage.getItem("debug") === "true" || process.env.NODE_ENV === "development");
|
|
2402
|
-
|
|
2403
|
-
var GameAudioContext =
|
|
2176
|
+
React110.lazy(() => import('react-markdown'));
|
|
2177
|
+
var GameAudioContext = React110.createContext(null);
|
|
2404
2178
|
GameAudioContext.displayName = "GameAudioContext";
|
|
2405
|
-
function detectAssetRoot2(modelUrl) {
|
|
2406
|
-
const idx = modelUrl.indexOf("/3d/");
|
|
2407
|
-
if (idx !== -1) {
|
|
2408
|
-
return modelUrl.substring(0, idx + 4);
|
|
2409
|
-
}
|
|
2410
|
-
return modelUrl.substring(0, modelUrl.lastIndexOf("/") + 1);
|
|
2411
|
-
}
|
|
2412
|
-
function createGLTFLoaderForUrl(url) {
|
|
2413
|
-
const loader = new GLTFLoader_js.GLTFLoader();
|
|
2414
|
-
loader.setResourcePath(detectAssetRoot2(url));
|
|
2415
|
-
return loader;
|
|
2416
|
-
}
|
|
2417
|
-
var AssetLoader = class {
|
|
2418
|
-
constructor() {
|
|
2419
|
-
__publicField(this, "objLoader");
|
|
2420
|
-
__publicField(this, "textureLoader");
|
|
2421
|
-
__publicField(this, "modelCache");
|
|
2422
|
-
__publicField(this, "textureCache");
|
|
2423
|
-
__publicField(this, "loadingPromises");
|
|
2424
|
-
this.objLoader = new OBJLoader_js.OBJLoader();
|
|
2425
|
-
this.textureLoader = new THREE__namespace.TextureLoader();
|
|
2426
|
-
this.modelCache = /* @__PURE__ */ new Map();
|
|
2427
|
-
this.textureCache = /* @__PURE__ */ new Map();
|
|
2428
|
-
this.loadingPromises = /* @__PURE__ */ new Map();
|
|
2429
|
-
}
|
|
2430
|
-
/**
|
|
2431
|
-
* Load a GLB/GLTF model
|
|
2432
|
-
* @param url - URL to the .glb or .gltf file
|
|
2433
|
-
* @returns Promise with loaded model scene and animations
|
|
2434
|
-
*/
|
|
2435
|
-
async loadModel(url) {
|
|
2436
|
-
if (this.modelCache.has(url)) {
|
|
2437
|
-
return this.modelCache.get(url);
|
|
2438
|
-
}
|
|
2439
|
-
if (this.loadingPromises.has(url)) {
|
|
2440
|
-
return this.loadingPromises.get(url);
|
|
2441
|
-
}
|
|
2442
|
-
const loader = createGLTFLoaderForUrl(url);
|
|
2443
|
-
const loadPromise = loader.loadAsync(url).then((gltf) => {
|
|
2444
|
-
const result = {
|
|
2445
|
-
scene: gltf.scene,
|
|
2446
|
-
animations: gltf.animations || []
|
|
2447
|
-
};
|
|
2448
|
-
this.modelCache.set(url, result);
|
|
2449
|
-
this.loadingPromises.delete(url);
|
|
2450
|
-
return result;
|
|
2451
|
-
}).catch((error) => {
|
|
2452
|
-
this.loadingPromises.delete(url);
|
|
2453
|
-
throw new Error(`Failed to load model ${url}: ${error.message}`);
|
|
2454
|
-
});
|
|
2455
|
-
this.loadingPromises.set(url, loadPromise);
|
|
2456
|
-
return loadPromise;
|
|
2457
|
-
}
|
|
2458
|
-
/**
|
|
2459
|
-
* Load an OBJ model (fallback for non-GLB assets)
|
|
2460
|
-
* @param url - URL to the .obj file
|
|
2461
|
-
* @returns Promise with loaded object group
|
|
2462
|
-
*/
|
|
2463
|
-
async loadOBJ(url) {
|
|
2464
|
-
if (this.modelCache.has(url)) {
|
|
2465
|
-
return this.modelCache.get(url).scene;
|
|
2466
|
-
}
|
|
2467
|
-
if (this.loadingPromises.has(url)) {
|
|
2468
|
-
const result = await this.loadingPromises.get(url);
|
|
2469
|
-
return result.scene;
|
|
2470
|
-
}
|
|
2471
|
-
const loadPromise = this.objLoader.loadAsync(url).then((group) => {
|
|
2472
|
-
const result = {
|
|
2473
|
-
scene: group,
|
|
2474
|
-
animations: []
|
|
2475
|
-
};
|
|
2476
|
-
this.modelCache.set(url, result);
|
|
2477
|
-
this.loadingPromises.delete(url);
|
|
2478
|
-
return result;
|
|
2479
|
-
}).catch((error) => {
|
|
2480
|
-
this.loadingPromises.delete(url);
|
|
2481
|
-
throw new Error(`Failed to load OBJ ${url}: ${error.message}`);
|
|
2482
|
-
});
|
|
2483
|
-
this.loadingPromises.set(url, loadPromise);
|
|
2484
|
-
return (await loadPromise).scene;
|
|
2485
|
-
}
|
|
2486
|
-
/**
|
|
2487
|
-
* Load a texture
|
|
2488
|
-
* @param url - URL to the texture image
|
|
2489
|
-
* @returns Promise with loaded texture
|
|
2490
|
-
*/
|
|
2491
|
-
async loadTexture(url) {
|
|
2492
|
-
if (this.textureCache.has(url)) {
|
|
2493
|
-
return this.textureCache.get(url);
|
|
2494
|
-
}
|
|
2495
|
-
if (this.loadingPromises.has(`texture:${url}`)) {
|
|
2496
|
-
return this.loadingPromises.get(`texture:${url}`);
|
|
2497
|
-
}
|
|
2498
|
-
const loadPromise = this.textureLoader.loadAsync(url).then((texture) => {
|
|
2499
|
-
texture.colorSpace = THREE__namespace.SRGBColorSpace;
|
|
2500
|
-
this.textureCache.set(url, texture);
|
|
2501
|
-
this.loadingPromises.delete(`texture:${url}`);
|
|
2502
|
-
return texture;
|
|
2503
|
-
}).catch((error) => {
|
|
2504
|
-
this.loadingPromises.delete(`texture:${url}`);
|
|
2505
|
-
throw new Error(`Failed to load texture ${url}: ${error.message}`);
|
|
2506
|
-
});
|
|
2507
|
-
this.loadingPromises.set(`texture:${url}`, loadPromise);
|
|
2508
|
-
return loadPromise;
|
|
2509
|
-
}
|
|
2510
|
-
/**
|
|
2511
|
-
* Preload multiple assets
|
|
2512
|
-
* @param urls - Array of asset URLs to preload
|
|
2513
|
-
* @returns Promise that resolves when all assets are loaded
|
|
2514
|
-
*/
|
|
2515
|
-
async preload(urls) {
|
|
2516
|
-
const promises = urls.map((url) => {
|
|
2517
|
-
if (url.endsWith(".glb") || url.endsWith(".gltf")) {
|
|
2518
|
-
return this.loadModel(url).catch(() => null);
|
|
2519
|
-
} else if (url.endsWith(".obj")) {
|
|
2520
|
-
return this.loadOBJ(url).catch(() => null);
|
|
2521
|
-
} else if (/\.(png|jpg|jpeg|webp)$/i.test(url)) {
|
|
2522
|
-
return this.loadTexture(url).catch(() => null);
|
|
2523
|
-
}
|
|
2524
|
-
return Promise.resolve(null);
|
|
2525
|
-
});
|
|
2526
|
-
await Promise.all(promises);
|
|
2527
|
-
}
|
|
2528
|
-
/**
|
|
2529
|
-
* Check if a model is cached
|
|
2530
|
-
* @param url - Model URL
|
|
2531
|
-
*/
|
|
2532
|
-
hasModel(url) {
|
|
2533
|
-
return this.modelCache.has(url);
|
|
2534
|
-
}
|
|
2535
|
-
/**
|
|
2536
|
-
* Check if a texture is cached
|
|
2537
|
-
* @param url - Texture URL
|
|
2538
|
-
*/
|
|
2539
|
-
hasTexture(url) {
|
|
2540
|
-
return this.textureCache.has(url);
|
|
2541
|
-
}
|
|
2542
|
-
/**
|
|
2543
|
-
* Get cached model (throws if not cached)
|
|
2544
|
-
* @param url - Model URL
|
|
2545
|
-
*/
|
|
2546
|
-
getModel(url) {
|
|
2547
|
-
const model = this.modelCache.get(url);
|
|
2548
|
-
if (!model) {
|
|
2549
|
-
throw new Error(`Model ${url} not in cache`);
|
|
2550
|
-
}
|
|
2551
|
-
return model;
|
|
2552
|
-
}
|
|
2553
|
-
/**
|
|
2554
|
-
* Get cached texture (throws if not cached)
|
|
2555
|
-
* @param url - Texture URL
|
|
2556
|
-
*/
|
|
2557
|
-
getTexture(url) {
|
|
2558
|
-
const texture = this.textureCache.get(url);
|
|
2559
|
-
if (!texture) {
|
|
2560
|
-
throw new Error(`Texture ${url} not in cache`);
|
|
2561
|
-
}
|
|
2562
|
-
return texture;
|
|
2563
|
-
}
|
|
2564
|
-
/**
|
|
2565
|
-
* Clear all caches
|
|
2566
|
-
*/
|
|
2567
|
-
clearCache() {
|
|
2568
|
-
this.textureCache.forEach((texture) => {
|
|
2569
|
-
texture.dispose();
|
|
2570
|
-
});
|
|
2571
|
-
this.modelCache.forEach((model) => {
|
|
2572
|
-
model.scene.traverse((child) => {
|
|
2573
|
-
if (child instanceof THREE__namespace.Mesh) {
|
|
2574
|
-
child.geometry.dispose();
|
|
2575
|
-
if (Array.isArray(child.material)) {
|
|
2576
|
-
child.material.forEach((m) => m.dispose());
|
|
2577
|
-
} else {
|
|
2578
|
-
child.material.dispose();
|
|
2579
|
-
}
|
|
2580
|
-
}
|
|
2581
|
-
});
|
|
2582
|
-
});
|
|
2583
|
-
this.modelCache.clear();
|
|
2584
|
-
this.textureCache.clear();
|
|
2585
|
-
this.loadingPromises.clear();
|
|
2586
|
-
}
|
|
2587
|
-
/**
|
|
2588
|
-
* Get cache statistics
|
|
2589
|
-
*/
|
|
2590
|
-
getStats() {
|
|
2591
|
-
return {
|
|
2592
|
-
models: this.modelCache.size,
|
|
2593
|
-
textures: this.textureCache.size,
|
|
2594
|
-
loading: this.loadingPromises.size
|
|
2595
|
-
};
|
|
2596
|
-
}
|
|
2597
|
-
};
|
|
2598
|
-
new AssetLoader();
|
|
2599
|
-
function useAssetLoader(options = {}) {
|
|
2600
|
-
const { preloadUrls = [], loader: customLoader } = options;
|
|
2601
|
-
const loaderRef = React113.useRef(customLoader || new AssetLoader());
|
|
2602
|
-
const [state, setState] = React113.useState({
|
|
2603
|
-
isLoading: false,
|
|
2604
|
-
progress: 0,
|
|
2605
|
-
loaded: 0,
|
|
2606
|
-
total: 0,
|
|
2607
|
-
errors: []
|
|
2608
|
-
});
|
|
2609
|
-
React113.useEffect(() => {
|
|
2610
|
-
if (preloadUrls.length > 0) {
|
|
2611
|
-
preload(preloadUrls);
|
|
2612
|
-
}
|
|
2613
|
-
}, []);
|
|
2614
|
-
const updateProgress = React113.useCallback((loaded, total) => {
|
|
2615
|
-
setState((prev) => ({
|
|
2616
|
-
...prev,
|
|
2617
|
-
loaded,
|
|
2618
|
-
total,
|
|
2619
|
-
progress: total > 0 ? Math.round(loaded / total * 100) : 0
|
|
2620
|
-
}));
|
|
2621
|
-
}, []);
|
|
2622
|
-
const loadModel = React113.useCallback(
|
|
2623
|
-
async (url) => {
|
|
2624
|
-
setState((prev) => ({ ...prev, isLoading: true }));
|
|
2625
|
-
try {
|
|
2626
|
-
const model = await loaderRef.current.loadModel(url);
|
|
2627
|
-
setState((prev) => ({
|
|
2628
|
-
...prev,
|
|
2629
|
-
isLoading: false,
|
|
2630
|
-
loaded: prev.loaded + 1
|
|
2631
|
-
}));
|
|
2632
|
-
return model;
|
|
2633
|
-
} catch (error) {
|
|
2634
|
-
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
2635
|
-
setState((prev) => ({
|
|
2636
|
-
...prev,
|
|
2637
|
-
isLoading: false,
|
|
2638
|
-
errors: [...prev.errors, errorMsg]
|
|
2639
|
-
}));
|
|
2640
|
-
throw error;
|
|
2641
|
-
}
|
|
2642
|
-
},
|
|
2643
|
-
[]
|
|
2644
|
-
);
|
|
2645
|
-
const loadOBJ = React113.useCallback(
|
|
2646
|
-
async (url) => {
|
|
2647
|
-
setState((prev) => ({ ...prev, isLoading: true }));
|
|
2648
|
-
try {
|
|
2649
|
-
const model = await loaderRef.current.loadOBJ(url);
|
|
2650
|
-
setState((prev) => ({
|
|
2651
|
-
...prev,
|
|
2652
|
-
isLoading: false,
|
|
2653
|
-
loaded: prev.loaded + 1
|
|
2654
|
-
}));
|
|
2655
|
-
return model;
|
|
2656
|
-
} catch (error) {
|
|
2657
|
-
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
2658
|
-
setState((prev) => ({
|
|
2659
|
-
...prev,
|
|
2660
|
-
isLoading: false,
|
|
2661
|
-
errors: [...prev.errors, errorMsg]
|
|
2662
|
-
}));
|
|
2663
|
-
throw error;
|
|
2664
|
-
}
|
|
2665
|
-
},
|
|
2666
|
-
[]
|
|
2667
|
-
);
|
|
2668
|
-
const loadTexture = React113.useCallback(
|
|
2669
|
-
async (url) => {
|
|
2670
|
-
setState((prev) => ({ ...prev, isLoading: true }));
|
|
2671
|
-
try {
|
|
2672
|
-
const texture = await loaderRef.current.loadTexture(url);
|
|
2673
|
-
setState((prev) => ({
|
|
2674
|
-
...prev,
|
|
2675
|
-
isLoading: false,
|
|
2676
|
-
loaded: prev.loaded + 1
|
|
2677
|
-
}));
|
|
2678
|
-
return texture;
|
|
2679
|
-
} catch (error) {
|
|
2680
|
-
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
2681
|
-
setState((prev) => ({
|
|
2682
|
-
...prev,
|
|
2683
|
-
isLoading: false,
|
|
2684
|
-
errors: [...prev.errors, errorMsg]
|
|
2685
|
-
}));
|
|
2686
|
-
throw error;
|
|
2687
|
-
}
|
|
2688
|
-
},
|
|
2689
|
-
[]
|
|
2690
|
-
);
|
|
2691
|
-
const preload = React113.useCallback(
|
|
2692
|
-
async (urls) => {
|
|
2693
|
-
setState((prev) => ({
|
|
2694
|
-
...prev,
|
|
2695
|
-
isLoading: true,
|
|
2696
|
-
total: urls.length,
|
|
2697
|
-
loaded: 0,
|
|
2698
|
-
errors: []
|
|
2699
|
-
}));
|
|
2700
|
-
let completed = 0;
|
|
2701
|
-
const errors = [];
|
|
2702
|
-
await Promise.all(
|
|
2703
|
-
urls.map(async (url) => {
|
|
2704
|
-
try {
|
|
2705
|
-
if (url.endsWith(".glb") || url.endsWith(".gltf")) {
|
|
2706
|
-
await loaderRef.current.loadModel(url);
|
|
2707
|
-
} else if (url.endsWith(".obj")) {
|
|
2708
|
-
await loaderRef.current.loadOBJ(url);
|
|
2709
|
-
} else if (/\.(png|jpg|jpeg|webp)$/i.test(url)) {
|
|
2710
|
-
await loaderRef.current.loadTexture(url);
|
|
2711
|
-
}
|
|
2712
|
-
completed++;
|
|
2713
|
-
updateProgress(completed, urls.length);
|
|
2714
|
-
} catch (error) {
|
|
2715
|
-
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
2716
|
-
errors.push(`${url}: ${errorMsg}`);
|
|
2717
|
-
completed++;
|
|
2718
|
-
updateProgress(completed, urls.length);
|
|
2719
|
-
}
|
|
2720
|
-
})
|
|
2721
|
-
);
|
|
2722
|
-
setState((prev) => ({
|
|
2723
|
-
...prev,
|
|
2724
|
-
isLoading: false,
|
|
2725
|
-
errors
|
|
2726
|
-
}));
|
|
2727
|
-
},
|
|
2728
|
-
[updateProgress]
|
|
2729
|
-
);
|
|
2730
|
-
const hasModel = React113.useCallback((url) => {
|
|
2731
|
-
return loaderRef.current.hasModel(url);
|
|
2732
|
-
}, []);
|
|
2733
|
-
const hasTexture = React113.useCallback((url) => {
|
|
2734
|
-
return loaderRef.current.hasTexture(url);
|
|
2735
|
-
}, []);
|
|
2736
|
-
const getModel = React113.useCallback((url) => {
|
|
2737
|
-
try {
|
|
2738
|
-
return loaderRef.current.getModel(url);
|
|
2739
|
-
} catch {
|
|
2740
|
-
return void 0;
|
|
2741
|
-
}
|
|
2742
|
-
}, []);
|
|
2743
|
-
const getTexture = React113.useCallback((url) => {
|
|
2744
|
-
try {
|
|
2745
|
-
return loaderRef.current.getTexture(url);
|
|
2746
|
-
} catch {
|
|
2747
|
-
return void 0;
|
|
2748
|
-
}
|
|
2749
|
-
}, []);
|
|
2750
|
-
const clearCache = React113.useCallback(() => {
|
|
2751
|
-
loaderRef.current.clearCache();
|
|
2752
|
-
setState({
|
|
2753
|
-
isLoading: false,
|
|
2754
|
-
progress: 0,
|
|
2755
|
-
loaded: 0,
|
|
2756
|
-
total: 0,
|
|
2757
|
-
errors: []
|
|
2758
|
-
});
|
|
2759
|
-
}, []);
|
|
2760
|
-
return {
|
|
2761
|
-
...state,
|
|
2762
|
-
loadModel,
|
|
2763
|
-
loadOBJ,
|
|
2764
|
-
loadTexture,
|
|
2765
|
-
preload,
|
|
2766
|
-
hasModel,
|
|
2767
|
-
hasTexture,
|
|
2768
|
-
getModel,
|
|
2769
|
-
getTexture,
|
|
2770
|
-
clearCache
|
|
2771
|
-
};
|
|
2772
|
-
}
|
|
2773
|
-
function useGameCanvas3DEvents(options) {
|
|
2774
|
-
const {
|
|
2775
|
-
tileClickEvent,
|
|
2776
|
-
unitClickEvent,
|
|
2777
|
-
featureClickEvent,
|
|
2778
|
-
canvasClickEvent,
|
|
2779
|
-
tileHoverEvent,
|
|
2780
|
-
tileLeaveEvent,
|
|
2781
|
-
unitAnimationEvent,
|
|
2782
|
-
cameraChangeEvent,
|
|
2783
|
-
onTileClick,
|
|
2784
|
-
onUnitClick,
|
|
2785
|
-
onFeatureClick,
|
|
2786
|
-
onCanvasClick,
|
|
2787
|
-
onTileHover,
|
|
2788
|
-
onUnitAnimation
|
|
2789
|
-
} = options;
|
|
2790
|
-
const emit = useEmitEvent();
|
|
2791
|
-
const optionsRef = React113.useRef(options);
|
|
2792
|
-
optionsRef.current = options;
|
|
2793
|
-
const handleTileClick = React113.useCallback(
|
|
2794
|
-
(tile, event) => {
|
|
2795
|
-
if (tileClickEvent) {
|
|
2796
|
-
emit(tileClickEvent, {
|
|
2797
|
-
tileId: tile.id,
|
|
2798
|
-
x: tile.x,
|
|
2799
|
-
z: tile.z ?? tile.y ?? 0,
|
|
2800
|
-
type: tile.type,
|
|
2801
|
-
terrain: tile.terrain,
|
|
2802
|
-
elevation: tile.elevation
|
|
2803
|
-
});
|
|
2804
|
-
}
|
|
2805
|
-
optionsRef.current.onTileClick?.(tile, event);
|
|
2806
|
-
},
|
|
2807
|
-
[tileClickEvent, emit]
|
|
2808
|
-
);
|
|
2809
|
-
const handleUnitClick = React113.useCallback(
|
|
2810
|
-
(unit, event) => {
|
|
2811
|
-
if (unitClickEvent) {
|
|
2812
|
-
emit(unitClickEvent, {
|
|
2813
|
-
unitId: unit.id,
|
|
2814
|
-
x: unit.x,
|
|
2815
|
-
z: unit.z ?? unit.y ?? 0,
|
|
2816
|
-
unitType: unit.unitType,
|
|
2817
|
-
name: unit.name,
|
|
2818
|
-
team: unit.team,
|
|
2819
|
-
faction: unit.faction,
|
|
2820
|
-
health: unit.health,
|
|
2821
|
-
maxHealth: unit.maxHealth
|
|
2822
|
-
});
|
|
2823
|
-
}
|
|
2824
|
-
optionsRef.current.onUnitClick?.(unit, event);
|
|
2825
|
-
},
|
|
2826
|
-
[unitClickEvent, emit]
|
|
2827
|
-
);
|
|
2828
|
-
const handleFeatureClick = React113.useCallback(
|
|
2829
|
-
(feature, event) => {
|
|
2830
|
-
if (featureClickEvent) {
|
|
2831
|
-
emit(featureClickEvent, {
|
|
2832
|
-
featureId: feature.id,
|
|
2833
|
-
x: feature.x,
|
|
2834
|
-
z: feature.z ?? feature.y ?? 0,
|
|
2835
|
-
type: feature.type,
|
|
2836
|
-
elevation: feature.elevation
|
|
2837
|
-
});
|
|
2838
|
-
}
|
|
2839
|
-
optionsRef.current.onFeatureClick?.(feature, event);
|
|
2840
|
-
},
|
|
2841
|
-
[featureClickEvent, emit]
|
|
2842
|
-
);
|
|
2843
|
-
const handleCanvasClick = React113.useCallback(
|
|
2844
|
-
(event) => {
|
|
2845
|
-
if (canvasClickEvent) {
|
|
2846
|
-
emit(canvasClickEvent, {
|
|
2847
|
-
clientX: event.clientX,
|
|
2848
|
-
clientY: event.clientY,
|
|
2849
|
-
button: event.button
|
|
2850
|
-
});
|
|
2851
|
-
}
|
|
2852
|
-
optionsRef.current.onCanvasClick?.(event);
|
|
2853
|
-
},
|
|
2854
|
-
[canvasClickEvent, emit]
|
|
2855
|
-
);
|
|
2856
|
-
const handleTileHover = React113.useCallback(
|
|
2857
|
-
(tile, event) => {
|
|
2858
|
-
if (tile) {
|
|
2859
|
-
if (tileHoverEvent) {
|
|
2860
|
-
emit(tileHoverEvent, {
|
|
2861
|
-
tileId: tile.id,
|
|
2862
|
-
x: tile.x,
|
|
2863
|
-
z: tile.z ?? tile.y ?? 0,
|
|
2864
|
-
type: tile.type
|
|
2865
|
-
});
|
|
2866
|
-
}
|
|
2867
|
-
} else {
|
|
2868
|
-
if (tileLeaveEvent) {
|
|
2869
|
-
emit(tileLeaveEvent, {});
|
|
2870
|
-
}
|
|
2871
|
-
}
|
|
2872
|
-
optionsRef.current.onTileHover?.(tile, event);
|
|
2873
|
-
},
|
|
2874
|
-
[tileHoverEvent, tileLeaveEvent, emit]
|
|
2875
|
-
);
|
|
2876
|
-
const handleUnitAnimation = React113.useCallback(
|
|
2877
|
-
(unitId, state) => {
|
|
2878
|
-
if (unitAnimationEvent) {
|
|
2879
|
-
emit(unitAnimationEvent, {
|
|
2880
|
-
unitId,
|
|
2881
|
-
state,
|
|
2882
|
-
timestamp: Date.now()
|
|
2883
|
-
});
|
|
2884
|
-
}
|
|
2885
|
-
optionsRef.current.onUnitAnimation?.(unitId, state);
|
|
2886
|
-
},
|
|
2887
|
-
[unitAnimationEvent, emit]
|
|
2888
|
-
);
|
|
2889
|
-
const handleCameraChange = React113.useCallback(
|
|
2890
|
-
(position) => {
|
|
2891
|
-
if (cameraChangeEvent) {
|
|
2892
|
-
emit(cameraChangeEvent, {
|
|
2893
|
-
position,
|
|
2894
|
-
timestamp: Date.now()
|
|
2895
|
-
});
|
|
2896
|
-
}
|
|
2897
|
-
},
|
|
2898
|
-
[cameraChangeEvent, emit]
|
|
2899
|
-
);
|
|
2900
|
-
return {
|
|
2901
|
-
handleTileClick,
|
|
2902
|
-
handleUnitClick,
|
|
2903
|
-
handleFeatureClick,
|
|
2904
|
-
handleCanvasClick,
|
|
2905
|
-
handleTileHover,
|
|
2906
|
-
handleUnitAnimation,
|
|
2907
|
-
handleCameraChange
|
|
2908
|
-
};
|
|
2909
|
-
}
|
|
2910
|
-
function detectAssetRoot3(modelUrl) {
|
|
2911
|
-
const idx = modelUrl.indexOf("/3d/");
|
|
2912
|
-
if (idx !== -1) {
|
|
2913
|
-
return modelUrl.substring(0, idx + 4);
|
|
2914
|
-
}
|
|
2915
|
-
return modelUrl.substring(0, modelUrl.lastIndexOf("/") + 1);
|
|
2916
|
-
}
|
|
2917
|
-
function useGLTFModel2(url, resourceBasePath) {
|
|
2918
|
-
const [state, setState] = React113.useState({
|
|
2919
|
-
model: null,
|
|
2920
|
-
isLoading: false,
|
|
2921
|
-
error: null
|
|
2922
|
-
});
|
|
2923
|
-
React113.useEffect(() => {
|
|
2924
|
-
if (!url) {
|
|
2925
|
-
setState({ model: null, isLoading: false, error: null });
|
|
2926
|
-
return;
|
|
2927
|
-
}
|
|
2928
|
-
console.log("[ModelLoader] Loading:", url);
|
|
2929
|
-
setState((prev) => ({ ...prev, isLoading: true, error: null }));
|
|
2930
|
-
const assetRoot = resourceBasePath || detectAssetRoot3(url);
|
|
2931
|
-
const loader = new GLTFLoader.GLTFLoader();
|
|
2932
|
-
loader.setResourcePath(assetRoot);
|
|
2933
|
-
loader.load(
|
|
2934
|
-
url,
|
|
2935
|
-
(gltf) => {
|
|
2936
|
-
console.log("[ModelLoader] Loaded:", url);
|
|
2937
|
-
setState({
|
|
2938
|
-
model: gltf.scene,
|
|
2939
|
-
isLoading: false,
|
|
2940
|
-
error: null
|
|
2941
|
-
});
|
|
2942
|
-
},
|
|
2943
|
-
void 0,
|
|
2944
|
-
(err) => {
|
|
2945
|
-
const errorMsg = err instanceof Error ? err.message : String(err);
|
|
2946
|
-
console.warn("[ModelLoader] Failed:", url, errorMsg);
|
|
2947
|
-
setState({
|
|
2948
|
-
model: null,
|
|
2949
|
-
isLoading: false,
|
|
2950
|
-
error: err instanceof Error ? err : new Error(String(err))
|
|
2951
|
-
});
|
|
2952
|
-
}
|
|
2953
|
-
);
|
|
2954
|
-
}, [url, resourceBasePath]);
|
|
2955
|
-
return state;
|
|
2956
|
-
}
|
|
2957
|
-
function ModelLoader({
|
|
2958
|
-
url,
|
|
2959
|
-
position = [0, 0, 0],
|
|
2960
|
-
scale = 1,
|
|
2961
|
-
rotation = [0, 0, 0],
|
|
2962
|
-
isSelected = false,
|
|
2963
|
-
isHovered = false,
|
|
2964
|
-
onClick,
|
|
2965
|
-
onHover,
|
|
2966
|
-
fallbackGeometry = "box",
|
|
2967
|
-
castShadow = true,
|
|
2968
|
-
receiveShadow = true,
|
|
2969
|
-
resourceBasePath
|
|
2970
|
-
}) {
|
|
2971
|
-
const { model: loadedModel, isLoading, error } = useGLTFModel2(url, resourceBasePath);
|
|
2972
|
-
const model = React113.useMemo(() => {
|
|
2973
|
-
if (!loadedModel) return null;
|
|
2974
|
-
const cloned = loadedModel.clone();
|
|
2975
|
-
cloned.traverse((child) => {
|
|
2976
|
-
if (child instanceof THREE__namespace.Mesh) {
|
|
2977
|
-
child.castShadow = castShadow;
|
|
2978
|
-
child.receiveShadow = receiveShadow;
|
|
2979
|
-
}
|
|
2980
|
-
});
|
|
2981
|
-
return cloned;
|
|
2982
|
-
}, [loadedModel, castShadow, receiveShadow]);
|
|
2983
|
-
const scaleArray = React113.useMemo(() => {
|
|
2984
|
-
if (typeof scale === "number") {
|
|
2985
|
-
return [scale, scale, scale];
|
|
2986
|
-
}
|
|
2987
|
-
return scale;
|
|
2988
|
-
}, [scale]);
|
|
2989
|
-
const rotationRad = React113.useMemo(() => {
|
|
2990
|
-
return [
|
|
2991
|
-
rotation[0] * Math.PI / 180,
|
|
2992
|
-
rotation[1] * Math.PI / 180,
|
|
2993
|
-
rotation[2] * Math.PI / 180
|
|
2994
|
-
];
|
|
2995
|
-
}, [rotation]);
|
|
2996
|
-
if (isLoading) {
|
|
2997
|
-
return /* @__PURE__ */ jsxRuntime.jsx("group", { position, children: /* @__PURE__ */ jsxRuntime.jsxs("mesh", { rotation: [Math.PI / 2, 0, 0], children: [
|
|
2998
|
-
/* @__PURE__ */ jsxRuntime.jsx("ringGeometry", { args: [0.3, 0.35, 16] }),
|
|
2999
|
-
/* @__PURE__ */ jsxRuntime.jsx("meshBasicMaterial", { color: "#4a90d9", transparent: true, opacity: 0.8 })
|
|
3000
|
-
] }) });
|
|
3001
|
-
}
|
|
3002
|
-
if (error || !model) {
|
|
3003
|
-
if (fallbackGeometry === "none") {
|
|
3004
|
-
return /* @__PURE__ */ jsxRuntime.jsx("group", { position });
|
|
3005
|
-
}
|
|
3006
|
-
const fallbackProps = {
|
|
3007
|
-
onClick,
|
|
3008
|
-
onPointerOver: () => onHover?.(true),
|
|
3009
|
-
onPointerOut: () => onHover?.(false)
|
|
3010
|
-
};
|
|
3011
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("group", { position, children: [
|
|
3012
|
-
(isSelected || isHovered) && /* @__PURE__ */ jsxRuntime.jsxs("mesh", { position: [0, 0.02, 0], rotation: [-Math.PI / 2, 0, 0], children: [
|
|
3013
|
-
/* @__PURE__ */ jsxRuntime.jsx("ringGeometry", { args: [0.6, 0.7, 32] }),
|
|
3014
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3015
|
-
"meshBasicMaterial",
|
|
3016
|
-
{
|
|
3017
|
-
color: isSelected ? 16755200 : 16777215,
|
|
3018
|
-
transparent: true,
|
|
3019
|
-
opacity: 0.5
|
|
3020
|
-
}
|
|
3021
|
-
)
|
|
3022
|
-
] }),
|
|
3023
|
-
fallbackGeometry === "box" && /* @__PURE__ */ jsxRuntime.jsxs("mesh", { ...fallbackProps, position: [0, 0.5, 0], children: [
|
|
3024
|
-
/* @__PURE__ */ jsxRuntime.jsx("boxGeometry", { args: [0.8, 0.8, 0.8] }),
|
|
3025
|
-
/* @__PURE__ */ jsxRuntime.jsx("meshStandardMaterial", { color: error ? 16729156 : 8947848 })
|
|
3026
|
-
] }),
|
|
3027
|
-
fallbackGeometry === "sphere" && /* @__PURE__ */ jsxRuntime.jsxs("mesh", { ...fallbackProps, position: [0, 0.5, 0], children: [
|
|
3028
|
-
/* @__PURE__ */ jsxRuntime.jsx("sphereGeometry", { args: [0.4, 16, 16] }),
|
|
3029
|
-
/* @__PURE__ */ jsxRuntime.jsx("meshStandardMaterial", { color: error ? 16729156 : 8947848 })
|
|
3030
|
-
] }),
|
|
3031
|
-
fallbackGeometry === "cylinder" && /* @__PURE__ */ jsxRuntime.jsxs("mesh", { ...fallbackProps, position: [0, 0.5, 0], children: [
|
|
3032
|
-
/* @__PURE__ */ jsxRuntime.jsx("cylinderGeometry", { args: [0.3, 0.3, 0.8, 16] }),
|
|
3033
|
-
/* @__PURE__ */ jsxRuntime.jsx("meshStandardMaterial", { color: error ? 16729156 : 8947848 })
|
|
3034
|
-
] })
|
|
3035
|
-
] });
|
|
3036
|
-
}
|
|
3037
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3038
|
-
"group",
|
|
3039
|
-
{
|
|
3040
|
-
position,
|
|
3041
|
-
rotation: rotationRad,
|
|
3042
|
-
onClick,
|
|
3043
|
-
onPointerOver: () => onHover?.(true),
|
|
3044
|
-
onPointerOut: () => onHover?.(false),
|
|
3045
|
-
children: [
|
|
3046
|
-
(isSelected || isHovered) && /* @__PURE__ */ jsxRuntime.jsxs("mesh", { position: [0, 0.02, 0], rotation: [-Math.PI / 2, 0, 0], children: [
|
|
3047
|
-
/* @__PURE__ */ jsxRuntime.jsx("ringGeometry", { args: [0.6, 0.7, 32] }),
|
|
3048
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3049
|
-
"meshBasicMaterial",
|
|
3050
|
-
{
|
|
3051
|
-
color: isSelected ? 16755200 : 16777215,
|
|
3052
|
-
transparent: true,
|
|
3053
|
-
opacity: 0.5
|
|
3054
|
-
}
|
|
3055
|
-
)
|
|
3056
|
-
] }),
|
|
3057
|
-
/* @__PURE__ */ jsxRuntime.jsx("primitive", { object: model, scale: scaleArray })
|
|
3058
|
-
]
|
|
3059
|
-
}
|
|
3060
|
-
);
|
|
3061
|
-
}
|
|
3062
|
-
var DEFAULT_GRID_CONFIG = {
|
|
3063
|
-
cellSize: 1,
|
|
3064
|
-
offsetX: 0,
|
|
3065
|
-
offsetZ: 0
|
|
3066
|
-
};
|
|
3067
|
-
function CameraController({
|
|
3068
|
-
onCameraChange
|
|
3069
|
-
}) {
|
|
3070
|
-
const { camera } = fiber.useThree();
|
|
3071
|
-
React113.useEffect(() => {
|
|
3072
|
-
if (onCameraChange) {
|
|
3073
|
-
onCameraChange({
|
|
3074
|
-
x: camera.position.x,
|
|
3075
|
-
y: camera.position.y,
|
|
3076
|
-
z: camera.position.z
|
|
3077
|
-
});
|
|
3078
|
-
}
|
|
3079
|
-
}, [camera.position, onCameraChange]);
|
|
3080
|
-
return null;
|
|
3081
|
-
}
|
|
3082
|
-
var GameCanvas3D = React113.forwardRef(
|
|
3083
|
-
({
|
|
3084
|
-
tiles = [],
|
|
3085
|
-
units = [],
|
|
3086
|
-
features = [],
|
|
3087
|
-
events: events2 = [],
|
|
3088
|
-
orientation = "standard",
|
|
3089
|
-
cameraMode = "isometric",
|
|
3090
|
-
showGrid = true,
|
|
3091
|
-
showCoordinates = false,
|
|
3092
|
-
showTileInfo = false,
|
|
3093
|
-
overlay = "default",
|
|
3094
|
-
shadows = true,
|
|
3095
|
-
backgroundColor = "#1a1a2e",
|
|
3096
|
-
onTileClick,
|
|
3097
|
-
onUnitClick,
|
|
3098
|
-
onFeatureClick,
|
|
3099
|
-
onCanvasClick,
|
|
3100
|
-
onTileHover,
|
|
3101
|
-
onUnitAnimation,
|
|
3102
|
-
assetLoader: customAssetLoader,
|
|
3103
|
-
tileRenderer: CustomTileRenderer,
|
|
3104
|
-
unitRenderer: CustomUnitRenderer,
|
|
3105
|
-
featureRenderer: CustomFeatureRenderer,
|
|
3106
|
-
className,
|
|
3107
|
-
isLoading: externalLoading,
|
|
3108
|
-
error: externalError,
|
|
3109
|
-
entity,
|
|
3110
|
-
preloadAssets = [],
|
|
3111
|
-
tileClickEvent,
|
|
3112
|
-
unitClickEvent,
|
|
3113
|
-
featureClickEvent,
|
|
3114
|
-
canvasClickEvent,
|
|
3115
|
-
tileHoverEvent,
|
|
3116
|
-
tileLeaveEvent,
|
|
3117
|
-
unitAnimationEvent,
|
|
3118
|
-
cameraChangeEvent,
|
|
3119
|
-
loadingMessage = "Loading 3D Scene...",
|
|
3120
|
-
useInstancing = true,
|
|
3121
|
-
validMoves = [],
|
|
3122
|
-
attackTargets = [],
|
|
3123
|
-
selectedTileIds = [],
|
|
3124
|
-
selectedUnitId = null,
|
|
3125
|
-
children
|
|
3126
|
-
}, ref) => {
|
|
3127
|
-
const containerRef = React113.useRef(null);
|
|
3128
|
-
const controlsRef = React113.useRef(null);
|
|
3129
|
-
const [hoveredTile, setHoveredTile] = React113.useState(null);
|
|
3130
|
-
const [internalError, setInternalError] = React113.useState(null);
|
|
3131
|
-
const { isLoading: assetsLoading, progress, loaded, total } = useAssetLoader({
|
|
3132
|
-
preloadUrls: preloadAssets,
|
|
3133
|
-
loader: customAssetLoader
|
|
3134
|
-
});
|
|
3135
|
-
const eventHandlers = useGameCanvas3DEvents({
|
|
3136
|
-
tileClickEvent,
|
|
3137
|
-
unitClickEvent,
|
|
3138
|
-
featureClickEvent,
|
|
3139
|
-
canvasClickEvent,
|
|
3140
|
-
tileHoverEvent,
|
|
3141
|
-
tileLeaveEvent,
|
|
3142
|
-
unitAnimationEvent,
|
|
3143
|
-
cameraChangeEvent,
|
|
3144
|
-
onTileClick,
|
|
3145
|
-
onUnitClick,
|
|
3146
|
-
onFeatureClick,
|
|
3147
|
-
onCanvasClick,
|
|
3148
|
-
onTileHover,
|
|
3149
|
-
onUnitAnimation
|
|
3150
|
-
});
|
|
3151
|
-
const gridBounds = React113.useMemo(() => {
|
|
3152
|
-
if (tiles.length === 0) {
|
|
3153
|
-
return { minX: 0, maxX: 10, minZ: 0, maxZ: 10 };
|
|
3154
|
-
}
|
|
3155
|
-
const xs = tiles.map((t) => t.x);
|
|
3156
|
-
const zs = tiles.map((t) => t.z || t.y || 0);
|
|
3157
|
-
return {
|
|
3158
|
-
minX: Math.min(...xs),
|
|
3159
|
-
maxX: Math.max(...xs),
|
|
3160
|
-
minZ: Math.min(...zs),
|
|
3161
|
-
maxZ: Math.max(...zs)
|
|
3162
|
-
};
|
|
3163
|
-
}, [tiles]);
|
|
3164
|
-
const cameraTarget = React113.useMemo(() => {
|
|
3165
|
-
return [
|
|
3166
|
-
(gridBounds.minX + gridBounds.maxX) / 2,
|
|
3167
|
-
0,
|
|
3168
|
-
(gridBounds.minZ + gridBounds.maxZ) / 2
|
|
3169
|
-
];
|
|
3170
|
-
}, [gridBounds]);
|
|
3171
|
-
const gridConfig = React113.useMemo(
|
|
3172
|
-
() => ({
|
|
3173
|
-
...DEFAULT_GRID_CONFIG,
|
|
3174
|
-
offsetX: -(gridBounds.maxX - gridBounds.minX) / 2,
|
|
3175
|
-
offsetZ: -(gridBounds.maxZ - gridBounds.minZ) / 2
|
|
3176
|
-
}),
|
|
3177
|
-
[gridBounds]
|
|
3178
|
-
);
|
|
3179
|
-
const gridToWorld = React113.useCallback(
|
|
3180
|
-
(x, z, y = 0) => {
|
|
3181
|
-
const worldX = (x - gridBounds.minX) * gridConfig.cellSize;
|
|
3182
|
-
const worldZ = (z - gridBounds.minZ) * gridConfig.cellSize;
|
|
3183
|
-
return [worldX, y * gridConfig.cellSize, worldZ];
|
|
3184
|
-
},
|
|
3185
|
-
[gridBounds, gridConfig]
|
|
3186
|
-
);
|
|
3187
|
-
React113.useImperativeHandle(ref, () => ({
|
|
3188
|
-
getCameraPosition: () => {
|
|
3189
|
-
if (controlsRef.current) {
|
|
3190
|
-
const pos = controlsRef.current.object.position;
|
|
3191
|
-
return new THREE__namespace.Vector3(pos.x, pos.y, pos.z);
|
|
3192
|
-
}
|
|
3193
|
-
return null;
|
|
3194
|
-
},
|
|
3195
|
-
setCameraPosition: (x, y, z) => {
|
|
3196
|
-
if (controlsRef.current) {
|
|
3197
|
-
controlsRef.current.object.position.set(x, y, z);
|
|
3198
|
-
controlsRef.current.update();
|
|
3199
|
-
}
|
|
3200
|
-
},
|
|
3201
|
-
lookAt: (x, y, z) => {
|
|
3202
|
-
if (controlsRef.current) {
|
|
3203
|
-
controlsRef.current.target.set(x, y, z);
|
|
3204
|
-
controlsRef.current.update();
|
|
3205
|
-
}
|
|
3206
|
-
},
|
|
3207
|
-
resetCamera: () => {
|
|
3208
|
-
if (controlsRef.current) {
|
|
3209
|
-
controlsRef.current.reset();
|
|
3210
|
-
}
|
|
3211
|
-
},
|
|
3212
|
-
screenshot: () => {
|
|
3213
|
-
const canvas = containerRef.current?.querySelector("canvas");
|
|
3214
|
-
if (canvas) {
|
|
3215
|
-
return canvas.toDataURL("image/png");
|
|
3216
|
-
}
|
|
3217
|
-
return null;
|
|
3218
|
-
},
|
|
3219
|
-
export: () => ({
|
|
3220
|
-
tiles,
|
|
3221
|
-
units,
|
|
3222
|
-
features
|
|
3223
|
-
})
|
|
3224
|
-
}));
|
|
3225
|
-
const handleTileClick = React113.useCallback(
|
|
3226
|
-
(tile, event) => {
|
|
3227
|
-
eventHandlers.handleTileClick(tile, event);
|
|
3228
|
-
},
|
|
3229
|
-
[eventHandlers]
|
|
3230
|
-
);
|
|
3231
|
-
const handleUnitClick = React113.useCallback(
|
|
3232
|
-
(unit, event) => {
|
|
3233
|
-
eventHandlers.handleUnitClick(unit, event);
|
|
3234
|
-
},
|
|
3235
|
-
[eventHandlers]
|
|
3236
|
-
);
|
|
3237
|
-
const handleFeatureClick = React113.useCallback(
|
|
3238
|
-
(feature, event) => {
|
|
3239
|
-
if (event) {
|
|
3240
|
-
eventHandlers.handleFeatureClick(feature, event);
|
|
3241
|
-
}
|
|
3242
|
-
},
|
|
3243
|
-
[eventHandlers]
|
|
3244
|
-
);
|
|
3245
|
-
const handleTileHover = React113.useCallback(
|
|
3246
|
-
(tile, event) => {
|
|
3247
|
-
setHoveredTile(tile);
|
|
3248
|
-
if (event) {
|
|
3249
|
-
eventHandlers.handleTileHover(tile, event);
|
|
3250
|
-
}
|
|
3251
|
-
},
|
|
3252
|
-
[eventHandlers]
|
|
3253
|
-
);
|
|
3254
|
-
const cameraConfig = React113.useMemo(() => {
|
|
3255
|
-
const size = Math.max(
|
|
3256
|
-
gridBounds.maxX - gridBounds.minX,
|
|
3257
|
-
gridBounds.maxZ - gridBounds.minZ
|
|
3258
|
-
);
|
|
3259
|
-
const distance = size * 1.5;
|
|
3260
|
-
switch (cameraMode) {
|
|
3261
|
-
case "isometric":
|
|
3262
|
-
return {
|
|
3263
|
-
position: [distance, distance * 0.8, distance],
|
|
3264
|
-
fov: 45
|
|
3265
|
-
};
|
|
3266
|
-
case "top-down":
|
|
3267
|
-
return {
|
|
3268
|
-
position: [0, distance * 2, 0],
|
|
3269
|
-
fov: 45
|
|
3270
|
-
};
|
|
3271
|
-
case "perspective":
|
|
3272
|
-
default:
|
|
3273
|
-
return {
|
|
3274
|
-
position: [distance, distance, distance],
|
|
3275
|
-
fov: 45
|
|
3276
|
-
};
|
|
3277
|
-
}
|
|
3278
|
-
}, [cameraMode, gridBounds]);
|
|
3279
|
-
const DefaultTileRenderer = React113.useCallback(
|
|
3280
|
-
({ tile, position }) => {
|
|
3281
|
-
const isSelected = tile.id ? selectedTileIds.includes(tile.id) : false;
|
|
3282
|
-
const isHovered = hoveredTile?.id === tile.id;
|
|
3283
|
-
const isValidMove = validMoves.some(
|
|
3284
|
-
(m) => m.x === tile.x && m.z === (tile.z ?? tile.y ?? 0)
|
|
3285
|
-
);
|
|
3286
|
-
const isAttackTarget = attackTargets.some(
|
|
3287
|
-
(m) => m.x === tile.x && m.z === (tile.z ?? tile.y ?? 0)
|
|
3288
|
-
);
|
|
3289
|
-
let color = 8421504;
|
|
3290
|
-
if (tile.type === "water") color = 4491468;
|
|
3291
|
-
else if (tile.type === "grass") color = 4500036;
|
|
3292
|
-
else if (tile.type === "sand") color = 14535816;
|
|
3293
|
-
else if (tile.type === "rock") color = 8947848;
|
|
3294
|
-
else if (tile.type === "snow") color = 15658734;
|
|
3295
|
-
let emissive = 0;
|
|
3296
|
-
if (isSelected) emissive = 4473924;
|
|
3297
|
-
else if (isAttackTarget) emissive = 4456448;
|
|
3298
|
-
else if (isValidMove) emissive = 17408;
|
|
3299
|
-
else if (isHovered) emissive = 2236962;
|
|
3300
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3301
|
-
"mesh",
|
|
3302
|
-
{
|
|
3303
|
-
position,
|
|
3304
|
-
onClick: (e) => handleTileClick(tile, e),
|
|
3305
|
-
onPointerEnter: (e) => handleTileHover(tile, e),
|
|
3306
|
-
onPointerLeave: (e) => handleTileHover(null, e),
|
|
3307
|
-
userData: { type: "tile", tileId: tile.id, gridX: tile.x, gridZ: tile.z ?? tile.y },
|
|
3308
|
-
children: [
|
|
3309
|
-
/* @__PURE__ */ jsxRuntime.jsx("boxGeometry", { args: [0.95, 0.2, 0.95] }),
|
|
3310
|
-
/* @__PURE__ */ jsxRuntime.jsx("meshStandardMaterial", { color, emissive })
|
|
3311
|
-
]
|
|
3312
|
-
}
|
|
3313
|
-
);
|
|
3314
|
-
},
|
|
3315
|
-
[selectedTileIds, hoveredTile, validMoves, attackTargets, handleTileClick, handleTileHover]
|
|
3316
|
-
);
|
|
3317
|
-
const DefaultUnitRenderer = React113.useCallback(
|
|
3318
|
-
({ unit, position }) => {
|
|
3319
|
-
const isSelected = selectedUnitId === unit.id;
|
|
3320
|
-
const color = unit.faction === "player" ? 4491519 : unit.faction === "enemy" ? 16729156 : 16777028;
|
|
3321
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3322
|
-
"group",
|
|
3323
|
-
{
|
|
3324
|
-
position,
|
|
3325
|
-
onClick: (e) => handleUnitClick(unit, e),
|
|
3326
|
-
userData: { type: "unit", unitId: unit.id },
|
|
3327
|
-
children: [
|
|
3328
|
-
isSelected && /* @__PURE__ */ jsxRuntime.jsxs("mesh", { position: [0, 0.05, 0], rotation: [-Math.PI / 2, 0, 0], children: [
|
|
3329
|
-
/* @__PURE__ */ jsxRuntime.jsx("ringGeometry", { args: [0.4, 0.5, 32] }),
|
|
3330
|
-
/* @__PURE__ */ jsxRuntime.jsx("meshBasicMaterial", { color: "#ffff00", transparent: true, opacity: 0.8 })
|
|
3331
|
-
] }),
|
|
3332
|
-
/* @__PURE__ */ jsxRuntime.jsxs("mesh", { position: [0, 0.3, 0], children: [
|
|
3333
|
-
/* @__PURE__ */ jsxRuntime.jsx("cylinderGeometry", { args: [0.3, 0.3, 0.1, 8] }),
|
|
3334
|
-
/* @__PURE__ */ jsxRuntime.jsx("meshStandardMaterial", { color })
|
|
3335
|
-
] }),
|
|
3336
|
-
/* @__PURE__ */ jsxRuntime.jsxs("mesh", { position: [0, 0.6, 0], children: [
|
|
3337
|
-
/* @__PURE__ */ jsxRuntime.jsx("capsuleGeometry", { args: [0.2, 0.4, 4, 8] }),
|
|
3338
|
-
/* @__PURE__ */ jsxRuntime.jsx("meshStandardMaterial", { color })
|
|
3339
|
-
] }),
|
|
3340
|
-
/* @__PURE__ */ jsxRuntime.jsxs("mesh", { position: [0, 0.9, 0], children: [
|
|
3341
|
-
/* @__PURE__ */ jsxRuntime.jsx("sphereGeometry", { args: [0.12, 8, 8] }),
|
|
3342
|
-
/* @__PURE__ */ jsxRuntime.jsx("meshStandardMaterial", { color })
|
|
3343
|
-
] }),
|
|
3344
|
-
unit.health !== void 0 && unit.maxHealth !== void 0 && /* @__PURE__ */ jsxRuntime.jsxs("group", { position: [0, 1.2, 0], children: [
|
|
3345
|
-
/* @__PURE__ */ jsxRuntime.jsxs("mesh", { position: [-0.25, 0, 0], children: [
|
|
3346
|
-
/* @__PURE__ */ jsxRuntime.jsx("planeGeometry", { args: [0.5, 0.05] }),
|
|
3347
|
-
/* @__PURE__ */ jsxRuntime.jsx("meshBasicMaterial", { color: 3355443 })
|
|
3348
|
-
] }),
|
|
3349
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
3350
|
-
"mesh",
|
|
3351
|
-
{
|
|
3352
|
-
position: [
|
|
3353
|
-
-0.25 + 0.5 * (unit.health / unit.maxHealth) / 2,
|
|
3354
|
-
0,
|
|
3355
|
-
0.01
|
|
3356
|
-
],
|
|
3357
|
-
children: [
|
|
3358
|
-
/* @__PURE__ */ jsxRuntime.jsx("planeGeometry", { args: [0.5 * (unit.health / unit.maxHealth), 0.05] }),
|
|
3359
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3360
|
-
"meshBasicMaterial",
|
|
3361
|
-
{
|
|
3362
|
-
color: unit.health / unit.maxHealth > 0.5 ? 4500036 : unit.health / unit.maxHealth > 0.25 ? 11184708 : 16729156
|
|
3363
|
-
}
|
|
3364
|
-
)
|
|
3365
|
-
]
|
|
3366
|
-
}
|
|
3367
|
-
)
|
|
3368
|
-
] })
|
|
3369
|
-
]
|
|
3370
|
-
}
|
|
3371
|
-
);
|
|
3372
|
-
},
|
|
3373
|
-
[selectedUnitId, handleUnitClick]
|
|
3374
|
-
);
|
|
3375
|
-
const DefaultFeatureRenderer = React113.useCallback(
|
|
3376
|
-
({
|
|
3377
|
-
feature,
|
|
3378
|
-
position
|
|
3379
|
-
}) => {
|
|
3380
|
-
if (feature.assetUrl) {
|
|
3381
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
3382
|
-
ModelLoader,
|
|
3383
|
-
{
|
|
3384
|
-
url: feature.assetUrl,
|
|
3385
|
-
position,
|
|
3386
|
-
scale: 0.5,
|
|
3387
|
-
rotation: [0, feature.rotation ?? 0, 0],
|
|
3388
|
-
onClick: () => handleFeatureClick(feature, null),
|
|
3389
|
-
fallbackGeometry: "box"
|
|
3390
|
-
},
|
|
3391
|
-
feature.id
|
|
3392
|
-
);
|
|
3393
|
-
}
|
|
3394
|
-
if (feature.type === "tree") {
|
|
3395
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3396
|
-
"group",
|
|
3397
|
-
{
|
|
3398
|
-
position,
|
|
3399
|
-
onClick: (e) => handleFeatureClick(feature, e),
|
|
3400
|
-
userData: { type: "feature", featureId: feature.id },
|
|
3401
|
-
children: [
|
|
3402
|
-
/* @__PURE__ */ jsxRuntime.jsxs("mesh", { position: [0, 0.4, 0], children: [
|
|
3403
|
-
/* @__PURE__ */ jsxRuntime.jsx("cylinderGeometry", { args: [0.1, 0.15, 0.8, 6] }),
|
|
3404
|
-
/* @__PURE__ */ jsxRuntime.jsx("meshStandardMaterial", { color: 9127187 })
|
|
3405
|
-
] }),
|
|
3406
|
-
/* @__PURE__ */ jsxRuntime.jsxs("mesh", { position: [0, 0.9, 0], children: [
|
|
3407
|
-
/* @__PURE__ */ jsxRuntime.jsx("coneGeometry", { args: [0.5, 0.8, 8] }),
|
|
3408
|
-
/* @__PURE__ */ jsxRuntime.jsx("meshStandardMaterial", { color: 2263842 })
|
|
3409
|
-
] })
|
|
3410
|
-
]
|
|
3411
|
-
}
|
|
3412
|
-
);
|
|
3413
|
-
}
|
|
3414
|
-
if (feature.type === "rock") {
|
|
3415
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3416
|
-
"mesh",
|
|
3417
|
-
{
|
|
3418
|
-
position: [position[0], position[1] + 0.3, position[2]],
|
|
3419
|
-
onClick: (e) => handleFeatureClick(feature, e),
|
|
3420
|
-
userData: { type: "feature", featureId: feature.id },
|
|
3421
|
-
children: [
|
|
3422
|
-
/* @__PURE__ */ jsxRuntime.jsx("dodecahedronGeometry", { args: [0.3, 0] }),
|
|
3423
|
-
/* @__PURE__ */ jsxRuntime.jsx("meshStandardMaterial", { color: 8421504 })
|
|
3424
|
-
]
|
|
3425
|
-
}
|
|
3426
|
-
);
|
|
3427
|
-
}
|
|
3428
|
-
return null;
|
|
3429
|
-
},
|
|
3430
|
-
[handleFeatureClick]
|
|
3431
|
-
);
|
|
3432
|
-
if (externalLoading || assetsLoading && preloadAssets.length > 0) {
|
|
3433
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
3434
|
-
Canvas3DLoadingState,
|
|
3435
|
-
{
|
|
3436
|
-
progress,
|
|
3437
|
-
loaded,
|
|
3438
|
-
total,
|
|
3439
|
-
message: loadingMessage,
|
|
3440
|
-
className
|
|
3441
|
-
}
|
|
3442
|
-
);
|
|
3443
|
-
}
|
|
3444
|
-
const displayError = externalError || internalError;
|
|
3445
|
-
if (displayError) {
|
|
3446
|
-
return /* @__PURE__ */ jsxRuntime.jsx(Canvas3DErrorBoundary, { children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "game-canvas-3d game-canvas-3d--error", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "game-canvas-3d__error", children: [
|
|
3447
|
-
"Error: ",
|
|
3448
|
-
displayError
|
|
3449
|
-
] }) }) });
|
|
3450
|
-
}
|
|
3451
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
3452
|
-
Canvas3DErrorBoundary,
|
|
3453
|
-
{
|
|
3454
|
-
onError: (err) => setInternalError(err.message),
|
|
3455
|
-
onReset: () => setInternalError(null),
|
|
3456
|
-
children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3457
|
-
"div",
|
|
3458
|
-
{
|
|
3459
|
-
ref: containerRef,
|
|
3460
|
-
className: `game-canvas-3d ${className || ""}`,
|
|
3461
|
-
"data-orientation": orientation,
|
|
3462
|
-
"data-camera-mode": cameraMode,
|
|
3463
|
-
"data-overlay": overlay,
|
|
3464
|
-
children: [
|
|
3465
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
3466
|
-
fiber.Canvas,
|
|
3467
|
-
{
|
|
3468
|
-
shadows,
|
|
3469
|
-
camera: {
|
|
3470
|
-
position: cameraConfig.position,
|
|
3471
|
-
fov: cameraConfig.fov,
|
|
3472
|
-
near: 0.1,
|
|
3473
|
-
far: 1e3
|
|
3474
|
-
},
|
|
3475
|
-
style: { background: backgroundColor },
|
|
3476
|
-
onClick: (e) => {
|
|
3477
|
-
if (e.target === e.currentTarget) {
|
|
3478
|
-
eventHandlers.handleCanvasClick(e);
|
|
3479
|
-
}
|
|
3480
|
-
},
|
|
3481
|
-
children: [
|
|
3482
|
-
/* @__PURE__ */ jsxRuntime.jsx(CameraController, { onCameraChange: eventHandlers.handleCameraChange }),
|
|
3483
|
-
/* @__PURE__ */ jsxRuntime.jsx("ambientLight", { intensity: 0.6 }),
|
|
3484
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3485
|
-
"directionalLight",
|
|
3486
|
-
{
|
|
3487
|
-
position: [10, 20, 10],
|
|
3488
|
-
intensity: 0.8,
|
|
3489
|
-
castShadow: shadows,
|
|
3490
|
-
"shadow-mapSize": [2048, 2048]
|
|
3491
|
-
}
|
|
3492
|
-
),
|
|
3493
|
-
/* @__PURE__ */ jsxRuntime.jsx("hemisphereLight", { intensity: 0.3, color: "#87ceeb", groundColor: "#362d1d" }),
|
|
3494
|
-
showGrid && /* @__PURE__ */ jsxRuntime.jsx(
|
|
3495
|
-
drei.Grid,
|
|
3496
|
-
{
|
|
3497
|
-
args: [
|
|
3498
|
-
Math.max(gridBounds.maxX - gridBounds.minX + 2, 10),
|
|
3499
|
-
Math.max(gridBounds.maxZ - gridBounds.minZ + 2, 10)
|
|
3500
|
-
],
|
|
3501
|
-
position: [
|
|
3502
|
-
(gridBounds.maxX - gridBounds.minX) / 2 - 0.5,
|
|
3503
|
-
0,
|
|
3504
|
-
(gridBounds.maxZ - gridBounds.minZ) / 2 - 0.5
|
|
3505
|
-
],
|
|
3506
|
-
cellSize: 1,
|
|
3507
|
-
cellThickness: 1,
|
|
3508
|
-
cellColor: "#444444",
|
|
3509
|
-
sectionSize: 5,
|
|
3510
|
-
sectionThickness: 1.5,
|
|
3511
|
-
sectionColor: "#666666",
|
|
3512
|
-
fadeDistance: 50,
|
|
3513
|
-
fadeStrength: 1
|
|
3514
|
-
}
|
|
3515
|
-
),
|
|
3516
|
-
tiles.map((tile, index) => {
|
|
3517
|
-
const position = gridToWorld(
|
|
3518
|
-
tile.x,
|
|
3519
|
-
tile.z ?? tile.y ?? 0,
|
|
3520
|
-
tile.elevation ?? 0
|
|
3521
|
-
);
|
|
3522
|
-
const Renderer = CustomTileRenderer || DefaultTileRenderer;
|
|
3523
|
-
return /* @__PURE__ */ jsxRuntime.jsx(Renderer, { tile, position }, tile.id ?? `tile-${index}`);
|
|
3524
|
-
}),
|
|
3525
|
-
features.map((feature, index) => {
|
|
3526
|
-
const position = gridToWorld(
|
|
3527
|
-
feature.x,
|
|
3528
|
-
feature.z ?? feature.y ?? 0,
|
|
3529
|
-
(feature.elevation ?? 0) + 0.5
|
|
3530
|
-
);
|
|
3531
|
-
const Renderer = CustomFeatureRenderer || DefaultFeatureRenderer;
|
|
3532
|
-
return /* @__PURE__ */ jsxRuntime.jsx(Renderer, { feature, position }, feature.id ?? `feature-${index}`);
|
|
3533
|
-
}),
|
|
3534
|
-
units.map((unit) => {
|
|
3535
|
-
const position = gridToWorld(
|
|
3536
|
-
unit.x ?? 0,
|
|
3537
|
-
unit.z ?? unit.y ?? 0,
|
|
3538
|
-
(unit.elevation ?? 0) + 0.5
|
|
3539
|
-
);
|
|
3540
|
-
const Renderer = CustomUnitRenderer || DefaultUnitRenderer;
|
|
3541
|
-
return /* @__PURE__ */ jsxRuntime.jsx(Renderer, { unit, position }, unit.id);
|
|
3542
|
-
}),
|
|
3543
|
-
children,
|
|
3544
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3545
|
-
drei.OrbitControls,
|
|
3546
|
-
{
|
|
3547
|
-
ref: controlsRef,
|
|
3548
|
-
target: cameraTarget,
|
|
3549
|
-
enableDamping: true,
|
|
3550
|
-
dampingFactor: 0.05,
|
|
3551
|
-
minDistance: 2,
|
|
3552
|
-
maxDistance: 100,
|
|
3553
|
-
maxPolarAngle: Math.PI / 2 - 0.1
|
|
3554
|
-
}
|
|
3555
|
-
)
|
|
3556
|
-
]
|
|
3557
|
-
}
|
|
3558
|
-
),
|
|
3559
|
-
showCoordinates && hoveredTile && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "game-canvas-3d__coordinates", children: [
|
|
3560
|
-
"X: ",
|
|
3561
|
-
hoveredTile.x,
|
|
3562
|
-
", Z: ",
|
|
3563
|
-
hoveredTile.z ?? hoveredTile.y ?? 0
|
|
3564
|
-
] }),
|
|
3565
|
-
showTileInfo && hoveredTile && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "game-canvas-3d__tile-info", children: [
|
|
3566
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "tile-info__type", children: hoveredTile.type }),
|
|
3567
|
-
hoveredTile.terrain && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "tile-info__terrain", children: hoveredTile.terrain })
|
|
3568
|
-
] })
|
|
3569
|
-
]
|
|
3570
|
-
}
|
|
3571
|
-
)
|
|
3572
|
-
}
|
|
3573
|
-
);
|
|
3574
|
-
}
|
|
3575
|
-
);
|
|
3576
|
-
GameCanvas3D.displayName = "GameCanvas3D";
|
|
3577
2179
|
|
|
3578
2180
|
// lib/traitRegistry.ts
|
|
3579
2181
|
var traits = /* @__PURE__ */ new Map();
|
|
@@ -3597,9 +2199,38 @@ function unregisterTrait(id) {
|
|
|
3597
2199
|
traits.delete(id);
|
|
3598
2200
|
notifyListeners2();
|
|
3599
2201
|
}
|
|
3600
|
-
|
|
3601
|
-
|
|
3602
|
-
|
|
2202
|
+
|
|
2203
|
+
// components/organisms/component-registry.generated.ts
|
|
2204
|
+
function lazyThree(name, loader) {
|
|
2205
|
+
const Lazy = React110__namespace.default.lazy(() => loader().then((m) => ({ default: m[name] })));
|
|
2206
|
+
function ThreeWrapper(props) {
|
|
2207
|
+
return React110__namespace.default.createElement(
|
|
2208
|
+
React110__namespace.default.Suspense,
|
|
2209
|
+
{ fallback: null },
|
|
2210
|
+
React110__namespace.default.createElement(Lazy, props)
|
|
2211
|
+
);
|
|
2212
|
+
}
|
|
2213
|
+
ThreeWrapper.displayName = `Lazy(${name})`;
|
|
2214
|
+
return ThreeWrapper;
|
|
2215
|
+
}
|
|
2216
|
+
lazyThree("Camera3D", () => import('@almadar/ui/components/organisms/game/three'));
|
|
2217
|
+
lazyThree("Canvas3DErrorBoundary", () => import('@almadar/ui/components/organisms/game/three'));
|
|
2218
|
+
lazyThree("Canvas3DLoadingState", () => import('@almadar/ui/components/organisms/game/three'));
|
|
2219
|
+
lazyThree("FeatureRenderer", () => import('@almadar/ui/components/organisms/game/three'));
|
|
2220
|
+
lazyThree("FeatureRenderer3D", () => import('@almadar/ui/components/organisms/game/three'));
|
|
2221
|
+
lazyThree("GameCanvas3D", () => import('@almadar/ui/components/organisms/game/three'));
|
|
2222
|
+
lazyThree("GameCanvas3DBattleTemplate", () => import('@almadar/ui/components/organisms/game/three'));
|
|
2223
|
+
lazyThree("GameCanvas3DCastleTemplate", () => import('@almadar/ui/components/organisms/game/three'));
|
|
2224
|
+
lazyThree("GameCanvas3DWorldMapTemplate", () => import('@almadar/ui/components/organisms/game/three'));
|
|
2225
|
+
lazyThree("Lighting3D", () => import('@almadar/ui/components/organisms/game/three'));
|
|
2226
|
+
lazyThree("ModelLoader", () => import('@almadar/ui/components/organisms/game/three'));
|
|
2227
|
+
lazyThree("PhysicsObject3D", () => import('@almadar/ui/components/organisms/game/three'));
|
|
2228
|
+
lazyThree("Scene3D", () => import('@almadar/ui/components/organisms/game/three'));
|
|
2229
|
+
lazyThree("TileRenderer", () => import('@almadar/ui/components/organisms/game/three'));
|
|
2230
|
+
lazyThree("UnitRenderer", () => import('@almadar/ui/components/organisms/game/three'));
|
|
2231
|
+
React110.createContext({ enabled: false });
|
|
2232
|
+
React110.createContext(false);
|
|
2233
|
+
React110.createContext(null);
|
|
3603
2234
|
|
|
3604
2235
|
// runtime/createClientEffectHandlers.ts
|
|
3605
2236
|
function createClientEffectHandlers(options) {
|
|
@@ -3635,19 +2266,19 @@ function createClientEffectHandlers(options) {
|
|
|
3635
2266
|
})
|
|
3636
2267
|
};
|
|
3637
2268
|
}
|
|
3638
|
-
var EntitySchemaContext =
|
|
2269
|
+
var EntitySchemaContext = React110.createContext(null);
|
|
3639
2270
|
function EntitySchemaProvider({
|
|
3640
2271
|
entities,
|
|
3641
2272
|
children
|
|
3642
2273
|
}) {
|
|
3643
|
-
const entitiesMap =
|
|
2274
|
+
const entitiesMap = React110.useMemo(() => {
|
|
3644
2275
|
const map = /* @__PURE__ */ new Map();
|
|
3645
2276
|
for (const entity of entities) {
|
|
3646
2277
|
map.set(entity.name, entity);
|
|
3647
2278
|
}
|
|
3648
2279
|
return map;
|
|
3649
2280
|
}, [entities]);
|
|
3650
|
-
const contextValue =
|
|
2281
|
+
const contextValue = React110.useMemo(
|
|
3651
2282
|
() => ({
|
|
3652
2283
|
entities: entitiesMap
|
|
3653
2284
|
}),
|
|
@@ -3656,7 +2287,7 @@ function EntitySchemaProvider({
|
|
|
3656
2287
|
return /* @__PURE__ */ jsxRuntime.jsx(EntitySchemaContext.Provider, { value: contextValue, children });
|
|
3657
2288
|
}
|
|
3658
2289
|
function useEntitySchema() {
|
|
3659
|
-
const context =
|
|
2290
|
+
const context = React110.useContext(EntitySchemaContext);
|
|
3660
2291
|
if (!context) {
|
|
3661
2292
|
throw new Error("useEntitySchema must be used within an EntitySchemaProvider");
|
|
3662
2293
|
}
|
|
@@ -3683,41 +2314,41 @@ function useTraitStateMachine(traitBindings, slotsActions, options) {
|
|
|
3683
2314
|
const eventBus = useEventBus();
|
|
3684
2315
|
const { entities } = useEntitySchema();
|
|
3685
2316
|
const fetchedDataContext = useFetchedDataContext();
|
|
3686
|
-
const manager =
|
|
2317
|
+
const manager = React110.useMemo(() => {
|
|
3687
2318
|
const traitDefs = traitBindings.map(toTraitDefinition);
|
|
3688
2319
|
return new runtime.StateMachineManager(traitDefs);
|
|
3689
2320
|
}, [traitBindings]);
|
|
3690
|
-
const [traitStates, setTraitStates] =
|
|
2321
|
+
const [traitStates, setTraitStates] = React110.useState(() => {
|
|
3691
2322
|
return manager.getAllStates();
|
|
3692
2323
|
});
|
|
3693
|
-
const eventQueueRef =
|
|
3694
|
-
const processingRef =
|
|
3695
|
-
const traitBindingsRef =
|
|
3696
|
-
const managerRef =
|
|
3697
|
-
const slotsActionsRef =
|
|
3698
|
-
const optionsRef =
|
|
3699
|
-
|
|
2324
|
+
const eventQueueRef = React110.useRef([]);
|
|
2325
|
+
const processingRef = React110.useRef(false);
|
|
2326
|
+
const traitBindingsRef = React110.useRef(traitBindings);
|
|
2327
|
+
const managerRef = React110.useRef(manager);
|
|
2328
|
+
const slotsActionsRef = React110.useRef(slotsActions);
|
|
2329
|
+
const optionsRef = React110.useRef(options);
|
|
2330
|
+
React110.useEffect(() => {
|
|
3700
2331
|
traitBindingsRef.current = traitBindings;
|
|
3701
2332
|
}, [traitBindings]);
|
|
3702
|
-
|
|
2333
|
+
React110.useEffect(() => {
|
|
3703
2334
|
managerRef.current = manager;
|
|
3704
2335
|
setTraitStates(manager.getAllStates());
|
|
3705
2336
|
}, [manager]);
|
|
3706
|
-
|
|
2337
|
+
React110.useEffect(() => {
|
|
3707
2338
|
slotsActionsRef.current = slotsActions;
|
|
3708
2339
|
}, [slotsActions]);
|
|
3709
|
-
|
|
2340
|
+
React110.useEffect(() => {
|
|
3710
2341
|
optionsRef.current = options;
|
|
3711
2342
|
}, [options]);
|
|
3712
|
-
const traitStatesRef =
|
|
3713
|
-
const fetchedDataContextRef =
|
|
3714
|
-
|
|
2343
|
+
const traitStatesRef = React110.useRef(traitStates);
|
|
2344
|
+
const fetchedDataContextRef = React110.useRef(fetchedDataContext);
|
|
2345
|
+
React110.useEffect(() => {
|
|
3715
2346
|
traitStatesRef.current = traitStates;
|
|
3716
2347
|
}, [traitStates]);
|
|
3717
|
-
|
|
2348
|
+
React110.useEffect(() => {
|
|
3718
2349
|
fetchedDataContextRef.current = fetchedDataContext;
|
|
3719
2350
|
}, [fetchedDataContext]);
|
|
3720
|
-
|
|
2351
|
+
React110.useEffect(() => {
|
|
3721
2352
|
const mgr = managerRef.current;
|
|
3722
2353
|
const bindings = traitBindingsRef.current;
|
|
3723
2354
|
const ids = [];
|
|
@@ -3750,7 +2381,7 @@ function useTraitStateMachine(traitBindings, slotsActions, options) {
|
|
|
3750
2381
|
}
|
|
3751
2382
|
};
|
|
3752
2383
|
}, [traitBindings]);
|
|
3753
|
-
|
|
2384
|
+
React110.useEffect(() => {
|
|
3754
2385
|
const newManager = managerRef.current;
|
|
3755
2386
|
newManager.resetAll();
|
|
3756
2387
|
setTraitStates(newManager.getAllStates());
|
|
@@ -3759,7 +2390,7 @@ function useTraitStateMachine(traitBindings, slotsActions, options) {
|
|
|
3759
2390
|
Array.from(newManager.getAllStates().keys()).join(", ")
|
|
3760
2391
|
);
|
|
3761
2392
|
}, [traitBindings]);
|
|
3762
|
-
const runTickEffects =
|
|
2393
|
+
const runTickEffects = React110.useCallback((tick, binding) => {
|
|
3763
2394
|
const fdc = fetchedDataContextRef.current;
|
|
3764
2395
|
const actions = slotsActionsRef.current;
|
|
3765
2396
|
const linkedEntity = binding.linkedEntity ?? "";
|
|
@@ -3858,7 +2489,7 @@ function useTraitStateMachine(traitBindings, slotsActions, options) {
|
|
|
3858
2489
|
}
|
|
3859
2490
|
}
|
|
3860
2491
|
}, []);
|
|
3861
|
-
|
|
2492
|
+
React110.useEffect(() => {
|
|
3862
2493
|
const hasFrameTicks = traitBindingsRef.current.some(
|
|
3863
2494
|
(b) => b.trait.ticks?.some((t) => t.interval === "frame")
|
|
3864
2495
|
);
|
|
@@ -3881,7 +2512,7 @@ function useTraitStateMachine(traitBindings, slotsActions, options) {
|
|
|
3881
2512
|
cancelAnimationFrame(rafId);
|
|
3882
2513
|
};
|
|
3883
2514
|
}, [traitBindings, runTickEffects]);
|
|
3884
|
-
|
|
2515
|
+
React110.useEffect(() => {
|
|
3885
2516
|
const intervals = [];
|
|
3886
2517
|
for (const binding of traitBindings) {
|
|
3887
2518
|
for (const tick of binding.trait.ticks ?? []) {
|
|
@@ -3896,7 +2527,7 @@ function useTraitStateMachine(traitBindings, slotsActions, options) {
|
|
|
3896
2527
|
for (const id of intervals) clearInterval(id);
|
|
3897
2528
|
};
|
|
3898
2529
|
}, [traitBindings, runTickEffects]);
|
|
3899
|
-
const processEventQueued =
|
|
2530
|
+
const processEventQueued = React110.useCallback(async (eventKey, payload) => {
|
|
3900
2531
|
const normalizedEvent = normalizeEventKey(eventKey);
|
|
3901
2532
|
const bindings = traitBindingsRef.current;
|
|
3902
2533
|
const currentManager = managerRef.current;
|
|
@@ -4163,7 +2794,7 @@ function useTraitStateMachine(traitBindings, slotsActions, options) {
|
|
|
4163
2794
|
onEventProcessed(normalizedEvent, payload);
|
|
4164
2795
|
}
|
|
4165
2796
|
}, [entities, fetchedDataContext, eventBus]);
|
|
4166
|
-
const drainEventQueue =
|
|
2797
|
+
const drainEventQueue = React110.useCallback(async () => {
|
|
4167
2798
|
if (processingRef.current) return;
|
|
4168
2799
|
processingRef.current = true;
|
|
4169
2800
|
try {
|
|
@@ -4175,24 +2806,24 @@ function useTraitStateMachine(traitBindings, slotsActions, options) {
|
|
|
4175
2806
|
processingRef.current = false;
|
|
4176
2807
|
}
|
|
4177
2808
|
}, [processEventQueued]);
|
|
4178
|
-
const enqueueAndDrain =
|
|
2809
|
+
const enqueueAndDrain = React110.useCallback((eventKey, payload) => {
|
|
4179
2810
|
eventQueueRef.current.push({ eventKey, payload });
|
|
4180
2811
|
void drainEventQueue();
|
|
4181
2812
|
}, [drainEventQueue]);
|
|
4182
|
-
|
|
2813
|
+
React110.useCallback((eventKey, payload) => {
|
|
4183
2814
|
enqueueAndDrain(eventKey, payload);
|
|
4184
2815
|
}, [enqueueAndDrain]);
|
|
4185
|
-
const sendEvent =
|
|
2816
|
+
const sendEvent = React110.useCallback((eventKey, payload) => {
|
|
4186
2817
|
enqueueAndDrain(eventKey, payload);
|
|
4187
2818
|
}, [enqueueAndDrain]);
|
|
4188
|
-
const getTraitState =
|
|
2819
|
+
const getTraitState = React110.useCallback((traitName) => {
|
|
4189
2820
|
return managerRef.current.getState(traitName);
|
|
4190
2821
|
}, []);
|
|
4191
|
-
const canHandleEvent =
|
|
2822
|
+
const canHandleEvent = React110.useCallback((traitName, eventKey) => {
|
|
4192
2823
|
const normalizedEvent = normalizeEventKey(eventKey);
|
|
4193
2824
|
return managerRef.current.canHandleEvent(traitName, normalizedEvent);
|
|
4194
2825
|
}, []);
|
|
4195
|
-
|
|
2826
|
+
React110.useEffect(() => {
|
|
4196
2827
|
const allEvents = /* @__PURE__ */ new Set();
|
|
4197
2828
|
for (const binding of traitBindings) {
|
|
4198
2829
|
for (const event of binding.trait.events) {
|
|
@@ -4228,9 +2859,9 @@ function useTraitStateMachine(traitBindings, slotsActions, options) {
|
|
|
4228
2859
|
};
|
|
4229
2860
|
}
|
|
4230
2861
|
function useResolvedSchema(schema, pageName) {
|
|
4231
|
-
const [loading, setLoading] =
|
|
4232
|
-
const [error, setError] =
|
|
4233
|
-
const ir =
|
|
2862
|
+
const [loading, setLoading] = React110.useState(true);
|
|
2863
|
+
const [error, setError] = React110.useState(null);
|
|
2864
|
+
const ir = React110.useMemo(() => {
|
|
4234
2865
|
if (!schema) return null;
|
|
4235
2866
|
try {
|
|
4236
2867
|
return core.schemaToIR(schema);
|
|
@@ -4239,10 +2870,10 @@ function useResolvedSchema(schema, pageName) {
|
|
|
4239
2870
|
return null;
|
|
4240
2871
|
}
|
|
4241
2872
|
}, [schema]);
|
|
4242
|
-
|
|
2873
|
+
React110.useEffect(() => {
|
|
4243
2874
|
setLoading(false);
|
|
4244
2875
|
}, [ir]);
|
|
4245
|
-
const result =
|
|
2876
|
+
const result = React110.useMemo(() => {
|
|
4246
2877
|
if (!ir) {
|
|
4247
2878
|
return {
|
|
4248
2879
|
page: void 0,
|
|
@@ -4280,12 +2911,12 @@ function useResolvedSchema(schema, pageName) {
|
|
|
4280
2911
|
function clearSchemaCache() {
|
|
4281
2912
|
core.clearSchemaCache();
|
|
4282
2913
|
}
|
|
4283
|
-
var TraitContext =
|
|
2914
|
+
var TraitContext = React110.createContext(null);
|
|
4284
2915
|
function TraitProvider({
|
|
4285
2916
|
traits: traitBindings,
|
|
4286
2917
|
children
|
|
4287
2918
|
}) {
|
|
4288
|
-
const traitInstances =
|
|
2919
|
+
const traitInstances = React110.useMemo(() => {
|
|
4289
2920
|
const map = /* @__PURE__ */ new Map();
|
|
4290
2921
|
for (const binding of traitBindings) {
|
|
4291
2922
|
const trait = binding.trait;
|
|
@@ -4309,7 +2940,7 @@ function TraitProvider({
|
|
|
4309
2940
|
}
|
|
4310
2941
|
return map;
|
|
4311
2942
|
}, [traitBindings]);
|
|
4312
|
-
const contextValue =
|
|
2943
|
+
const contextValue = React110.useMemo(() => {
|
|
4313
2944
|
return {
|
|
4314
2945
|
traits: traitInstances,
|
|
4315
2946
|
getTrait: (name) => traitInstances.get(name),
|
|
@@ -4328,7 +2959,7 @@ function TraitProvider({
|
|
|
4328
2959
|
return /* @__PURE__ */ jsxRuntime.jsx(TraitContext.Provider, { value: contextValue, children });
|
|
4329
2960
|
}
|
|
4330
2961
|
function useTraitContext() {
|
|
4331
|
-
const context =
|
|
2962
|
+
const context = React110.useContext(TraitContext);
|
|
4332
2963
|
if (!context) {
|
|
4333
2964
|
throw new Error("useTraitContext must be used within a TraitProvider");
|
|
4334
2965
|
}
|
|
@@ -4338,17 +2969,17 @@ function useTrait(traitName) {
|
|
|
4338
2969
|
const context = useTraitContext();
|
|
4339
2970
|
return context.getTrait(traitName);
|
|
4340
2971
|
}
|
|
4341
|
-
var SlotsStateContext =
|
|
4342
|
-
var SlotsActionsContext =
|
|
2972
|
+
var SlotsStateContext = React110.createContext({});
|
|
2973
|
+
var SlotsActionsContext = React110.createContext(null);
|
|
4343
2974
|
function SlotsProvider({ children }) {
|
|
4344
|
-
const [slots, setSlots] =
|
|
4345
|
-
const setSlotPatterns =
|
|
2975
|
+
const [slots, setSlots] = React110.useState({});
|
|
2976
|
+
const setSlotPatterns = React110.useCallback((slot, patterns, source) => {
|
|
4346
2977
|
setSlots((prev) => ({
|
|
4347
2978
|
...prev,
|
|
4348
2979
|
[slot]: { patterns, source }
|
|
4349
2980
|
}));
|
|
4350
2981
|
}, []);
|
|
4351
|
-
const clearSlot =
|
|
2982
|
+
const clearSlot = React110.useCallback((slot) => {
|
|
4352
2983
|
setSlots((prev) => {
|
|
4353
2984
|
if (!(slot in prev)) return prev;
|
|
4354
2985
|
const next = { ...prev };
|
|
@@ -4356,12 +2987,12 @@ function SlotsProvider({ children }) {
|
|
|
4356
2987
|
return next;
|
|
4357
2988
|
});
|
|
4358
2989
|
}, []);
|
|
4359
|
-
const clearAllSlots =
|
|
2990
|
+
const clearAllSlots = React110.useCallback(() => {
|
|
4360
2991
|
setSlots({});
|
|
4361
2992
|
}, []);
|
|
4362
|
-
const actionsRef =
|
|
2993
|
+
const actionsRef = React110.useRef({ setSlotPatterns, clearSlot, clearAllSlots });
|
|
4363
2994
|
actionsRef.current = { setSlotPatterns, clearSlot, clearAllSlots };
|
|
4364
|
-
const [stableActions] =
|
|
2995
|
+
const [stableActions] = React110.useState(() => ({
|
|
4365
2996
|
setSlotPatterns: (...args) => actionsRef.current.setSlotPatterns(...args),
|
|
4366
2997
|
clearSlot: (...args) => actionsRef.current.clearSlot(...args),
|
|
4367
2998
|
clearAllSlots: () => actionsRef.current.clearAllSlots()
|
|
@@ -4369,14 +3000,14 @@ function SlotsProvider({ children }) {
|
|
|
4369
3000
|
return /* @__PURE__ */ jsxRuntime.jsx(SlotsActionsContext.Provider, { value: stableActions, children: /* @__PURE__ */ jsxRuntime.jsx(SlotsStateContext.Provider, { value: slots, children }) });
|
|
4370
3001
|
}
|
|
4371
3002
|
function useSlots() {
|
|
4372
|
-
return
|
|
3003
|
+
return React110.useContext(SlotsStateContext);
|
|
4373
3004
|
}
|
|
4374
3005
|
function useSlotContent(slotName) {
|
|
4375
|
-
const slots =
|
|
3006
|
+
const slots = React110.useContext(SlotsStateContext);
|
|
4376
3007
|
return slots[slotName] || null;
|
|
4377
3008
|
}
|
|
4378
3009
|
function useSlotsActions() {
|
|
4379
|
-
const actions =
|
|
3010
|
+
const actions = React110.useContext(SlotsActionsContext);
|
|
4380
3011
|
if (!actions) {
|
|
4381
3012
|
throw new Error("useSlotsActions must be used within a SlotsProvider");
|
|
4382
3013
|
}
|