@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.
Files changed (29) hide show
  1. package/dist/{GameAudioProvider-CPGwD49P.d.cts → GameAudioProvider-B48iXwz3.d.ts} +2 -50
  2. package/dist/{GameAudioProvider-CPGwD49P.d.ts → GameAudioProvider-CQAdPreB.d.cts} +2 -50
  3. package/dist/avl/index.cjs +535 -15
  4. package/dist/avl/index.js +535 -15
  5. package/dist/{avl-schema-parser-DVmrgdwc.d.cts → avl-schema-parser-CVzkNzg7.d.cts} +18 -9
  6. package/dist/{avl-schema-parser-BRJ77Yze.d.ts → avl-schema-parser-Cx_4SVg9.d.ts} +18 -9
  7. package/dist/{cn-BAn68sNO.d.cts → cn-BnAJZcNb.d.cts} +2 -8
  8. package/dist/{cn-CWxxLkri.d.ts → cn-DJTUjk1M.d.ts} +2 -8
  9. package/dist/components/index.cjs +545 -18
  10. package/dist/components/index.d.cts +278 -98
  11. package/dist/components/index.d.ts +278 -98
  12. package/dist/components/index.js +541 -20
  13. package/dist/lib/drawable/three/index.cjs +56 -29
  14. package/dist/lib/drawable/three/index.d.cts +4 -3
  15. package/dist/lib/drawable/three/index.d.ts +4 -3
  16. package/dist/lib/drawable/three/index.js +56 -29
  17. package/dist/lib/index.d.cts +3 -2
  18. package/dist/lib/index.d.ts +3 -2
  19. package/dist/{paintDispatch-Cb_hQj4Y.d.ts → paintDispatch-BjZjUbcb.d.cts} +63 -69
  20. package/dist/{paintDispatch-Cb_hQj4Y.d.cts → paintDispatch-CxdLjHQq.d.ts} +63 -69
  21. package/dist/providers/index.cjs +535 -15
  22. package/dist/providers/index.d.cts +2 -1
  23. package/dist/providers/index.d.ts +2 -1
  24. package/dist/providers/index.js +535 -15
  25. package/dist/runtime/index.cjs +535 -15
  26. package/dist/runtime/index.js +535 -15
  27. package/dist/types-B3nHgnMG.d.cts +51 -0
  28. package/dist/types-B3nHgnMG.d.ts +51 -0
  29. package/package.json +4 -4
@@ -1556,27 +1556,30 @@ function Mesh3D({
1556
1556
  ] });
1557
1557
  }
1558
1558
  function Drawable3D({ node, projector, groupOpacity = 1 }) {
1559
- switch (node.type) {
1560
- case "draw-sprite":
1561
- return /* @__PURE__ */ jsxRuntime.jsx(Sprite3D, { node, projector, groupOpacity });
1562
- case "draw-shape":
1563
- return /* @__PURE__ */ jsxRuntime.jsx(Shape3D, { node, projector, groupOpacity });
1564
- case "draw-text":
1565
- return /* @__PURE__ */ jsxRuntime.jsx(Text3D, { node, projector, groupOpacity });
1566
- case "draw-mesh":
1567
- return /* @__PURE__ */ jsxRuntime.jsx(Mesh3D, { node, projector, groupOpacity });
1568
- case "draw-sprite-layer":
1569
- return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: node.items.map((item, i) => /* @__PURE__ */ jsxRuntime.jsx(Sprite3D, { node: item, projector, groupOpacity }, i)) });
1570
- case "draw-shape-layer":
1571
- return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: node.items.map((item, i) => /* @__PURE__ */ jsxRuntime.jsx(Shape3D, { node: item, projector, groupOpacity }, i)) });
1572
- case "draw-text-layer":
1573
- return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: node.items.map((item, i) => /* @__PURE__ */ jsxRuntime.jsx(Text3D, { node: item, projector, groupOpacity }, i)) });
1574
- case "draw-group": {
1575
- if (!isValidScenePos(node.position) || !Array.isArray(node.items)) return null;
1576
- if (node.clip) warnUnsupported3d("draw-group:clip");
1577
- return /* @__PURE__ */ jsxRuntime.jsx(Group3D, { node, projector, groupOpacity });
1559
+ const rendered = (() => {
1560
+ switch (node.type) {
1561
+ case "draw-sprite":
1562
+ return /* @__PURE__ */ jsxRuntime.jsx(Sprite3D, { node, projector, groupOpacity });
1563
+ case "draw-shape":
1564
+ return /* @__PURE__ */ jsxRuntime.jsx(Shape3D, { node, projector, groupOpacity });
1565
+ case "draw-text":
1566
+ return /* @__PURE__ */ jsxRuntime.jsx(Text3D, { node, projector, groupOpacity });
1567
+ case "draw-mesh":
1568
+ return /* @__PURE__ */ jsxRuntime.jsx(Mesh3D, { node, projector, groupOpacity });
1569
+ case "draw-sprite-layer":
1570
+ return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: node.items.map((item, i) => /* @__PURE__ */ jsxRuntime.jsx(Sprite3D, { node: item, projector, groupOpacity }, i)) });
1571
+ case "draw-shape-layer":
1572
+ return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: node.items.map((item, i) => /* @__PURE__ */ jsxRuntime.jsx(Shape3D, { node: item, projector, groupOpacity }, i)) });
1573
+ case "draw-text-layer":
1574
+ return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: node.items.map((item, i) => /* @__PURE__ */ jsxRuntime.jsx(Text3D, { node: item, projector, groupOpacity }, i)) });
1575
+ case "draw-group": {
1576
+ if (!isValidScenePos(node.position) || !Array.isArray(node.items)) return null;
1577
+ if (node.clip) warnUnsupported3d("draw-group:clip");
1578
+ return /* @__PURE__ */ jsxRuntime.jsx(Group3D, { node, projector, groupOpacity });
1579
+ }
1578
1580
  }
