@almadar/ui 5.147.0 → 5.149.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/{GameAudioProvider-CPGwD49P.d.cts → GameAudioProvider-B48iXwz3.d.ts} +2 -50
- package/dist/{GameAudioProvider-CPGwD49P.d.ts → GameAudioProvider-CQAdPreB.d.cts} +2 -50
- package/dist/avl/index.cjs +535 -15
- package/dist/avl/index.js +535 -15
- package/dist/{avl-schema-parser-DVmrgdwc.d.cts → avl-schema-parser-CVzkNzg7.d.cts} +18 -9
- package/dist/{avl-schema-parser-BRJ77Yze.d.ts → avl-schema-parser-Cx_4SVg9.d.ts} +18 -9
- package/dist/{cn-BAn68sNO.d.cts → cn-BnAJZcNb.d.cts} +2 -8
- package/dist/{cn-CWxxLkri.d.ts → cn-DJTUjk1M.d.ts} +2 -8
- package/dist/components/index.cjs +545 -18
- package/dist/components/index.d.cts +278 -98
- package/dist/components/index.d.ts +278 -98
- package/dist/components/index.js +541 -20
- package/dist/lib/drawable/three/index.cjs +56 -29
- package/dist/lib/drawable/three/index.d.cts +4 -3
- package/dist/lib/drawable/three/index.d.ts +4 -3
- package/dist/lib/drawable/three/index.js +56 -29
- package/dist/lib/index.d.cts +3 -2
- package/dist/lib/index.d.ts +3 -2
- package/dist/{paintDispatch-Cb_hQj4Y.d.ts → paintDispatch-BjZjUbcb.d.cts} +63 -69
- package/dist/{paintDispatch-Cb_hQj4Y.d.cts → paintDispatch-CxdLjHQq.d.ts} +63 -69
- package/dist/providers/index.cjs +535 -15
- package/dist/providers/index.d.cts +2 -1
- package/dist/providers/index.d.ts +2 -1
- package/dist/providers/index.js +535 -15
- package/dist/runtime/index.cjs +535 -15
- package/dist/runtime/index.js +535 -15
- package/dist/types-B3nHgnMG.d.cts +51 -0
- package/dist/types-B3nHgnMG.d.ts +51 -0
- package/package.json +4 -4
|
@@ -8690,7 +8690,10 @@ var init_LearningCanvas = __esm({
|
|
|
8690
8690
|
ctx.fillRect(0, 0, width, height);
|
|
8691
8691
|
}
|
|
8692
8692
|
for (const shape of shapes) {
|
|
8693
|
-
drawShape(ctx, shape, width, height);
|
|
8693
|
+
if (shape.type !== "text") drawShape(ctx, shape, width, height);
|
|
8694
|
+
}
|
|
8695
|
+
for (const shape of shapes) {
|
|
8696
|
+
if (shape.type === "text") drawShape(ctx, shape, width, height);
|
|
8694
8697
|
}
|
|
8695
8698
|
}, [width, height, backgroundColor, shapes]);
|
|
8696
8699
|
React77.useEffect(() => {
|
|
@@ -8771,7 +8774,7 @@ var init_AlgorithmCanvas = __esm({
|
|
|
8771
8774
|
DEFAULT_CELL_COLOR = "#e5e7eb";
|
|
8772
8775
|
DEFAULT_POINTER_COLOR = "#dc2626";
|
|
8773
8776
|
POINTER_BAND = 34;
|
|
8774
|
-
TOP_PAD =
|
|
8777
|
+
TOP_PAD = 26;
|
|
8775
8778
|
exports.AlgorithmCanvas = ({
|
|
8776
8779
|
className,
|
|
8777
8780
|
width = 600,
|
|
@@ -9875,23 +9878,188 @@ var init_BehaviorView = __esm({
|
|
|
9875
9878
|
exports.BehaviorView.displayName = "BehaviorView";
|
|
9876
9879
|
}
|
|
9877
9880
|
});
|
|
9878
|
-
|
|
9881
|
+
function LearningScene3D({
|
|
9882
|
+
className,
|
|
9883
|
+
width = 600,
|
|
9884
|
+
height = 400,
|
|
9885
|
+
title,
|
|
9886
|
+
backgroundColor,
|
|
9887
|
+
drawables,
|
|
9888
|
+
camera,
|
|
9889
|
+
lighting,
|
|
9890
|
+
post,
|
|
9891
|
+
showGrid = false,
|
|
9892
|
+
shadows,
|
|
9893
|
+
interactive,
|
|
9894
|
+
isLoading,
|
|
9895
|
+
error,
|
|
9896
|
+
onItemClick
|
|
9897
|
+
}) {
|
|
9898
|
+
const instanceId = React77.useId().replace(/[^a-zA-Z0-9]/g, "");
|
|
9899
|
+
const clickEvent = onItemClick ? `LEARNING_SCENE_3D.ITEM_CLICK.${instanceId}` : void 0;
|
|
9900
|
+
const onItemClickRef = React77.useRef(onItemClick);
|
|
9901
|
+
onItemClickRef.current = onItemClick;
|
|
9902
|
+
useEventListener(`UI:${clickEvent ?? "LEARNING_SCENE_3D.ITEM_CLICK.__disabled"}`, (event) => {
|
|
9903
|
+
const unitId = event.payload?.unitId;
|
|
9904
|
+
if (typeof unitId === "string") onItemClickRef.current?.(unitId);
|
|
9905
|
+
});
|
|
9906
|
+
const props3d = {
|
|
9907
|
+
drawables,
|
|
9908
|
+
isLoading,
|
|
9909
|
+
error: error ? error.message : null,
|
|
9910
|
+
cameraMode: camera?.mode ?? "perspective",
|
|
9911
|
+
...camera?.zoom !== void 0 ? { zoom: camera.zoom } : {},
|
|
9912
|
+
...camera?.fov !== void 0 ? { fov: camera.fov } : {},
|
|
9913
|
+
...camera?.azimuth !== void 0 ? { azimuth: camera.azimuth } : {},
|
|
9914
|
+
...camera?.elevation !== void 0 ? { elevation: camera.elevation } : {},
|
|
9915
|
+
...camera?.target !== void 0 ? { followTarget: camera.target } : {},
|
|
9916
|
+
backgroundColor,
|
|
9917
|
+
showGrid,
|
|
9918
|
+
...shadows !== void 0 ? { shadows } : {},
|
|
9919
|
+
...interactive !== void 0 ? { controlsEnabled: interactive } : {},
|
|
9920
|
+
lighting,
|
|
9921
|
+
post,
|
|
9922
|
+
...clickEvent !== void 0 ? { unitClickEvent: clickEvent } : {}
|
|
9923
|
+
};
|
|
9924
|
+
return /* @__PURE__ */ jsxRuntime.jsx(exports.Card, { className, children: /* @__PURE__ */ jsxRuntime.jsxs(exports.VStack, { gap: "sm", children: [
|
|
9925
|
+
title ? /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "h4", children: title }) : null,
|
|
9926
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: { width, height, display: "flex" }, children: /* @__PURE__ */ jsxRuntime.jsx(React77.Suspense, { fallback: null, children: /* @__PURE__ */ jsxRuntime.jsx(Canvas3DHost, { ...props3d }) }) })
|
|
9927
|
+
] }) });
|
|
9928
|
+
}
|
|
9929
|
+
function meshSphere(id, x, y, z, radius, color, opts) {
|
|
9930
|
+
return {
|
|
9931
|
+
type: "draw-mesh",
|
|
9932
|
+
...id !== void 0 ? { id } : {},
|
|
9933
|
+
shape: opts?.shape ?? "sphere",
|
|
9934
|
+
position: { x, y, z },
|
|
9935
|
+
radius,
|
|
9936
|
+
pivot: "center",
|
|
9937
|
+
segments: opts?.segments ?? 24,
|
|
9938
|
+
material: { color, ...opts?.material },
|
|
9939
|
+
...opts?.opacity !== void 0 ? { opacity: opts.opacity } : {}
|
|
9940
|
+
};
|
|
9941
|
+
}
|
|
9942
|
+
function axisRotation(from, to) {
|
|
9943
|
+
const wx = to[0] - from[0];
|
|
9944
|
+
const wy = to[2] - from[2];
|
|
9945
|
+
const wz = to[1] - from[1];
|
|
9946
|
+
const len = Math.sqrt(wx * wx + wy * wy + wz * wz);
|
|
9947
|
+
const tilt = Math.acos(Math.min(1, Math.max(-1, len > 0 ? wy / len : 1)));
|
|
9948
|
+
return [0, Math.atan2(wz, -wx), tilt];
|
|
9949
|
+
}
|
|
9950
|
+
function segmentLength(from, to) {
|
|
9951
|
+
const dx = to[0] - from[0];
|
|
9952
|
+
const dy = to[1] - from[1];
|
|
9953
|
+
const dz = to[2] - from[2];
|
|
9954
|
+
return Math.sqrt(dx * dx + dy * dy + dz * dz);
|
|
9955
|
+
}
|
|
9956
|
+
function cylinderBetween(from, to, radius, color) {
|
|
9957
|
+
const len = segmentLength(from, to);
|
|
9958
|
+
if (len < 1e-6) return null;
|
|
9959
|
+
return {
|
|
9960
|
+
type: "draw-mesh",
|
|
9961
|
+
shape: "cylinder",
|
|
9962
|
+
position: { x: (from[0] + to[0]) / 2, y: (from[1] + to[1]) / 2, z: (from[2] + to[2]) / 2 },
|
|
9963
|
+
radius,
|
|
9964
|
+
height: len,
|
|
9965
|
+
rotation: axisRotation(from, to),
|
|
9966
|
+
pivot: "center",
|
|
9967
|
+
segments: 12,
|
|
9968
|
+
material: { color }
|
|
9969
|
+
};
|
|
9970
|
+
}
|
|
9971
|
+
function arrowBetween(from, to, color, shaftRadius = 0.08) {
|
|
9972
|
+
const len = segmentLength(from, to);
|
|
9973
|
+
if (len < 1e-6) return null;
|
|
9974
|
+
const tipLen = Math.min(shaftRadius * 8, len * 0.35);
|
|
9975
|
+
const k = (len - tipLen) / len;
|
|
9976
|
+
const delta = [to[0] - from[0], to[1] - from[1], to[2] - from[2]];
|
|
9977
|
+
const shaftEnd = [delta[0] * k, delta[1] * k, delta[2] * k];
|
|
9978
|
+
const tipStart = shaftEnd;
|
|
9979
|
+
const tipEnd = delta;
|
|
9980
|
+
const shaft = cylinderBetween([0, 0, 0], shaftEnd, shaftRadius, color);
|
|
9981
|
+
const tipLenActual = segmentLength(tipStart, tipEnd);
|
|
9982
|
+
const tip = {
|
|
9983
|
+
type: "draw-mesh",
|
|
9984
|
+
shape: "cone",
|
|
9985
|
+
position: {
|
|
9986
|
+
x: (tipStart[0] + tipEnd[0]) / 2,
|
|
9987
|
+
y: (tipStart[1] + tipEnd[1]) / 2,
|
|
9988
|
+
z: (tipStart[2] + tipEnd[2]) / 2
|
|
9989
|
+
},
|
|
9990
|
+
radius: shaftRadius * 3,
|
|
9991
|
+
height: tipLenActual,
|
|
9992
|
+
rotation: axisRotation(tipStart, tipEnd),
|
|
9993
|
+
pivot: "center",
|
|
9994
|
+
segments: 12,
|
|
9995
|
+
material: { color }
|
|
9996
|
+
};
|
|
9997
|
+
return {
|
|
9998
|
+
type: "draw-group",
|
|
9999
|
+
position: { x: from[0], y: from[1], z: from[2] },
|
|
10000
|
+
items: tipLenActual < 1e-6 ? shaft ? [shaft] : [] : shaft ? [shaft, tip] : [tip]
|
|
10001
|
+
};
|
|
10002
|
+
}
|
|
10003
|
+
function billboardLabel(text, x, y, z, opts) {
|
|
10004
|
+
return {
|
|
10005
|
+
type: "draw-text",
|
|
10006
|
+
text,
|
|
10007
|
+
position: { x, y, z },
|
|
10008
|
+
color: opts?.color ?? "#111827"
|
|
10009
|
+
};
|
|
10010
|
+
}
|
|
10011
|
+
function labelColorForBackground(backgroundColor) {
|
|
10012
|
+
const m = /^#(?:([0-9a-f]{3})|([0-9a-f]{6}))$/i.exec(backgroundColor ?? "");
|
|
10013
|
+
if (!m) return "#111827";
|
|
10014
|
+
const hex = m[1] !== void 0 ? m[1].split("").map((c) => c + c).join("") : m[2];
|
|
10015
|
+
const r = parseInt(hex.slice(0, 2), 16) / 255;
|
|
10016
|
+
const g = parseInt(hex.slice(2, 4), 16) / 255;
|
|
10017
|
+
const b = parseInt(hex.slice(4, 6), 16) / 255;
|
|
10018
|
+
const luminance = 0.2126 * r + 0.7152 * g + 0.0722 * b;
|
|
10019
|
+
return luminance < 0.5 ? "#e5e7eb" : "#111827";
|
|
10020
|
+
}
|
|
10021
|
+
function get3DClickPayload(onShapeClick, idToIndex) {
|
|
10022
|
+
if (!onShapeClick) return void 0;
|
|
10023
|
+
return (id) => onShapeClick({ id, index: idToIndex.get(id) ?? -1 });
|
|
10024
|
+
}
|
|
10025
|
+
var Canvas3DHost;
|
|
10026
|
+
var init_learningScene3D = __esm({
|
|
10027
|
+
"components/learning/molecules/learningScene3D.tsx"() {
|
|
10028
|
+
"use client";
|
|
10029
|
+
init_atoms();
|
|
10030
|
+
init_Stack();
|
|
10031
|
+
init_useEventBus();
|
|
10032
|
+
Canvas3DHost = React77.lazy(
|
|
10033
|
+
() => import('@almadar/ui/components/molecules/game/three').then((m) => ({ default: m.Canvas3DHost }))
|
|
10034
|
+
);
|
|
10035
|
+
LearningScene3D.displayName = "LearningScene3D";
|
|
10036
|
+
}
|
|
10037
|
+
});
|
|
10038
|
+
var biologyLog; exports.BiologyCanvas = void 0;
|
|
9879
10039
|
var init_BiologyCanvas = __esm({
|
|
9880
10040
|
"components/learning/molecules/BiologyCanvas.tsx"() {
|
|
9881
10041
|
"use client";
|
|
9882
10042
|
init_atoms();
|
|
9883
10043
|
init_Stack();
|
|
9884
10044
|
init_LearningCanvas();
|
|
10045
|
+
init_learningScene3D();
|
|
10046
|
+
biologyLog = logger.createLogger("almadar:ui:biology-canvas");
|
|
9885
10047
|
exports.BiologyCanvas = ({
|
|
9886
10048
|
className,
|
|
9887
10049
|
width = 600,
|
|
9888
10050
|
height = 400,
|
|
9889
10051
|
title,
|
|
9890
10052
|
backgroundColor,
|
|
10053
|
+
mode = "2d",
|
|
10054
|
+
camera,
|
|
10055
|
+
lighting,
|
|
10056
|
+
post,
|
|
9891
10057
|
nodes = [],
|
|
9892
10058
|
edges = [],
|
|
9893
10059
|
shapes = [],
|
|
9894
|
-
|
|
10060
|
+
showGrid,
|
|
10061
|
+
shadows,
|
|
10062
|
+
interactive,
|
|
9895
10063
|
animate = false,
|
|
9896
10064
|
onShapeClick,
|
|
9897
10065
|
isLoading,
|
|
@@ -9952,6 +10120,75 @@ var init_BiologyCanvas = __esm({
|
|
|
9952
10120
|
out.push(...shapes);
|
|
9953
10121
|
return out;
|
|
9954
10122
|
}, [nodes, edges, shapes]);
|
|
10123
|
+
const drawables3D = React77.useMemo(() => {
|
|
10124
|
+
if (mode !== "3d") return [];
|
|
10125
|
+
if (shapes.length > 0) {
|
|
10126
|
+
biologyLog.debug("shapes ignored in 3D mode (pixel-authored 2D vocabulary)", { count: shapes.length });
|
|
10127
|
+
}
|
|
10128
|
+
const out = [];
|
|
10129
|
+
const labelColor = labelColorForBackground(backgroundColor);
|
|
10130
|
+
const nodeById = /* @__PURE__ */ new Map();
|
|
10131
|
+
for (const n of nodes) {
|
|
10132
|
+
if (n.id) nodeById.set(n.id, n);
|
|
10133
|
+
}
|
|
10134
|
+
for (const e of edges) {
|
|
10135
|
+
const a = nodeById.get(e.from);
|
|
10136
|
+
const b = nodeById.get(e.to);
|
|
10137
|
+
if (!a || !b) continue;
|
|
10138
|
+
const edgeRadius = Math.max(0.04, Math.min(a.radius ?? 0.5, b.radius ?? 0.5) * 0.12);
|
|
10139
|
+
const edge = cylinderBetween([a.x, a.y, a.z ?? 0], [b.x, b.y, b.z ?? 0], edgeRadius, e.color ?? "#9ca3af");
|
|
10140
|
+
if (edge) out.push(edge);
|
|
10141
|
+
if (e.label) {
|
|
10142
|
+
out.push(
|
|
10143
|
+
billboardLabel(
|
|
10144
|
+
e.label,
|
|
10145
|
+
(a.x + b.x) / 2,
|
|
10146
|
+
(a.y + b.y) / 2,
|
|
10147
|
+
((a.z ?? 0) + (b.z ?? 0)) / 2,
|
|
10148
|
+
{ color: labelColor }
|
|
10149
|
+
)
|
|
10150
|
+
);
|
|
10151
|
+
}
|
|
10152
|
+
}
|
|
10153
|
+
for (const n of nodes) {
|
|
10154
|
+
const radius = n.radius ?? 0.5;
|
|
10155
|
+
const nz = n.z ?? 0;
|
|
10156
|
+
out.push(meshSphere(n.id, n.x, n.y, nz, radius, n.color ?? "#16a34a", { shape: n.shape, ...n.opacity !== void 0 ? { opacity: n.opacity } : {} }));
|
|
10157
|
+
if (n.label) {
|
|
10158
|
+
out.push(billboardLabel(n.label, n.x, n.y, nz + radius, { color: labelColor }));
|
|
10159
|
+
}
|
|
10160
|
+
}
|
|
10161
|
+
return out;
|
|
10162
|
+
}, [mode, nodes, edges, shapes, backgroundColor]);
|
|
10163
|
+
const nodeIndexById = React77.useMemo(() => {
|
|
10164
|
+
const m = /* @__PURE__ */ new Map();
|
|
10165
|
+
nodes.forEach((n, i) => {
|
|
10166
|
+
if (n.id) m.set(n.id, i);
|
|
10167
|
+
});
|
|
10168
|
+
return m;
|
|
10169
|
+
}, [nodes]);
|
|
10170
|
+
if (mode === "3d") {
|
|
10171
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
10172
|
+
LearningScene3D,
|
|
10173
|
+
{
|
|
10174
|
+
className,
|
|
10175
|
+
width,
|
|
10176
|
+
height,
|
|
10177
|
+
title,
|
|
10178
|
+
backgroundColor,
|
|
10179
|
+
drawables: drawables3D,
|
|
10180
|
+
camera,
|
|
10181
|
+
lighting,
|
|
10182
|
+
post,
|
|
10183
|
+
showGrid,
|
|
10184
|
+
shadows,
|
|
10185
|
+
interactive,
|
|
10186
|
+
isLoading,
|
|
10187
|
+
error,
|
|
10188
|
+
onItemClick: get3DClickPayload(onShapeClick, nodeIndexById)
|
|
10189
|
+
}
|
|
10190
|
+
);
|
|
10191
|
+
}
|
|
9955
10192
|
return /* @__PURE__ */ jsxRuntime.jsx(exports.Card, { className, children: /* @__PURE__ */ jsxRuntime.jsxs(exports.VStack, { gap: "sm", children: [
|
|
9956
10193
|
title ? /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "h4", children: title }) : null,
|
|
9957
10194
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -9961,7 +10198,7 @@ var init_BiologyCanvas = __esm({
|
|
|
9961
10198
|
height,
|
|
9962
10199
|
backgroundColor,
|
|
9963
10200
|
shapes: derivedShapes,
|
|
9964
|
-
interactive,
|
|
10201
|
+
interactive: interactive ?? false,
|
|
9965
10202
|
animate,
|
|
9966
10203
|
onShapeClick,
|
|
9967
10204
|
isLoading,
|
|
@@ -17353,9 +17590,10 @@ function Canvas({
|
|
|
17353
17590
|
drawables: [...drawables ?? [], ...childDrawables],
|
|
17354
17591
|
isLoading,
|
|
17355
17592
|
cameraMode: to3DCameraMode(camera?.mode),
|
|
17356
|
-
...zoom !== void 0 ? {
|
|
17593
|
+
...zoom !== void 0 ? { zoom } : {},
|
|
17357
17594
|
...camera?.fov !== void 0 ? { fov: camera.fov } : {},
|
|
17358
17595
|
...camera?.azimuth !== void 0 ? { azimuth: camera.azimuth } : {},
|
|
17596
|
+
...camera?.elevation !== void 0 ? { elevation: camera.elevation } : {},
|
|
17359
17597
|
...camera?.target !== void 0 ? { followTarget: camera.target } : {},
|
|
17360
17598
|
unitScale,
|
|
17361
17599
|
backgroundColor,
|
|
@@ -17378,7 +17616,7 @@ function Canvas({
|
|
|
17378
17616
|
keyUpMap
|
|
17379
17617
|
};
|
|
17380
17618
|
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
17381
|
-
/* @__PURE__ */ jsxRuntime.jsx(React77.Suspense, { fallback: null, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
17619
|
+
/* @__PURE__ */ jsxRuntime.jsx(React77.Suspense, { fallback: null, children: /* @__PURE__ */ jsxRuntime.jsx(Canvas3DHost2, { ...props3d }) }),
|
|
17382
17620
|
React77__namespace.Children.count(children) > 0 && /* @__PURE__ */ jsxRuntime.jsx(DrawableRegistryContext.Provider, { value: registerChildDrawable, children: /* @__PURE__ */ jsxRuntime.jsx("div", { "aria-hidden": "true", style: { position: "absolute", width: 0, height: 0, overflow: "hidden" }, children }) })
|
|
17383
17621
|
] });
|
|
17384
17622
|
}
|
|
@@ -17408,13 +17646,13 @@ function Canvas({
|
|
|
17408
17646
|
}
|
|
17409
17647
|
);
|
|
17410
17648
|
}
|
|
17411
|
-
var
|
|
17649
|
+
var Canvas3DHost2, canvasLog;
|
|
17412
17650
|
var init_Canvas = __esm({
|
|
17413
17651
|
"components/game/molecules/Canvas.tsx"() {
|
|
17414
17652
|
"use client";
|
|
17415
17653
|
init_registry();
|
|
17416
17654
|
init_Canvas2D();
|
|
17417
|
-
|
|
17655
|
+
Canvas3DHost2 = React77.lazy(
|
|
17418
17656
|
() => import('@almadar/ui/components/molecules/game/three').then((m) => ({ default: m.Canvas3DHost }))
|
|
17419
17657
|
);
|
|
17420
17658
|
canvasLog = logger.createLogger("almadar:ui:game-canvas");
|
|
@@ -19141,24 +19379,41 @@ var init_ChatBar = __esm({
|
|
|
19141
19379
|
ChatBar.displayName = "ChatBar";
|
|
19142
19380
|
}
|
|
19143
19381
|
});
|
|
19144
|
-
|
|
19382
|
+
function bondPerpendicular(a, b) {
|
|
19383
|
+
const dx = b[0] - a[0];
|
|
19384
|
+
const dy = b[1] - a[1];
|
|
19385
|
+
const px = dy;
|
|
19386
|
+
const py = -dx;
|
|
19387
|
+
const len = Math.sqrt(px * px + py * py);
|
|
19388
|
+
if (len < 1e-6) return [1, 0, 0];
|
|
19389
|
+
return [px / len, py / len, 0];
|
|
19390
|
+
}
|
|
19391
|
+
var chemistryLog; exports.ChemistryCanvas = void 0;
|
|
19145
19392
|
var init_ChemistryCanvas = __esm({
|
|
19146
19393
|
"components/learning/molecules/ChemistryCanvas.tsx"() {
|
|
19147
19394
|
"use client";
|
|
19148
19395
|
init_atoms();
|
|
19149
19396
|
init_Stack();
|
|
19150
19397
|
init_LearningCanvas();
|
|
19398
|
+
init_learningScene3D();
|
|
19399
|
+
chemistryLog = logger.createLogger("almadar:ui:chemistry-canvas");
|
|
19151
19400
|
exports.ChemistryCanvas = ({
|
|
19152
19401
|
className,
|
|
19153
19402
|
width = 600,
|
|
19154
19403
|
height = 400,
|
|
19155
19404
|
title,
|
|
19156
19405
|
backgroundColor,
|
|
19406
|
+
mode = "2d",
|
|
19407
|
+
camera,
|
|
19408
|
+
lighting,
|
|
19409
|
+
post,
|
|
19157
19410
|
atoms = [],
|
|
19158
19411
|
bonds = [],
|
|
19159
19412
|
arrows = [],
|
|
19160
19413
|
shapes = [],
|
|
19161
|
-
|
|
19414
|
+
showGrid,
|
|
19415
|
+
shadows,
|
|
19416
|
+
interactive,
|
|
19162
19417
|
animate = false,
|
|
19163
19418
|
onShapeClick,
|
|
19164
19419
|
isLoading,
|
|
@@ -19237,6 +19492,88 @@ var init_ChemistryCanvas = __esm({
|
|
|
19237
19492
|
out.push(...shapes);
|
|
19238
19493
|
return out;
|
|
19239
19494
|
}, [atoms, bonds, arrows, shapes]);
|
|
19495
|
+
const drawables3D = React77.useMemo(() => {
|
|
19496
|
+
if (mode !== "3d") return [];
|
|
19497
|
+
if (shapes.length > 0) {
|
|
19498
|
+
chemistryLog.debug("shapes ignored in 3D mode (pixel-authored 2D vocabulary)", { count: shapes.length });
|
|
19499
|
+
}
|
|
19500
|
+
const out = [];
|
|
19501
|
+
const labelColor = labelColorForBackground(backgroundColor);
|
|
19502
|
+
const atomById = /* @__PURE__ */ new Map();
|
|
19503
|
+
for (const a of atoms) {
|
|
19504
|
+
if (a.id) atomById.set(a.id, a);
|
|
19505
|
+
}
|
|
19506
|
+
for (const b of bonds) {
|
|
19507
|
+
const a = atomById.get(b.from);
|
|
19508
|
+
const c = atomById.get(b.to);
|
|
19509
|
+
if (!a || !c) continue;
|
|
19510
|
+
const color = b.color ?? "#6b7280";
|
|
19511
|
+
const from = [a.x, a.y, a.z ?? 0];
|
|
19512
|
+
const to = [c.x, c.y, c.z ?? 0];
|
|
19513
|
+
const perp = bondPerpendicular(from, to);
|
|
19514
|
+
const bondRadius = Math.max(0.06, Math.min(a.radius ?? 0.45, c.radius ?? 0.45) * 0.22);
|
|
19515
|
+
const step = bondRadius * 2.2;
|
|
19516
|
+
const offsets = b.type === "double" ? [-step, step] : b.type === "triple" ? [-step, 0, step] : [0];
|
|
19517
|
+
for (const off of offsets) {
|
|
19518
|
+
const bond = cylinderBetween(
|
|
19519
|
+
[from[0] + perp[0] * off, from[1] + perp[1] * off, from[2] + perp[2] * off],
|
|
19520
|
+
[to[0] + perp[0] * off, to[1] + perp[1] * off, to[2] + perp[2] * off],
|
|
19521
|
+
bondRadius,
|
|
19522
|
+
color
|
|
19523
|
+
);
|
|
19524
|
+
if (bond) out.push(bond);
|
|
19525
|
+
}
|
|
19526
|
+
}
|
|
19527
|
+
for (const a of arrows) {
|
|
19528
|
+
const angle = (a.angle ?? 0) * (Math.PI / 180);
|
|
19529
|
+
const len = a.length ?? 60;
|
|
19530
|
+
const x2 = a.x + Math.cos(angle) * len;
|
|
19531
|
+
const y2 = a.y + Math.sin(angle) * len;
|
|
19532
|
+
const arrow = arrowBetween([a.x, a.y, 0], [x2, y2, 0], a.color ?? "#dc2626");
|
|
19533
|
+
if (arrow) out.push(arrow);
|
|
19534
|
+
if (a.label) {
|
|
19535
|
+
out.push(billboardLabel(a.label, (a.x + x2) / 2, (a.y + y2) / 2, 0, { color: labelColor }));
|
|
19536
|
+
}
|
|
19537
|
+
}
|
|
19538
|
+
for (const a of atoms) {
|
|
19539
|
+
const radius = a.radius ?? 0.45;
|
|
19540
|
+
const az = a.z ?? 0;
|
|
19541
|
+
out.push(meshSphere(a.id, a.x, a.y, az, radius, a.color ?? "#2563eb"));
|
|
19542
|
+
if (a.element) {
|
|
19543
|
+
out.push(billboardLabel(a.element, a.x, a.y, az + radius, { color: labelColor }));
|
|
19544
|
+
}
|
|
19545
|
+
}
|
|
19546
|
+
return out;
|
|
19547
|
+
}, [mode, atoms, bonds, arrows, shapes, backgroundColor]);
|
|
19548
|
+
const atomIndexById = React77.useMemo(() => {
|
|
19549
|
+
const m = /* @__PURE__ */ new Map();
|
|
19550
|
+
atoms.forEach((a, i) => {
|
|
19551
|
+
if (a.id) m.set(a.id, i);
|
|
19552
|
+
});
|
|
19553
|
+
return m;
|
|
19554
|
+
}, [atoms]);
|
|
19555
|
+
if (mode === "3d") {
|
|
19556
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
19557
|
+
LearningScene3D,
|
|
19558
|
+
{
|
|
19559
|
+
className,
|
|
19560
|
+
width,
|
|
19561
|
+
height,
|
|
19562
|
+
title,
|
|
19563
|
+
backgroundColor,
|
|
19564
|
+
drawables: drawables3D,
|
|
19565
|
+
camera,
|
|
19566
|
+
lighting,
|
|
19567
|
+
post,
|
|
19568
|
+
showGrid,
|
|
19569
|
+
shadows,
|
|
19570
|
+
interactive,
|
|
19571
|
+
isLoading,
|
|
19572
|
+
error,
|
|
19573
|
+
onItemClick: get3DClickPayload(onShapeClick, atomIndexById)
|
|
19574
|
+
}
|
|
19575
|
+
);
|
|
19576
|
+
}
|
|
19240
19577
|
return /* @__PURE__ */ jsxRuntime.jsx(exports.Card, { className, children: /* @__PURE__ */ jsxRuntime.jsxs(exports.VStack, { gap: "sm", children: [
|
|
19241
19578
|
title ? /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "h4", children: title }) : null,
|
|
19242
19579
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -19246,7 +19583,7 @@ var init_ChemistryCanvas = __esm({
|
|
|
19246
19583
|
height,
|
|
19247
19584
|
backgroundColor,
|
|
19248
19585
|
shapes: derivedShapes,
|
|
19249
|
-
interactive,
|
|
19586
|
+
interactive: interactive ?? false,
|
|
19250
19587
|
animate,
|
|
19251
19588
|
onShapeClick,
|
|
19252
19589
|
isLoading,
|
|
@@ -23756,6 +24093,7 @@ var init_FilterGroup = __esm({
|
|
|
23756
24093
|
init_Badge();
|
|
23757
24094
|
init_Stack();
|
|
23758
24095
|
init_Icon();
|
|
24096
|
+
init_RangeSlider();
|
|
23759
24097
|
init_useEventBus();
|
|
23760
24098
|
init_useQuerySingleton();
|
|
23761
24099
|
resolveFilterType = (filter) => filter.filterType ?? filter.type;
|
|
@@ -23950,6 +24288,35 @@ var init_FilterGroup = __esm({
|
|
|
23950
24288
|
onClear: () => handleFilterSelect(`${filter.field}_to`, null)
|
|
23951
24289
|
}
|
|
23952
24290
|
)
|
|
24291
|
+
] }) : resolveFilterType(filter) === "numberrange" || resolveFilterType(filter) === "number-range" ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2", children: [
|
|
24292
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
24293
|
+
exports.RangeSlider,
|
|
24294
|
+
{
|
|
24295
|
+
min: filter.min ?? 0,
|
|
24296
|
+
max: filter.max ?? 100,
|
|
24297
|
+
step: filter.step ?? 1,
|
|
24298
|
+
value: Number(
|
|
24299
|
+
selectedValues[`${filter.field}_min`] ?? filter.min ?? 0
|
|
24300
|
+
),
|
|
24301
|
+
onChange: (v) => handleFilterSelect(`${filter.field}_min`, String(v)),
|
|
24302
|
+
showTooltip: true,
|
|
24303
|
+
"aria-label": t("filterGroup.from")
|
|
24304
|
+
}
|
|
24305
|
+
),
|
|
24306
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
24307
|
+
exports.RangeSlider,
|
|
24308
|
+
{
|
|
24309
|
+
min: filter.min ?? 0,
|
|
24310
|
+
max: filter.max ?? 100,
|
|
24311
|
+
step: filter.step ?? 1,
|
|
24312
|
+
value: Number(
|
|
24313
|
+
selectedValues[`${filter.field}_max`] ?? filter.max ?? 100
|
|
24314
|
+
),
|
|
24315
|
+
onChange: (v) => handleFilterSelect(`${filter.field}_max`, String(v)),
|
|
24316
|
+
showTooltip: true,
|
|
24317
|
+
"aria-label": t("filterGroup.to")
|
|
24318
|
+
}
|
|
24319
|
+
)
|
|
23953
24320
|
] }) : resolveFilterType(filter) === "text" ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
23954
24321
|
exports.Input,
|
|
23955
24322
|
{
|
|
@@ -24032,6 +24399,36 @@ var init_FilterGroup = __esm({
|
|
|
24032
24399
|
className: "text-sm min-w-[100px]"
|
|
24033
24400
|
}
|
|
24034
24401
|
)
|
|
24402
|
+
] }) : resolveFilterType(filter) === "numberrange" || resolveFilterType(filter) === "number-range" ? /* @__PURE__ */ jsxRuntime.jsxs(exports.HStack, { gap: "xs", align: "center", children: [
|
|
24403
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
24404
|
+
exports.RangeSlider,
|
|
24405
|
+
{
|
|
24406
|
+
min: filter.min ?? 0,
|
|
24407
|
+
max: filter.max ?? 100,
|
|
24408
|
+
step: filter.step ?? 1,
|
|
24409
|
+
value: Number(
|
|
24410
|
+
selectedValues[`${filter.field}_min`] ?? filter.min ?? 0
|
|
24411
|
+
),
|
|
24412
|
+
onChange: (v) => handleFilterSelect(`${filter.field}_min`, String(v)),
|
|
24413
|
+
className: "min-w-[100px]",
|
|
24414
|
+
"aria-label": t("filterGroup.from")
|
|
24415
|
+
}
|
|
24416
|
+
),
|
|
24417
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: "-" }),
|
|
24418
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
24419
|
+
exports.RangeSlider,
|
|
24420
|
+
{
|
|
24421
|
+
min: filter.min ?? 0,
|
|
24422
|
+
max: filter.max ?? 100,
|
|
24423
|
+
step: filter.step ?? 1,
|
|
24424
|
+
value: Number(
|
|
24425
|
+
selectedValues[`${filter.field}_max`] ?? filter.max ?? 100
|
|
24426
|
+
),
|
|
24427
|
+
onChange: (v) => handleFilterSelect(`${filter.field}_max`, String(v)),
|
|
24428
|
+
className: "min-w-[100px]",
|
|
24429
|
+
"aria-label": t("filterGroup.to")
|
|
24430
|
+
}
|
|
24431
|
+
)
|
|
24035
24432
|
] }) : resolveFilterType(filter) === "text" ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
24036
24433
|
exports.Input,
|
|
24037
24434
|
{
|
|
@@ -24150,6 +24547,38 @@ var init_FilterGroup = __esm({
|
|
|
24150
24547
|
className: "min-w-[130px]"
|
|
24151
24548
|
}
|
|
24152
24549
|
)
|
|
24550
|
+
] }) : resolveFilterType(filter) === "numberrange" || resolveFilterType(filter) === "number-range" ? /* @__PURE__ */ jsxRuntime.jsxs(exports.HStack, { gap: "xs", align: "center", children: [
|
|
24551
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
24552
|
+
exports.RangeSlider,
|
|
24553
|
+
{
|
|
24554
|
+
min: filter.min ?? 0,
|
|
24555
|
+
max: filter.max ?? 100,
|
|
24556
|
+
step: filter.step ?? 1,
|
|
24557
|
+
value: Number(
|
|
24558
|
+
selectedValues[`${filter.field}_min`] ?? filter.min ?? 0
|
|
24559
|
+
),
|
|
24560
|
+
onChange: (v) => handleFilterSelect(`${filter.field}_min`, String(v)),
|
|
24561
|
+
showTooltip: true,
|
|
24562
|
+
className: "min-w-[130px]",
|
|
24563
|
+
"aria-label": t("filterGroup.from")
|
|
24564
|
+
}
|
|
24565
|
+
),
|
|
24566
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: "-" }),
|
|
24567
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
24568
|
+
exports.RangeSlider,
|
|
24569
|
+
{
|
|
24570
|
+
min: filter.min ?? 0,
|
|
24571
|
+
max: filter.max ?? 100,
|
|
24572
|
+
step: filter.step ?? 1,
|
|
24573
|
+
value: Number(
|
|
24574
|
+
selectedValues[`${filter.field}_max`] ?? filter.max ?? 100
|
|
24575
|
+
),
|
|
24576
|
+
onChange: (v) => handleFilterSelect(`${filter.field}_max`, String(v)),
|
|
24577
|
+
showTooltip: true,
|
|
24578
|
+
className: "min-w-[130px]",
|
|
24579
|
+
"aria-label": t("filterGroup.to")
|
|
24580
|
+
}
|
|
24581
|
+
)
|
|
24153
24582
|
] }) : resolveFilterType(filter) === "text" ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
24154
24583
|
exports.Input,
|
|
24155
24584
|
{
|
|
@@ -29182,19 +29611,25 @@ var init_MathCanvas = __esm({
|
|
|
29182
29611
|
};
|
|
29183
29612
|
}
|
|
29184
29613
|
});
|
|
29185
|
-
exports.PhysicsCanvas = void 0;
|
|
29614
|
+
var physicsLog2; exports.PhysicsCanvas = void 0;
|
|
29186
29615
|
var init_PhysicsCanvas = __esm({
|
|
29187
29616
|
"components/learning/molecules/PhysicsCanvas.tsx"() {
|
|
29188
29617
|
"use client";
|
|
29189
29618
|
init_atoms();
|
|
29190
29619
|
init_Stack();
|
|
29191
29620
|
init_LearningCanvas();
|
|
29621
|
+
init_learningScene3D();
|
|
29622
|
+
physicsLog2 = logger.createLogger("almadar:ui:physics-canvas");
|
|
29192
29623
|
exports.PhysicsCanvas = ({
|
|
29193
29624
|
className,
|
|
29194
29625
|
width = 600,
|
|
29195
29626
|
height = 400,
|
|
29196
29627
|
title,
|
|
29197
29628
|
backgroundColor,
|
|
29629
|
+
mode = "2d",
|
|
29630
|
+
camera,
|
|
29631
|
+
lighting,
|
|
29632
|
+
post,
|
|
29198
29633
|
bodies = [],
|
|
29199
29634
|
constraints = [],
|
|
29200
29635
|
showVelocity = true,
|
|
@@ -29202,7 +29637,9 @@ var init_PhysicsCanvas = __esm({
|
|
|
29202
29637
|
velocityScale = 20,
|
|
29203
29638
|
forceScale = 20,
|
|
29204
29639
|
shapes = [],
|
|
29205
|
-
|
|
29640
|
+
showGrid,
|
|
29641
|
+
shadows,
|
|
29642
|
+
interactive,
|
|
29206
29643
|
animate = false,
|
|
29207
29644
|
onShapeClick,
|
|
29208
29645
|
isLoading,
|
|
@@ -29274,6 +29711,89 @@ var init_PhysicsCanvas = __esm({
|
|
|
29274
29711
|
out.push(...shapes);
|
|
29275
29712
|
return out;
|
|
29276
29713
|
}, [bodies, constraints, showVelocity, showForces, velocityScale, forceScale, shapes]);
|
|
29714
|
+
const drawables3D = React77.useMemo(() => {
|
|
29715
|
+
if (mode !== "3d") return [];
|
|
29716
|
+
if (shapes.length > 0) {
|
|
29717
|
+
physicsLog2.debug("shapes ignored in 3D mode (pixel-authored 2D vocabulary)", { count: shapes.length });
|
|
29718
|
+
}
|
|
29719
|
+
const out = [];
|
|
29720
|
+
const labelColor = labelColorForBackground(backgroundColor);
|
|
29721
|
+
const bodyById = /* @__PURE__ */ new Map();
|
|
29722
|
+
for (const b of bodies) {
|
|
29723
|
+
if (b.id) bodyById.set(b.id, b);
|
|
29724
|
+
}
|
|
29725
|
+
for (const c of constraints) {
|
|
29726
|
+
const a = bodyById.get(c.from);
|
|
29727
|
+
const b = bodyById.get(c.to);
|
|
29728
|
+
if (!a || !b) continue;
|
|
29729
|
+
const rodRadius = Math.max(0.05, Math.min(a.radius ?? 0.5, b.radius ?? 0.5) * 0.15);
|
|
29730
|
+
const rod = cylinderBetween([a.x, a.y, a.z ?? 0], [b.x, b.y, b.z ?? 0], rodRadius, c.color ?? "#9ca3af");
|
|
29731
|
+
if (rod) out.push(rod);
|
|
29732
|
+
}
|
|
29733
|
+
for (const b of bodies) {
|
|
29734
|
+
const radius = b.radius ?? 0.5;
|
|
29735
|
+
const bz = b.z ?? 0;
|
|
29736
|
+
out.push(meshSphere(b.id, b.x, b.y, bz, radius, b.color ?? "#2563eb"));
|
|
29737
|
+
if (b.label) {
|
|
29738
|
+
out.push(billboardLabel(b.label, b.x, b.y, bz + radius, { color: labelColor }));
|
|
29739
|
+
}
|
|
29740
|
+
const vx = b.vx ?? 0;
|
|
29741
|
+
const vy = b.vy ?? 0;
|
|
29742
|
+
const vz = b.vz ?? 0;
|
|
29743
|
+
const arrowRadius = Math.max(0.05, radius * 0.15);
|
|
29744
|
+
if (showVelocity && (vx !== 0 || vy !== 0 || vz !== 0)) {
|
|
29745
|
+
const arrow = arrowBetween(
|
|
29746
|
+
[b.x, b.y, bz],
|
|
29747
|
+
[b.x + vx * velocityScale, b.y + vy * velocityScale, bz + vz * velocityScale],
|
|
29748
|
+
"#16a34a",
|
|
29749
|
+
arrowRadius
|
|
29750
|
+
);
|
|
29751
|
+
if (arrow) out.push(arrow);
|
|
29752
|
+
}
|
|
29753
|
+
const fx = b.fx ?? 0;
|
|
29754
|
+
const fy = b.fy ?? 0;
|
|
29755
|
+
const fz = b.fz ?? 0;
|
|
29756
|
+
if (showForces && (fx !== 0 || fy !== 0 || fz !== 0)) {
|
|
29757
|
+
const arrow = arrowBetween(
|
|
29758
|
+
[b.x, b.y, bz],
|
|
29759
|
+
[b.x + fx * forceScale, b.y + fy * forceScale, bz + fz * forceScale],
|
|
29760
|
+
"#dc2626",
|
|
29761
|
+
arrowRadius
|
|
29762
|
+
);
|
|
29763
|
+
if (arrow) out.push(arrow);
|
|
29764
|
+
}
|
|
29765
|
+
}
|
|
29766
|
+
return out;
|
|
29767
|
+
}, [mode, bodies, constraints, showVelocity, showForces, velocityScale, forceScale, shapes, backgroundColor]);
|
|
29768
|
+
const bodyIndexById = React77.useMemo(() => {
|
|
29769
|
+
const m = /* @__PURE__ */ new Map();
|
|
29770
|
+
bodies.forEach((b, i) => {
|
|
29771
|
+
if (b.id) m.set(b.id, i);
|
|
29772
|
+
});
|
|
29773
|
+
return m;
|
|
29774
|
+
}, [bodies]);
|
|
29775
|
+
if (mode === "3d") {
|
|
29776
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
29777
|
+
LearningScene3D,
|
|
29778
|
+
{
|
|
29779
|
+
className,
|
|
29780
|
+
width,
|
|
29781
|
+
height,
|
|
29782
|
+
title,
|
|
29783
|
+
backgroundColor,
|
|
29784
|
+
drawables: drawables3D,
|
|
29785
|
+
camera,
|
|
29786
|
+
lighting,
|
|
29787
|
+
post,
|
|
29788
|
+
showGrid,
|
|
29789
|
+
shadows,
|
|
29790
|
+
interactive,
|
|
29791
|
+
isLoading,
|
|
29792
|
+
error,
|
|
29793
|
+
onItemClick: get3DClickPayload(onShapeClick, bodyIndexById)
|
|
29794
|
+
}
|
|
29795
|
+
);
|
|
29796
|
+
}
|
|
29277
29797
|
return /* @__PURE__ */ jsxRuntime.jsx(exports.Card, { className, children: /* @__PURE__ */ jsxRuntime.jsxs(exports.VStack, { gap: "sm", children: [
|
|
29278
29798
|
title ? /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "h4", children: title }) : null,
|
|
29279
29799
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -29283,7 +29803,7 @@ var init_PhysicsCanvas = __esm({
|
|
|
29283
29803
|
height,
|
|
29284
29804
|
backgroundColor,
|
|
29285
29805
|
shapes: derivedShapes,
|
|
29286
|
-
interactive,
|
|
29806
|
+
interactive: interactive ?? false,
|
|
29287
29807
|
animate,
|
|
29288
29808
|
onShapeClick,
|
|
29289
29809
|
isLoading,
|
|
@@ -29901,12 +30421,12 @@ var init_MapView = __esm({
|
|
|
29901
30421
|
shadowSize: [41, 41]
|
|
29902
30422
|
});
|
|
29903
30423
|
L.Marker.prototype.options.icon = defaultIcon;
|
|
29904
|
-
const { useEffect: useEffect66, useRef:
|
|
30424
|
+
const { useEffect: useEffect66, useRef: useRef65, useCallback: useCallback107, useState: useState104 } = React77__namespace.default;
|
|
29905
30425
|
const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
|
|
29906
30426
|
const { useEventBus: useEventBus2 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
|
|
29907
30427
|
function MapUpdater({ centerLat, centerLng, zoom }) {
|
|
29908
30428
|
const map = useMap();
|
|
29909
|
-
const prevRef =
|
|
30429
|
+
const prevRef = useRef65({ centerLat, centerLng, zoom });
|
|
29910
30430
|
useEffect66(() => {
|
|
29911
30431
|
const prev = prevRef.current;
|
|
29912
30432
|
if (prev.centerLat !== centerLat || prev.centerLng !== centerLng || prev.zoom !== zoom) {
|
|
@@ -39698,6 +40218,7 @@ var init_molecules2 = __esm({
|
|
|
39698
40218
|
init_BiologyCanvas();
|
|
39699
40219
|
init_ChemistryCanvas();
|
|
39700
40220
|
init_AlgorithmCanvas();
|
|
40221
|
+
init_learningScene3D();
|
|
39701
40222
|
init_GraphView();
|
|
39702
40223
|
init_MapView();
|
|
39703
40224
|
init_NumberStepper();
|
|
@@ -40951,7 +41472,7 @@ function getEnumOptions(field) {
|
|
|
40951
41472
|
}));
|
|
40952
41473
|
}
|
|
40953
41474
|
const validation = field.validation;
|
|
40954
|
-
if (validation?.enum &&
|
|
41475
|
+
if (validation?.enum && validation.enum.length > 0) {
|
|
40955
41476
|
return validation.enum.map((v) => ({
|
|
40956
41477
|
value: v,
|
|
40957
41478
|
label: v.charAt(0).toUpperCase() + v.slice(1).replace(/_/g, " ")
|
|
@@ -50406,6 +50927,7 @@ exports.GameIcon = GameIcon;
|
|
|
50406
50927
|
exports.GameMenu = GameMenu;
|
|
50407
50928
|
exports.HealthBar = HealthBar;
|
|
50408
50929
|
exports.I18nProvider = I18nProvider;
|
|
50930
|
+
exports.LearningScene3D = LearningScene3D;
|
|
50409
50931
|
exports.MapView = MapView;
|
|
50410
50932
|
exports.MasterDetail = MasterDetail;
|
|
50411
50933
|
exports.NotifyListener = NotifyListener;
|
|
@@ -50431,6 +50953,8 @@ exports.TraitStateViewer = TraitStateViewer;
|
|
|
50431
50953
|
exports.TransitionArrow = TransitionArrow;
|
|
50432
50954
|
exports.UISlotComponent = UISlotComponent;
|
|
50433
50955
|
exports.UISlotRenderer = UISlotRenderer;
|
|
50956
|
+
exports.arrowBetween = arrowBetween;
|
|
50957
|
+
exports.billboardLabel = billboardLabel;
|
|
50434
50958
|
exports.boardEntity = boardEntity;
|
|
50435
50959
|
exports.bool = bool;
|
|
50436
50960
|
exports.calculateAttackTargets = calculateAttackTargets;
|
|
@@ -50440,6 +50964,8 @@ exports.createInitialGameState = createInitialGameState;
|
|
|
50440
50964
|
exports.createSharedEntityStore = createSharedEntityStore;
|
|
50441
50965
|
exports.createTranslate = createTranslate;
|
|
50442
50966
|
exports.createUnitAnimationState = createUnitAnimationState;
|
|
50967
|
+
exports.cylinderBetween = cylinderBetween;
|
|
50968
|
+
exports.get3DClickPayload = get3DClickPayload;
|
|
50443
50969
|
exports.getCurrentFrame = getCurrentFrame;
|
|
50444
50970
|
exports.getTileDimensions = getTileDimensions;
|
|
50445
50971
|
exports.inferDirection = inferDirection;
|
|
@@ -50447,6 +50973,7 @@ exports.isoToScreen = isoToScreen;
|
|
|
50447
50973
|
exports.makeAsset = makeAsset;
|
|
50448
50974
|
exports.makeAssetMap = makeAssetMap;
|
|
50449
50975
|
exports.mapBookData = mapBookData;
|
|
50976
|
+
exports.meshSphere = meshSphere;
|
|
50450
50977
|
exports.num = num;
|
|
50451
50978
|
exports.objAvailableActions = objAvailableActions;
|
|
50452
50979
|
exports.objAvailableEvents = objAvailableEvents;
|