1579
- }
1581
+ })();
1582
+ return node.id ? /* @__PURE__ */ jsxRuntime.jsx("group", { userData: { drawableId: node.id }, children: rendered }) : rendered;
1580
1583
  }
1581
1584
  function Group3D({
1582
1585
  node,
@@ -1639,14 +1642,15 @@ function CameraPose({
1639
1642
  controls
1640
1643
  }) {
1641
1644
  const camera = fiber.useThree((s) => s.camera);
1645
+ const [px, py, pz] = position;
1642
1646
  React3.useEffect(() => {
1643
- camera.position.set(position[0], position[1], position[2]);
1647
+ camera.position.set(px, py, pz);
1644
1648
  if (camera.isPerspectiveCamera) {
1645
1649
  camera.fov = fov;
1646
1650
  camera.updateProjectionMatrix();
1647
1651
  }
1648
1652
  controls.current?.update();
1649
- }, [camera, position, fov, controls]);
1653
+ }, [camera, px, py, pz, fov, controls]);
1650
1654
  return null;
1651
1655
  }
1652
1656
  function RoomEnvironment3D() {
@@ -1689,6 +1693,9 @@ var Canvas3DHost = React3.forwardRef(
1689
1693
  pixelsPerUnit,
1690
1694
  fov,
1691
1695
  azimuth,
1696
+ elevation,
1697
+ zoom,
1698
+ controlsEnabled = true,
1692
1699
  lighting,
1693
1700
  post,
1694
1701
  children,
@@ -1820,7 +1827,7 @@ var Canvas3DHost = React3.forwardRef(
1820
1827
  );
1821
1828
  const cx = cameraTarget[0];
1822
1829
  const cz = cameraTarget[2];
1823
- const d = size * 1;
1830
+ const d = size * 1 / (zoom !== void 0 && zoom > 0 ? zoom : 1);
1824
1831
  const fovDeg = fov ?? 45;
1825
1832
  const base = (() => {
1826
1833
  switch (cameraMode) {
@@ -1833,8 +1840,11 @@ var Canvas3DHost = React3.forwardRef(
1833
1840
  case "follow":
1834
1841
  return { position: [cx, d * 0.5, cz + d], fov: fovDeg };
1835
1842
  case "perspective":
1836
- default:
1837
- return { position: [cx + d, d, cz + d], fov: fovDeg };
1843
+ default: {
1844
+ if (elevation === void 0) return { position: [cx + d, d, cz + d], fov: fovDeg };
1845
+ const el = Math.min(Math.max(elevation, 0), Math.PI / 2 - 0.1);
1846
+ return { position: [cx + d, d * Math.tan(el), cz + d], fov: fovDeg };
1847
+ }
1838
1848
  }
1839
1849
  })();
1840
1850
  if (!azimuth) return base;
@@ -1843,7 +1853,7 @@ var Canvas3DHost = React3.forwardRef(
1843
1853
  const c = Math.cos(azimuth);
1844
1854
  const s = Math.sin(azimuth);
1845
1855
  return { position: [cx + ox * c - oz * s, base.position[1], cz + ox * s + oz * c], fov: base.fov };
1846
- }, [cameraMode, gridBounds, cellSize, cameraTarget, fov, azimuth]);
1856
+ }, [cameraMode, gridBounds, cellSize, cameraTarget, fov, azimuth, elevation, zoom]);
1847
1857
  const followWorld = React3.useMemo(() => {
1848
1858
  if (followTarget) return drawableProjector.toWorld(followTarget);
1849
1859
  return cameraTarget;
@@ -1866,6 +1876,23 @@ var Canvas3DHost = React3.forwardRef(
1866
1876
  eventBus.emit(`UI:${tileClickEvent}`, { x: cell.x, z: cell.y });
1867
1877
  }
1868
1878
  }, [tileClickEvent, unitClickEvent, gridConfig, gridBounds, hitIndex, eventBus]);
1879
+ const handleDrawableClick = React3.useCallback((e) => {
1880
+ if (!unitClickEvent) return;
1881
+ let obj = e.object;
1882
+ while (obj) {
1883
+ const id = obj.userData.drawableId;
1884
+ if (id !== void 0) {
1885
+ e.stopPropagation();
1886
+ eventBus.emit(`UI:${unitClickEvent}`, {
1887
+ unitId: id,
1888
+ x: e.point.x / gridConfig.cellSize + gridBounds.minX,
1889
+ z: e.point.z / gridConfig.cellSize + gridBounds.minZ
1890
+ });
1891
+ return;
1892
+ }
1893
+ obj = obj.parent;
1894
+ }
1895
+ }, [unitClickEvent, gridConfig, gridBounds, eventBus]);
1869
1896
  if (externalLoading) {
1870
1897
  return /* @__PURE__ */ jsxRuntime.jsx(
1871
1898
  Canvas3DLoadingState,
@@ -1919,7 +1946,7 @@ var Canvas3DHost = React3.forwardRef(
1919
1946
  },
1920
1947
  children: [
1921
1948
  /* @__PURE__ */ jsxRuntime.jsx(CameraController3D, { onCameraChange: eventHandlers.handleCameraChange }),
1922
- /* @__PURE__ */ jsxRuntime.jsx(CameraPose, { position: cameraConfig.position, fov: cameraConfig.fov, controls: controlsRef }),
1949
+ cameraMode !== "follow" && cameraMode !== "chase" && /* @__PURE__ */ jsxRuntime.jsx(CameraPose, { position: cameraConfig.position, fov: cameraConfig.fov, controls: controlsRef }),
1923
1950
  (cameraMode === "follow" || cameraMode === "chase") && /* @__PURE__ */ jsxRuntime.jsx(FollowCamera3D, { target: followWorld, offset: followOffset }),
1924
1951
  /* @__PURE__ */ jsxRuntime.jsx(
1925
1952
  Lighting3D,
@@ -1964,7 +1991,7 @@ var Canvas3DHost = React3.forwardRef(
1964
1991
  fadeStrength: 1
1965
1992
  }
1966
1993
  ),
1967
- allDrawables.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(BoneRegistryContext.Provider, { value: boneStore, children: /* @__PURE__ */ jsxRuntime.jsx("group", { children: allDrawables.map((node, i) => /* @__PURE__ */ jsxRuntime.jsx(Drawable3D, { node, projector: drawableProjector }, i)) }) }),
1994
+ allDrawables.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(BoneRegistryContext.Provider, { value: boneStore, children: /* @__PURE__ */ jsxRuntime.jsx("group", { onClick: unitClickEvent ? handleDrawableClick : void 0, children: allDrawables.map((node, i) => /* @__PURE__ */ jsxRuntime.jsx(Drawable3D, { node, projector: drawableProjector }, i)) }) }),
1968
1995
  (tileClickEvent || unitClickEvent) && /* @__PURE__ */ jsxRuntime.jsxs(
1969
1996
  "mesh",
1970
1997
  {
@@ -1994,7 +2021,7 @@ var Canvas3DHost = React3.forwardRef(
1994
2021
  drei.OrbitControls,
1995
2022
  {
1996
2023
  ref: controlsRef,
1997
- enabled: cameraMode !== "follow" && cameraMode !== "chase",
2024
+ enabled: controlsEnabled && cameraMode !== "follow" && cameraMode !== "chase",
1998
2025
  target: cameraTarget,
1999
2026
  enableDamping: true,
2000
2027
  dampingFactor: 0.05,
@@ -1,12 +1,13 @@
1
- import { C as CanvasPointLightConfig, I as IsometricTile, a as IsometricUnit, b as IsometricFeature, A as ApplicationLevelData, O as OrbitalLevelData, T as TraitLevelData, c as TransitionLevelData } from '../../../avl-schema-parser-DVmrgdwc.cjs';
2
- export { d as Canvas3DHost, e as Canvas3DHostHandle, f as Canvas3DHostProps, d as GameCanvas3D, U as UnitAnimationState } from '../../../avl-schema-parser-DVmrgdwc.cjs';
1
+ import { C as CanvasPointLightConfig, I as IsometricTile, a as IsometricUnit, b as IsometricFeature, A as ApplicationLevelData, O as OrbitalLevelData, T as TraitLevelData, c as TransitionLevelData } from '../../../avl-schema-parser-CVzkNzg7.cjs';
2
+ export { d as Canvas3DHost, e as Canvas3DHostHandle, f as Canvas3DHostProps, d as GameCanvas3D, U as UnitAnimationState } from '../../../avl-schema-parser-CVzkNzg7.cjs';
3
3
  import * as React$1 from 'react';
4
4
  import React__default, { Component, ReactNode, ErrorInfo } from 'react';
5
5
  import * as THREE from 'three';
6
6
  import { QuadraticBezierCurve3 } from 'three';
7
7
  import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
8
8
  import { JsonObject, EventEmit, OrbitalSchema } from '@almadar/core';
9
- import '../../../paintDispatch-Cb_hQj4Y.cjs';
9
+ import '../../../paintDispatch-BjZjUbcb.cjs';
10
+ import '../../../types-B3nHgnMG.cjs';
10
11
 
11
12
  /**
12
13
  * Scene3D
@@ -1,12 +1,13 @@
1
- import { C as CanvasPointLightConfig, I as IsometricTile, a as IsometricUnit, b as IsometricFeature, A as ApplicationLevelData, O as OrbitalLevelData, T as TraitLevelData, c as TransitionLevelData } from '../../../avl-schema-parser-BRJ77Yze.js';
2
- export { d as Canvas3DHost, e as Canvas3DHostHandle, f as Canvas3DHostProps, d as GameCanvas3D, U as UnitAnimationState } from '../../../avl-schema-parser-BRJ77Yze.js';
1
+ import { C as CanvasPointLightConfig, I as IsometricTile, a as IsometricUnit, b as IsometricFeature, A as ApplicationLevelData, O as OrbitalLevelData, T as TraitLevelData, c as TransitionLevelData } from '../../../avl-schema-parser-Cx_4SVg9.js';
2
+ export { d as Canvas3DHost, e as Canvas3DHostHandle, f as Canvas3DHostProps, d as GameCanvas3D, U as UnitAnimationState } from '../../../avl-schema-parser-Cx_4SVg9.js';
3
3
  import * as React$1 from 'react';
4
4
  import React__default, { Component, ReactNode, ErrorInfo } from 'react';
5
5
  import * as THREE from 'three';
6
6
  import { QuadraticBezierCurve3 } from 'three';
7
7
  import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
8
8
  import { JsonObject, EventEmit, OrbitalSchema } from '@almadar/core';
9
- import '../../../paintDispatch-Cb_hQj4Y.js';
9
+ import '../../../paintDispatch-CxdLjHQq.js';
10
+ import '../../../types-B3nHgnMG.js';
10
11
 
11
12
  /**
12
13
  * Scene3D
@@ -1532,27 +1532,30 @@ function Mesh3D({
1532
1532
  ] });
1533
1533
  }
1534
1534
  function Drawable3D({ node, projector, groupOpacity = 1 }) {
1535
- switch (node.type) {
1536
- case "draw-sprite":
1537
- return /* @__PURE__ */ jsx(Sprite3D, { node, projector, groupOpacity });
1538
- case "draw-shape":
1539
- return /* @__PURE__ */ jsx(Shape3D, { node, projector, groupOpacity });
1540
- case "draw-text":
1541
- return /* @__PURE__ */ jsx(Text3D, { node, projector, groupOpacity });
1542
- case "draw-mesh":
1543
- return /* @__PURE__ */ jsx(Mesh3D, { node, projector, groupOpacity });
1544
- case "draw-sprite-layer":
1545
- return /* @__PURE__ */ jsx(Fragment, { children: node.items.map((item, i) => /* @__PURE__ */ jsx(Sprite3D, { node: item, projector, groupOpacity }, i)) });
1546
- case "draw-shape-layer":
1547
- return /* @__PURE__ */ jsx(Fragment, { children: node.items.map((item, i) => /* @__PURE__ */ jsx(Shape3D, { node: item, projector, groupOpacity }, i)) });
1548
- case "draw-text-layer":
1549
- return /* @__PURE__ */ jsx(Fragment, { children: node.items.map((item, i) => /* @__PURE__ */ jsx(Text3D, { node: item, projector, groupOpacity }, i)) });
1550
- case "draw-group": {
1551
- if (!isValidScenePos(node.position) || !Array.isArray(node.items)) return null;
1552
- if (node.clip) warnUnsupported3d("draw-group:clip");
1553
- return /* @__PURE__ */ jsx(Group3D, { node, projector, groupOpacity });
1535
+ const rendered = (() => {
1536
+ switch (node.type) {
1537
+ case "draw-sprite":
1538
+ return /* @__PURE__ */ jsx(Sprite3D, { node, projector, groupOpacity });
1539
+ case "draw-shape":
1540
+ return /* @__PURE__ */ jsx(Shape3D, { node, projector, groupOpacity });
1541
+ case "draw-text":
1542
+ return /* @__PURE__ */ jsx(Text3D, { node, projector, groupOpacity });
1543
+ case "draw-mesh":
1544
+ return /* @__PURE__ */ jsx(Mesh3D, { node, projector, groupOpacity });
1545
+ case "draw-sprite-layer":
1546
+ return /* @__PURE__ */ jsx(Fragment, { children: node.items.map((item, i) => /* @__PURE__ */ jsx(Sprite3D, { node: item, projector, groupOpacity }, i)) });
1547
+ case "draw-shape-layer":
1548
+ return /* @__PURE__ */ jsx(Fragment, { children: node.items.map((item, i) => /* @__PURE__ */ jsx(Shape3D, { node: item, projector, groupOpacity }, i)) });
1549
+ case "draw-text-layer":
1550
+ return /* @__PURE__ */ jsx(Fragment, { children: node.items.map((item, i) => /* @__PURE__ */ jsx(Text3D, { node: item, projector, groupOpacity }, i)) });
1551
+ case "draw-group": {
1552
+ if (!isValidScenePos(node.position) || !Array.isArray(node.items)) return null;
1553
+ if (node.clip) warnUnsupported3d("draw-group:clip");
1554
+ return /* @__PURE__ */ jsx(Group3D, { node, projector, groupOpacity });
1555
+ }
1554
1556
  }
1555
- }
1557
+ })();
1558
+ return node.id ? /* @__PURE__ */ jsx("group", { userData: { drawableId: node.id }, children: rendered }) : rendered;
1556
1559
  }
1557
1560
  function Group3D({
1558
1561
  node,
@@ -1615,14 +1618,15 @@ function CameraPose({
1615
1618
  controls
1616
1619
  }) {
1617
1620
  const camera = useThree((s) => s.camera);
1621
+ const [px, py, pz] = position;
1618
1622
  useEffect(() => {
1619
- camera.position.set(position[0], position[1], position[2]);
1623
+ camera.position.set(px, py, pz);
1620
1624
  if (camera.isPerspectiveCamera) {
1621
1625
  camera.fov = fov;
1622
1626
  camera.updateProjectionMatrix();
1623
1627
  }
1624
1628
  controls.current?.update();
1625
- }, [camera, position, fov, controls]);
1629
+ }, [camera, px, py, pz, fov, controls]);
1626
1630
  return null;
1627
1631
  }
1628
1632
  function RoomEnvironment3D() {
@@ -1665,6 +1669,9 @@ var Canvas3DHost = forwardRef(
1665
1669
  pixelsPerUnit,
1666
1670
  fov,
1667
1671
  azimuth,
1672
+ elevation,
1673
+ zoom,
1674
+ controlsEnabled = true,
1668
1675
  lighting,
1669
1676
  post,
1670
1677
  children,
@@ -1796,7 +1803,7 @@ var Canvas3DHost = forwardRef(
1796
1803
  );
1797
1804
  const cx = cameraTarget[0];
1798
1805
  const cz = cameraTarget[2];
1799
- const d = size * 1;
1806
+ const d = size * 1 / (zoom !== void 0 && zoom > 0 ? zoom : 1);
1800
1807
  const fovDeg = fov ?? 45;
1801
1808
  const base = (() => {
1802
1809
  switch (cameraMode) {
@@ -1809,8 +1816,11 @@ var Canvas3DHost = forwardRef(
1809
1816
  case "follow":
1810
1817
  return { position: [cx, d * 0.5, cz + d], fov: fovDeg };
1811
1818
  case "perspective":
1812
- default:
1813
- return { position: [cx + d, d, cz + d], fov: fovDeg };
1819
+ default: {
1820
+ if (elevation === void 0) return { position: [cx + d, d, cz + d], fov: fovDeg };
1821
+ const el = Math.min(Math.max(elevation, 0), Math.PI / 2 - 0.1);
1822
+ return { position: [cx + d, d * Math.tan(el), cz + d], fov: fovDeg };
1823
+ }
1814
1824
  }
1815
1825
  })();
1816
1826
  if (!azimuth) return base;
@@ -1819,7 +1829,7 @@ var Canvas3DHost = forwardRef(
1819
1829
  const c = Math.cos(azimuth);
1820
1830
  const s = Math.sin(azimuth);
1821
1831
  return { position: [cx + ox * c - oz * s, base.position[1], cz + ox * s + oz * c], fov: base.fov };
1822
- }, [cameraMode, gridBounds, cellSize, cameraTarget, fov, azimuth]);
1832
+ }, [cameraMode, gridBounds, cellSize, cameraTarget, fov, azimuth, elevation, zoom]);
1823
1833
  const followWorld = useMemo(() => {
1824
1834
  if (followTarget) return drawableProjector.toWorld(followTarget);
1825
1835
  return cameraTarget;
@@ -1842,6 +1852,23 @@ var Canvas3DHost = forwardRef(
1842
1852
  eventBus.emit(`UI:${tileClickEvent}`, { x: cell.x, z: cell.y });
1843
1853
  }
1844
1854
  }, [tileClickEvent, unitClickEvent, gridConfig, gridBounds, hitIndex, eventBus]);
1855
+ const handleDrawableClick = useCallback((e) => {
1856
+ if (!unitClickEvent) return;
1857
+ let obj = e.object;
1858
+ while (obj) {
1859
+ const id = obj.userData.drawableId;
1860
+ if (id !== void 0) {
1861
+ e.stopPropagation();
1862
+ eventBus.emit(`UI:${unitClickEvent}`, {
1863
+ unitId: id,
1864
+ x: e.point.x / gridConfig.cellSize + gridBounds.minX,
1865
+ z: e.point.z / gridConfig.cellSize + gridBounds.minZ
1866
+ });
1867
+ return;
1868
+ }
1869
+ obj = obj.parent;
1870
+ }
1871
+ }, [unitClickEvent, gridConfig, gridBounds, eventBus]);
1845
1872
  if (externalLoading) {
1846
1873
  return /* @__PURE__ */ jsx(
1847
1874
  Canvas3DLoadingState,
@@ -1895,7 +1922,7 @@ var Canvas3DHost = forwardRef(
1895
1922
  },
1896
1923
  children: [
1897
1924
  /* @__PURE__ */ jsx(CameraController3D, { onCameraChange: eventHandlers.handleCameraChange }),
1898
- /* @__PURE__ */ jsx(CameraPose, { position: cameraConfig.position, fov: cameraConfig.fov, controls: controlsRef }),
1925
+ cameraMode !== "follow" && cameraMode !== "chase" && /* @__PURE__ */ jsx(CameraPose, { position: cameraConfig.position, fov: cameraConfig.fov, controls: controlsRef }),
1899
1926
  (cameraMode === "follow" || cameraMode === "chase") && /* @__PURE__ */ jsx(FollowCamera3D, { target: followWorld, offset: followOffset }),
1900
1927
  /* @__PURE__ */ jsx(
1901
1928
  Lighting3D,
@@ -1940,7 +1967,7 @@ var Canvas3DHost = forwardRef(
1940
1967
  fadeStrength: 1
1941
1968
  }
1942
1969
  ),
1943
- allDrawables.length > 0 && /* @__PURE__ */ jsx(BoneRegistryContext.Provider, { value: boneStore, children: /* @__PURE__ */ jsx("group", { children: allDrawables.map((node, i) => /* @__PURE__ */ jsx(Drawable3D, { node, projector: drawableProjector }, i)) }) }),
1970
+ allDrawables.length > 0 && /* @__PURE__ */ jsx(BoneRegistryContext.Provider, { value: boneStore, children: /* @__PURE__ */ jsx("group", { onClick: unitClickEvent ? handleDrawableClick : void 0, children: allDrawables.map((node, i) => /* @__PURE__ */ jsx(Drawable3D, { node, projector: drawableProjector }, i)) }) }),
1944
1971
  (tileClickEvent || unitClickEvent) && /* @__PURE__ */ jsxs(
1945
1972
  "mesh",
1946
1973
  {
@@ -1970,7 +1997,7 @@ var Canvas3DHost = forwardRef(
1970
1997
  OrbitControls,
1971
1998
  {
1972
1999
  ref: controlsRef,
1973
- enabled: cameraMode !== "follow" && cameraMode !== "chase",
2000
+ enabled: controlsEnabled && cameraMode !== "follow" && cameraMode !== "chase",
1974
2001
  target: cameraTarget,
1975
2002
  enableDamping: true,
1976
2003
  dampingFactor: 0.05,
@@ -1,8 +1,9 @@
1
- export { C as ContentSegment, D as DEFAULT_CONFIG, a as DomEntityBox, b as DomLayoutData, c as DomOutputsBox, d as DomStateNode, e as DomTransitionLabel, f as DomTransitionPath, E as EntityDefinition, L as LessonSegment, R as RenderOptions, S as StateDefinition, g as StateMachineDefinition, T as TraitSnapshotGetter, h as TransitionDefinition, V as VisualizerConfig, i as bindCanvasCapture, j as bindEventBus, k as bindLastDrawables, l as bindTraitStateGetter, m as clearVerification, n as cn, o as extractOutputsFromTransitions, p as extractStateMachine, q as formatGuard, r as getAllChecks, s as getBridgeHealth, t as getEffectSummary, u as getSnapshot, v as getSummary, w as getTraitSnapshots, x as getTransitions, y as getTransitionsForTrait, z as parseContentSegments, A as parseLessonSegments, B as parseMarkdownWithCodeBlocks, F as recordServerResponse, G as recordTransition, H as registerCheck, I as registerTraitSnapshot, J as renderStateMachineToDomData, K as renderStateMachineToSvg, M as subscribeToVerification, N as updateAssetStatus, O as updateBridgeHealth, P as updateCheck, Q as waitForTransition } from '../cn-BAn68sNO.cjs';
1
+ export { C as ContentSegment, D as DEFAULT_CONFIG, a as DomEntityBox, b as DomLayoutData, c as DomOutputsBox, d as DomStateNode, e as DomTransitionLabel, f as DomTransitionPath, E as EntityDefinition, L as LessonSegment, R as RenderOptions, S as StateDefinition, g as StateMachineDefinition, T as TraitSnapshotGetter, h as TransitionDefinition, V as VisualizerConfig, i as bindCanvasCapture, j as bindEventBus, k as bindLastDrawables, l as bindTraitStateGetter, m as clearVerification, n as cn, o as extractOutputsFromTransitions, p as extractStateMachine, q as formatGuard, r as getAllChecks, s as getBridgeHealth, t as getEffectSummary, u as getSnapshot, v as getSummary, w as getTraitSnapshots, x as getTransitions, y as getTransitionsForTrait, z as parseContentSegments, A as parseLessonSegments, B as parseMarkdownWithCodeBlocks, F as recordServerResponse, G as recordTransition, H as registerCheck, I as registerTraitSnapshot, J as renderStateMachineToDomData, K as renderStateMachineToSvg, M as subscribeToVerification, N as updateAssetStatus, O as updateBridgeHealth, P as updateCheck, Q as waitForTransition } from '../cn-BnAJZcNb.cjs';
2
2
  import { FieldValue, EntityRow, EventPayload } from '@almadar/core';
3
3
  export { AssetLoadStatus, BridgeHealth, CheckStatus, EffectTrace, EventLogEntry, OrbitalVerificationAPI, ServerResponseTrace, TraitStateSnapshot, TransitionTrace, VerificationCheck, VerificationSnapshot, VerificationSummary } from '@almadar/core';
4
4
  import 'react';
5
- import '../paintDispatch-Cb_hQj4Y.cjs';
5
+ import '../paintDispatch-BjZjUbcb.cjs';
6
+ import '../types-B3nHgnMG.cjs';
6
7
  import 'clsx';
7
8
 
8
9
  /**
@@ -1,8 +1,9 @@
1
- export { C as ContentSegment, D as DEFAULT_CONFIG, a as DomEntityBox, b as DomLayoutData, c as DomOutputsBox, d as DomStateNode, e as DomTransitionLabel, f as DomTransitionPath, E as EntityDefinition, L as LessonSegment, R as RenderOptions, S as StateDefinition, g as StateMachineDefinition, T as TraitSnapshotGetter, h as TransitionDefinition, V as VisualizerConfig, i as bindCanvasCapture, j as bindEventBus, k as bindLastDrawables, l as bindTraitStateGetter, m as clearVerification, n as cn, o as extractOutputsFromTransitions, p as extractStateMachine, q as formatGuard, r as getAllChecks, s as getBridgeHealth, t as getEffectSummary, u as getSnapshot, v as getSummary, w as getTraitSnapshots, x as getTransitions, y as getTransitionsForTrait, z as parseContentSegments, A as parseLessonSegments, B as parseMarkdownWithCodeBlocks, F as recordServerResponse, G as recordTransition, H as registerCheck, I as registerTraitSnapshot, J as renderStateMachineToDomData, K as renderStateMachineToSvg, M as subscribeToVerification, N as updateAssetStatus, O as updateBridgeHealth, P as updateCheck, Q as waitForTransition } from '../cn-CWxxLkri.js';
1
+ export { C as ContentSegment, D as DEFAULT_CONFIG, a as DomEntityBox, b as DomLayoutData, c as DomOutputsBox, d as DomStateNode, e as DomTransitionLabel, f as DomTransitionPath, E as EntityDefinition, L as LessonSegment, R as RenderOptions, S as StateDefinition, g as StateMachineDefinition, T as TraitSnapshotGetter, h as TransitionDefinition, V as VisualizerConfig, i as bindCanvasCapture, j as bindEventBus, k as bindLastDrawables, l as bindTraitStateGetter, m as clearVerification, n as cn, o as extractOutputsFromTransitions, p as extractStateMachine, q as formatGuard, r as getAllChecks, s as getBridgeHealth, t as getEffectSummary, u as getSnapshot, v as getSummary, w as getTraitSnapshots, x as getTransitions, y as getTransitionsForTrait, z as parseContentSegments, A as parseLessonSegments, B as parseMarkdownWithCodeBlocks, F as recordServerResponse, G as recordTransition, H as registerCheck, I as registerTraitSnapshot, J as renderStateMachineToDomData, K as renderStateMachineToSvg, M as subscribeToVerification, N as updateAssetStatus, O as updateBridgeHealth, P as updateCheck, Q as waitForTransition } from '../cn-DJTUjk1M.js';
2
2
  import { FieldValue, EntityRow, EventPayload } from '@almadar/core';
3
3
  export { AssetLoadStatus, BridgeHealth, CheckStatus, EffectTrace, EventLogEntry, OrbitalVerificationAPI, ServerResponseTrace, TraitStateSnapshot, TransitionTrace, VerificationCheck, VerificationSnapshot, VerificationSummary } from '@almadar/core';
4
4
  import 'react';
5
- import '../paintDispatch-Cb_hQj4Y.js';
5
+ import '../paintDispatch-CxdLjHQq.js';
6
+ import '../types-B3nHgnMG.js';
6
7
  import 'clsx';
7
8
 
8
9
  /**
@@ -1,22 +1,6 @@
1
1
  import { ScenePos, Asset } from '@almadar/core';
2
+ import { P as Point, R as Rect } from './types-B3nHgnMG.cjs';
2
3
 
3
- /** Source sub-rectangle within a texture (an atlas frame). Omitted → whole texture. */
4
- interface BlitSrc {
5
- x: number;
6
- y: number;
7
- w: number;
8
- h: number;
9
- }
10
- /** A polyline/polygon vertex in pixel space. */
11
- interface PainterPoint {
12
- x: number;
13
- y: number;
14
- }
15
- /** A drop shadow applied to subsequent draws until cleared. */
16
- interface PainterShadow {
17
- color: string;
18
- blur: number;
19
- }
20
4
  /** One color stop of a {@link PainterGradient}; `offset` is 0..1 along the gradient. */
21
5
  interface PainterGradientStop {
22
6
  offset: number;
@@ -57,50 +41,6 @@ interface DrawableBase {
57
41
  id?: string;
58
42
  }
59
43
 
60
- /**
61
- * `draw-sprite` — the neutral image/atlas-frame drawable atom (dimension-agnostic).
62
- *
63
- * ONE descriptor (`DrawSpriteProps`, grounded in core `ScenePos` + `Asset`) with
64
- * TWO backends: `paintSprite` (2D, here — via the portable `Painter2D` seam) and
65
- * an R3F mesh (`Sprite3D` in `lib/drawable/mesh3d`, kept OUT of this file so the
66
- * 2D paint path never pulls `three`/`drei` into an app bundle — the codebase
67
- * code-splits R3F). The canvas host picks the backend by `mode`; that is what
68
- * makes canvas-2d and canvas-3d the same `children` interface. Genre uses (tile,
69
- * unit body, feature, effect, movement ghost, background cover) are all this atom
70
- * with different `anchor`/`size`/`frame`/`flip`/`shadow` — composed in `.lolo`,
71
- * not here. The React component renders `null` (a drawable is painted by the host,
72
- * not the DOM); it exists so the pattern pipeline registers a `draw-sprite`
73
- * pattern and standalone pages stay inspectable.
74
- */
75
-
76
- interface DrawSpriteProps extends DrawableBase {
77
- type: 'draw-sprite';
78
- /** Logical scene position; the projector maps it to pixels / world. */
79
- position: ScenePos;
80
- /** The image / atlas reference to blit. */
81
- asset: Asset;
82
- /** How the sprite aligns to its projected position. Default `'top-left'`. */
83
- anchor?: DrawableAnchor;
84
- /** Draw width in world units (fractions of `projector.tileWidth`). Omitted → one cell on tile grids (`flat`/`iso`/`hex`); native source px on `free`/`side`. */
85
- width?: number;
86
- /** Draw height in world units (fractions of `projector.tileWidth`). Omitted → one cell on tile grids (`flat`/`iso`/`hex`); native source px on `free`/`side`. */
87
- height?: number;
88
- /** Explicit atlas sub-rect override (px); omitted → resolved from `asset.atlas`/`asset.sprite`. */
89
- frame?: BlitSrc;
90
- /** Animation to play. 3D backend: a named GLB clip (matched case-insensitively). 2D painter: when `asset.atlas` resolves to a `SpriteSheetAtlas` manifest, the canonical row of that name (idle/walk/attack/hit/death) plays off the host paint clock; an explicit `frame` rect overrides. */
91
- animation?: string;
92
- /** Override the sheet row's loop flag. The paint clock is wall-time, so one-shot rows hold their final frame — preview pages set `true` to cycle attack/hit/death continuously. */
93
- loop?: boolean;
94
- /** Mirror horizontally (facing). */
95
- flipX?: boolean;
96
- /** Rotation in radians about the sprite's center. */
97
- rotation?: number;
98
- /** 0..1 opacity. */
99
- opacity?: number;
100
- /** Drop shadow (e.g. a team-colored glow). */
101
- shadow?: PainterShadow;
102
- }
103
-
104
44
  /**
105
45
  * `draw-shape` — the neutral vector-fill/stroke drawable atom (dimension-agnostic).
106
46
  *
@@ -128,11 +68,11 @@ type DrawShapeGradientStop = PainterGradientStop;
128
68
  interface DrawShapeGradient {
129
69
  kind: 'linear' | 'radial' | 'conic';
130
70
  /** Linear start point in world units. */
131
- from?: PainterPoint;
71
+ from?: Point;
132
72
  /** Linear end point in world units. */
133
- to?: PainterPoint;
73
+ to?: Point;
134
74
  /** Radial/conic center in world units. */
135
- center?: PainterPoint;
75
+ center?: Point;
136
76
  /** Radial radius in world units. */
137
77
  radius?: number;
138
78
  /** Conic start angle in radians. */
@@ -216,7 +156,7 @@ interface DrawShapeProps extends DrawableBase {
216
156
  offsetX?: number;
217
157
  offsetY?: number;
218
158
  /** Poly vertices as world-unit offsets relative to the cell's projected top-left. */
219
- points?: PainterPoint[];
159
+ points?: Point[];
220
160
  /** SVG path data in world units relative to the cell's projected top-left — same coordinate convention as `points`. */
221
161
  d?: string;
222
162
  fill?: string;
@@ -239,7 +179,7 @@ interface DrawShapeProps extends DrawableBase {
239
179
  /** Rotation in radians (painter units, same as `draw-group`), about `pivot`. */
240
180
  rotate?: number;
241
181
  /** Rotation pivot in world units relative to the cell's projected top-left; default `{x:0.5, y:0.5}` (cell center). */
242
- pivot?: PainterPoint;
182
+ pivot?: Point;
243
183
  /** Soft glow / drop-shadow behind the shape; `blur` in world units. */
244
184
  shadow?: DrawShapeShadow;
245
185
  /** Keyframe animation over this shape's props; the host runs a paint clock while present. */
@@ -248,6 +188,50 @@ interface DrawShapeProps extends DrawableBase {
248
188
  opacity?: number;
249
189
  }
250
190
 
191
+ /**
192
+ * `draw-sprite` — the neutral image/atlas-frame drawable atom (dimension-agnostic).
193
+ *
194
+ * ONE descriptor (`DrawSpriteProps`, grounded in core `ScenePos` + `Asset`) with
195
+ * TWO backends: `paintSprite` (2D, here — via the portable `Painter2D` seam) and
196
+ * an R3F mesh (`Sprite3D` in `lib/drawable/mesh3d`, kept OUT of this file so the
197
+ * 2D paint path never pulls `three`/`drei` into an app bundle — the codebase
198
+ * code-splits R3F). The canvas host picks the backend by `mode`; that is what
199
+ * makes canvas-2d and canvas-3d the same `children` interface. Genre uses (tile,
200
+ * unit body, feature, effect, movement ghost, background cover) are all this atom
201
+ * with different `anchor`/`size`/`frame`/`flip`/`shadow` — composed in `.lolo`,
202
+ * not here. The React component renders `null` (a drawable is painted by the host,
203
+ * not the DOM); it exists so the pattern pipeline registers a `draw-sprite`
204
+ * pattern and standalone pages stay inspectable.
205
+ */
206
+
207
+ interface DrawSpriteProps extends DrawableBase {
208
+ type: 'draw-sprite';
209
+ /** Logical scene position; the projector maps it to pixels / world. */
210
+ position: ScenePos;
211
+ /** The image / atlas reference to blit. */
212
+ asset: Asset;
213
+ /** How the sprite aligns to its projected position. Default `'top-left'`. */
214
+ anchor?: DrawableAnchor;
215
+ /** Draw width in world units (fractions of `projector.tileWidth`). Omitted → one cell on tile grids (`flat`/`iso`/`hex`); native source px on `free`/`side`. */
216
+ width?: number;
217
+ /** Draw height in world units (fractions of `projector.tileWidth`). Omitted → one cell on tile grids (`flat`/`iso`/`hex`); native source px on `free`/`side`. */
218
+ height?: number;
219
+ /** Explicit atlas sub-rect override (px); omitted → resolved from `asset.atlas`/`asset.sprite`. */
220
+ frame?: Rect;
221
+ /** Animation to play. 3D backend: a named GLB clip (matched case-insensitively). 2D painter: when `asset.atlas` resolves to a `SpriteSheetAtlas` manifest, the canonical row of that name (idle/walk/attack/hit/death) plays off the host paint clock; an explicit `frame` rect overrides. */
222
+ animation?: string;
223
+ /** Override the sheet row's loop flag. The paint clock is wall-time, so one-shot rows hold their final frame — preview pages set `true` to cycle attack/hit/death continuously. */
224
+ loop?: boolean;
225
+ /** Mirror horizontally (facing). */
226
+ flipX?: boolean;
227
+ /** Rotation in radians about the sprite's center. */
228
+ rotation?: number;
229
+ /** 0..1 opacity. */
230
+ opacity?: number;
231
+ /** Drop shadow (e.g. a team-colored glow). */
232
+ shadow?: DrawShapeShadow;
233
+ }
234
+
251
235
  /**
252
236
  * `draw-text` — the neutral text drawable atom (dimension-agnostic).
253
237
  *
@@ -258,6 +242,16 @@ interface DrawShapeProps extends DrawableBase {
258
242
  * component renders `null` (a drawable is painted by the host, not the DOM).
259
243
  */
260
244
 
245
+ /**
246
+ * Mirrors DOM lib.dom.d.ts `CanvasTextAlign` by value (used directly instead
247
+ * of the ambient global so the pattern-sync scanner — which only indexes
248
+ * `components/**` and can't see ambient TS-lib types — resolves this to a
249
+ * concrete enum instead of `json`). Structurally identical; `node.align`
250
+ * still flows straight into `Painter2D.text`'s `TextStyle.align`.
251
+ */
252
+ type DrawTextAlign = 'center' | 'end' | 'left' | 'right' | 'start';
253
+ /** Mirrors DOM `CanvasTextBaseline` by value — see {@link DrawTextAlign}. */
254
+ type DrawTextBaseline = 'alphabetic' | 'bottom' | 'hanging' | 'ideographic' | 'middle' | 'top';
261
255
  interface DrawTextProps extends DrawableBase {
262
256
  type: 'draw-text';
263
257
  text: string;
@@ -268,8 +262,8 @@ interface DrawTextProps extends DrawableBase {
268
262
  offsetY?: number;
269
263
  color: string;
270
264
  font?: string;
271
- align?: CanvasTextAlign;
272
- baseline?: CanvasTextBaseline;
265
+ align?: DrawTextAlign;
266
+ baseline?: DrawTextBaseline;
273
267
  opacity?: number;
274
268
  }
275
269
 
@@ -525,4 +519,4 @@ interface DrawTextLayerProps extends DrawableBase {
525
519
  /** Every drawable descriptor. The host's `children` are a `DrawableNode[]`. */
526
520
  type DrawableNode = DrawSpriteProps | DrawShapeProps | DrawTextProps | DrawGroupProps | DrawMeshProps | DrawSpriteLayerProps | DrawShapeLayerProps | DrawTextLayerProps;
527
521
 
528
- export type { DrawableNode as D };
522
+ export type { DrawableNode as D, MeshShapeKind as M, MeshMaterial as a, DrawGroupProps as b, DrawTextProps as c, DrawMeshProps as d };