@pascal-app/core 1.0.0 → 1.0.3

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 (345) hide show
  1. package/dist/capture/index.d.ts +2 -2
  2. package/dist/capture/index.js +2 -2
  3. package/dist/capture/schema.d.ts.map +1 -1
  4. package/dist/capture/schema.js +2 -0
  5. package/dist/capture/source.d.ts +1 -1
  6. package/dist/capture/source.js +1 -1
  7. package/dist/events/bus.d.ts +6 -3
  8. package/dist/events/bus.d.ts.map +1 -1
  9. package/dist/hooks/spatial-grid/floor-placed-elevation.d.ts +4 -4
  10. package/dist/hooks/spatial-grid/floor-placed-elevation.d.ts.map +1 -1
  11. package/dist/hooks/spatial-grid/floor-placed-elevation.js +7 -12
  12. package/dist/hooks/spatial-grid/floor-placed-footprints.d.ts +4 -0
  13. package/dist/hooks/spatial-grid/floor-placed-footprints.d.ts.map +1 -0
  14. package/dist/hooks/spatial-grid/floor-placed-footprints.js +7 -0
  15. package/dist/hooks/spatial-grid/spatial-grid-manager.d.ts +5 -8
  16. package/dist/hooks/spatial-grid/spatial-grid-manager.d.ts.map +1 -1
  17. package/dist/hooks/spatial-grid/spatial-grid-manager.js +23 -106
  18. package/dist/hooks/spatial-grid/spatial-grid-sync.d.ts +263 -84
  19. package/dist/hooks/spatial-grid/spatial-grid-sync.d.ts.map +1 -1
  20. package/dist/hooks/spatial-grid/spatial-grid-sync.js +77 -13
  21. package/dist/hooks/spatial-grid/support-host-patch.d.ts +1 -1
  22. package/dist/hooks/spatial-grid/support-host-patch.js +6 -6
  23. package/dist/hooks/spatial-grid/use-spatial-query.d.ts +1 -1
  24. package/dist/hooks/spatial-grid/use-spatial-query.js +1 -1
  25. package/dist/index.d.ts +77 -72
  26. package/dist/index.d.ts.map +1 -1
  27. package/dist/index.js +74 -69
  28. package/dist/lib/door-operation.d.ts +1 -1
  29. package/dist/lib/item-polygon-overlap.d.ts +6 -0
  30. package/dist/lib/item-polygon-overlap.d.ts.map +1 -0
  31. package/dist/lib/item-polygon-overlap.js +67 -0
  32. package/dist/lib/level-name.d.ts +1 -1
  33. package/dist/lib/measurement-geometry.d.ts +4 -4
  34. package/dist/lib/node-visibility.d.ts +12 -0
  35. package/dist/lib/node-visibility.d.ts.map +1 -0
  36. package/dist/lib/node-visibility.js +12 -0
  37. package/dist/lib/plan-footprint.d.ts +41 -0
  38. package/dist/lib/plan-footprint.d.ts.map +1 -0
  39. package/dist/lib/plan-footprint.js +58 -0
  40. package/dist/lib/room-topology-index.d.ts +1 -1
  41. package/dist/lib/room-topology-index.js +1 -1
  42. package/dist/lib/selection-proxy.d.ts +1 -1
  43. package/dist/lib/slab-polygon.d.ts +2 -2
  44. package/dist/lib/slab-polygon.js +2 -2
  45. package/dist/lib/space-detection.d.ts +1 -1
  46. package/dist/lib/space-detection.d.ts.map +1 -1
  47. package/dist/lib/space-detection.js +16 -11
  48. package/dist/lib/terrain-brush.d.ts +1 -1
  49. package/dist/lib/terrain-brush.js +1 -1
  50. package/dist/lib/terrain-codec.d.ts +2 -2
  51. package/dist/lib/terrain-codec.js +1 -1
  52. package/dist/lib/terrain-raycast.d.ts +1 -1
  53. package/dist/lib/terrain-raycast.js +1 -1
  54. package/dist/lib/terrain-source.d.ts +3 -3
  55. package/dist/lib/terrain-source.js +3 -3
  56. package/dist/lib/terrain-support.d.ts +1 -1
  57. package/dist/lib/terrain-support.js +3 -3
  58. package/dist/lib/unit-containment.d.ts +19 -0
  59. package/dist/lib/unit-containment.d.ts.map +1 -0
  60. package/dist/lib/unit-containment.js +158 -0
  61. package/dist/lib/unit-report.d.ts +19 -0
  62. package/dist/lib/unit-report.d.ts.map +1 -0
  63. package/dist/lib/unit-report.js +36 -0
  64. package/dist/lib/wall-distance.d.ts +2 -2
  65. package/dist/lib/wall-distance.js +1 -1
  66. package/dist/lib/zone-quantities.d.ts +1 -1
  67. package/dist/lib/zone-quantities.js +7 -7
  68. package/dist/material-library.d.ts +1 -1
  69. package/dist/material-library.js +1 -1
  70. package/dist/procedural-items/fixtures.d.ts +261 -0
  71. package/dist/procedural-items/fixtures.d.ts.map +1 -0
  72. package/dist/procedural-items/fixtures.js +349 -0
  73. package/dist/procedural-items/index.d.ts +10 -0
  74. package/dist/procedural-items/index.d.ts.map +1 -0
  75. package/dist/procedural-items/index.js +9 -0
  76. package/dist/procedural-items/integration.d.ts +92 -0
  77. package/dist/procedural-items/integration.d.ts.map +1 -0
  78. package/dist/procedural-items/integration.js +19 -0
  79. package/dist/procedural-items/library-colors.d.ts +56 -0
  80. package/dist/procedural-items/library-colors.d.ts.map +1 -0
  81. package/dist/procedural-items/library-colors.js +84 -0
  82. package/dist/procedural-items/materials.d.ts +5 -0
  83. package/dist/procedural-items/materials.d.ts.map +1 -0
  84. package/dist/procedural-items/materials.js +47 -0
  85. package/dist/procedural-items/node.d.ts +280 -0
  86. package/dist/procedural-items/node.d.ts.map +1 -0
  87. package/dist/procedural-items/node.js +71 -0
  88. package/dist/procedural-items/placement.d.ts +7 -0
  89. package/dist/procedural-items/placement.d.ts.map +1 -0
  90. package/dist/procedural-items/placement.js +48 -0
  91. package/dist/procedural-items/query.d.ts +51 -0
  92. package/dist/procedural-items/query.d.ts.map +1 -0
  93. package/dist/procedural-items/query.js +342 -0
  94. package/dist/procedural-items/recipe.d.ts +144 -0
  95. package/dist/procedural-items/recipe.d.ts.map +1 -0
  96. package/dist/procedural-items/recipe.js +372 -0
  97. package/dist/procedural-items/spatial.d.ts +19 -0
  98. package/dist/procedural-items/spatial.d.ts.map +1 -0
  99. package/dist/procedural-items/spatial.js +39 -0
  100. package/dist/registry/__bench__/relations-resolver.bench.js +2 -2
  101. package/dist/registry/handles.d.ts +40 -5
  102. package/dist/registry/handles.d.ts.map +1 -1
  103. package/dist/registry/index.d.ts +6 -6
  104. package/dist/registry/index.d.ts.map +1 -1
  105. package/dist/registry/index.js +4 -4
  106. package/dist/registry/registry.d.ts +1 -1
  107. package/dist/registry/relations-resolver.d.ts +2 -2
  108. package/dist/registry/relations-resolver.js +1 -1
  109. package/dist/registry/scene-api.d.ts +2 -2
  110. package/dist/registry/scene-api.js +2 -2
  111. package/dist/registry/subtree.d.ts +1 -1
  112. package/dist/registry/subtree.d.ts.map +1 -1
  113. package/dist/registry/subtree.js +8 -2
  114. package/dist/registry/types.d.ts +32 -10
  115. package/dist/registry/types.d.ts.map +1 -1
  116. package/dist/registry/use-registry-version.js +1 -1
  117. package/dist/registry/validate-relations.d.ts +4 -0
  118. package/dist/registry/validate-relations.d.ts.map +1 -0
  119. package/dist/registry/validate-relations.js +22 -0
  120. package/dist/schema/__bench__/node-parsers.bench.js +3 -3
  121. package/dist/schema/__fixtures__/node-fixtures.d.ts +1 -1
  122. package/dist/schema/__fixtures__/node-fixtures.d.ts.map +1 -1
  123. package/dist/schema/__fixtures__/node-fixtures.js +4 -2
  124. package/dist/schema/base.js +1 -1
  125. package/dist/schema/collections.d.ts +1 -1
  126. package/dist/schema/collections.js +1 -1
  127. package/dist/schema/compiled-node-parsers.d.ts +1 -1
  128. package/dist/schema/compiled-node-parsers.js +1 -1
  129. package/dist/schema/index.d.ts +74 -70
  130. package/dist/schema/index.d.ts.map +1 -1
  131. package/dist/schema/index.js +65 -61
  132. package/dist/schema/material.d.ts +1 -1
  133. package/dist/schema/material.js +1 -1
  134. package/dist/schema/nodes/automatic-downspout.d.ts +4 -4
  135. package/dist/schema/nodes/automatic-downspout.js +5 -5
  136. package/dist/schema/nodes/block.d.ts +3 -3
  137. package/dist/schema/nodes/block.d.ts.map +1 -1
  138. package/dist/schema/nodes/block.js +24 -12
  139. package/dist/schema/nodes/box-vent.js +2 -2
  140. package/dist/schema/nodes/building.d.ts +1 -1
  141. package/dist/schema/nodes/building.d.ts.map +1 -1
  142. package/dist/schema/nodes/building.js +8 -5
  143. package/dist/schema/nodes/cabinet.d.ts +4 -4
  144. package/dist/schema/nodes/cabinet.js +4 -4
  145. package/dist/schema/nodes/ceiling.d.ts +1 -1
  146. package/dist/schema/nodes/ceiling.js +5 -5
  147. package/dist/schema/nodes/chimney.js +2 -2
  148. package/dist/schema/nodes/column.d.ts +1 -0
  149. package/dist/schema/nodes/column.d.ts.map +1 -1
  150. package/dist/schema/nodes/column.js +3 -2
  151. package/dist/schema/nodes/construction-dimension.d.ts +3 -3
  152. package/dist/schema/nodes/construction-dimension.js +2 -2
  153. package/dist/schema/nodes/cupola.d.ts +1 -1
  154. package/dist/schema/nodes/cupola.js +2 -2
  155. package/dist/schema/nodes/curtain-wall.d.ts +129 -0
  156. package/dist/schema/nodes/curtain-wall.d.ts.map +1 -0
  157. package/dist/schema/nodes/curtain-wall.js +49 -0
  158. package/dist/schema/nodes/door.d.ts +2 -2
  159. package/dist/schema/nodes/door.js +2 -2
  160. package/dist/schema/nodes/dormer.d.ts +3 -3
  161. package/dist/schema/nodes/dormer.js +4 -4
  162. package/dist/schema/nodes/downspout.js +2 -2
  163. package/dist/schema/nodes/duct-fitting.js +1 -1
  164. package/dist/schema/nodes/duct-segment.js +2 -2
  165. package/dist/schema/nodes/duct-terminal.js +1 -1
  166. package/dist/schema/nodes/elevator.js +2 -2
  167. package/dist/schema/nodes/eyebrow-vent.js +2 -2
  168. package/dist/schema/nodes/fence.js +2 -2
  169. package/dist/schema/nodes/guide.js +2 -2
  170. package/dist/schema/nodes/gutter.d.ts +1 -1
  171. package/dist/schema/nodes/gutter.js +4 -4
  172. package/dist/schema/nodes/hvac-equipment.js +1 -1
  173. package/dist/schema/nodes/imported-mesh.d.ts +40 -0
  174. package/dist/schema/nodes/imported-mesh.d.ts.map +1 -0
  175. package/dist/schema/nodes/imported-mesh.js +27 -0
  176. package/dist/schema/nodes/item.d.ts +3 -3
  177. package/dist/schema/nodes/item.js +3 -3
  178. package/dist/schema/nodes/lean-to-extension.js +4 -4
  179. package/dist/schema/nodes/level.d.ts +1 -1
  180. package/dist/schema/nodes/level.d.ts.map +1 -1
  181. package/dist/schema/nodes/level.js +1 -1
  182. package/dist/schema/nodes/lineset.js +1 -1
  183. package/dist/schema/nodes/liquid-line.js +1 -1
  184. package/dist/schema/nodes/measurement.js +2 -2
  185. package/dist/schema/nodes/pipe-fitting.d.ts +1 -1
  186. package/dist/schema/nodes/pipe-fitting.js +1 -1
  187. package/dist/schema/nodes/pipe-segment.d.ts +1 -1
  188. package/dist/schema/nodes/pipe-segment.js +2 -2
  189. package/dist/schema/nodes/pipe-trap.d.ts +1 -1
  190. package/dist/schema/nodes/pipe-trap.js +1 -1
  191. package/dist/schema/nodes/ridge-vent.d.ts +1 -1
  192. package/dist/schema/nodes/ridge-vent.js +3 -3
  193. package/dist/schema/nodes/roof-segment-shape.d.ts +1 -1
  194. package/dist/schema/nodes/roof-segment-shape.js +1 -1
  195. package/dist/schema/nodes/roof-segment-walls.d.ts +1 -1
  196. package/dist/schema/nodes/roof-segment-walls.js +1 -1
  197. package/dist/schema/nodes/roof-segment.d.ts +2 -2
  198. package/dist/schema/nodes/roof-segment.js +2 -2
  199. package/dist/schema/nodes/roof.d.ts +1 -1
  200. package/dist/schema/nodes/roof.js +3 -3
  201. package/dist/schema/nodes/scan.js +3 -3
  202. package/dist/schema/nodes/shelf.d.ts +1 -1
  203. package/dist/schema/nodes/shelf.d.ts.map +1 -1
  204. package/dist/schema/nodes/shelf.js +3 -4
  205. package/dist/schema/nodes/site.js +2 -2
  206. package/dist/schema/nodes/skylight.d.ts +4 -4
  207. package/dist/schema/nodes/skylight.js +2 -2
  208. package/dist/schema/nodes/slab.js +3 -3
  209. package/dist/schema/nodes/solar-panel.js +3 -3
  210. package/dist/schema/nodes/spawn.js +1 -1
  211. package/dist/schema/nodes/stair-segment.js +2 -2
  212. package/dist/schema/nodes/stair.d.ts +1 -1
  213. package/dist/schema/nodes/stair.js +3 -3
  214. package/dist/schema/nodes/structural-grid.js +1 -1
  215. package/dist/schema/nodes/turbine-vent.d.ts +1 -1
  216. package/dist/schema/nodes/turbine-vent.js +2 -2
  217. package/dist/schema/nodes/unit.d.ts +33 -0
  218. package/dist/schema/nodes/unit.d.ts.map +1 -0
  219. package/dist/schema/nodes/unit.js +13 -0
  220. package/dist/schema/nodes/wall.d.ts +75 -2
  221. package/dist/schema/nodes/wall.d.ts.map +1 -1
  222. package/dist/schema/nodes/wall.js +10 -6
  223. package/dist/schema/nodes/window.js +2 -2
  224. package/dist/schema/nodes/zone.js +1 -1
  225. package/dist/schema/scene-material.js +2 -2
  226. package/dist/schema/types.d.ts +417 -22
  227. package/dist/schema/types.d.ts.map +1 -1
  228. package/dist/schema/types.js +56 -49
  229. package/dist/services/__fixtures__/hosting.d.ts +3 -0
  230. package/dist/services/__fixtures__/hosting.d.ts.map +1 -0
  231. package/dist/services/__fixtures__/hosting.js +9 -0
  232. package/dist/services/__fixtures__/shelf-surface-rows.d.ts +4 -0
  233. package/dist/services/__fixtures__/shelf-surface-rows.d.ts.map +1 -0
  234. package/dist/services/__fixtures__/shelf-surface-rows.js +18 -0
  235. package/dist/services/alignment-anchors.d.ts +6 -11
  236. package/dist/services/alignment-anchors.d.ts.map +1 -1
  237. package/dist/services/alignment-anchors.js +7 -34
  238. package/dist/services/drag-session.d.ts +4 -4
  239. package/dist/services/drag-session.js +1 -1
  240. package/dist/services/hosting.d.ts +5 -8
  241. package/dist/services/hosting.d.ts.map +1 -1
  242. package/dist/services/hosting.js +25 -18
  243. package/dist/services/index.d.ts +16 -13
  244. package/dist/services/index.d.ts.map +1 -1
  245. package/dist/services/index.js +16 -13
  246. package/dist/services/level-height.d.ts +2 -2
  247. package/dist/services/level-height.js +3 -3
  248. package/dist/services/movement.d.ts +3 -3
  249. package/dist/services/movement.js +2 -2
  250. package/dist/services/port-connectivity.d.ts +1 -1
  251. package/dist/services/port-connectivity.js +1 -1
  252. package/dist/services/riser-diagram.d.ts +1 -1
  253. package/dist/services/shelf-board.d.ts +5 -0
  254. package/dist/services/shelf-board.d.ts.map +1 -0
  255. package/dist/services/shelf-board.js +15 -0
  256. package/dist/services/snap.d.ts +3 -0
  257. package/dist/services/snap.d.ts.map +1 -1
  258. package/dist/services/snap.js +11 -0
  259. package/dist/services/storey.d.ts +2 -2
  260. package/dist/services/storey.js +2 -2
  261. package/dist/services/surface-hosting-procedural-parity.fixtures.d.ts +13 -0
  262. package/dist/services/surface-hosting-procedural-parity.fixtures.d.ts.map +1 -0
  263. package/dist/services/surface-hosting-procedural-parity.fixtures.js +4691 -0
  264. package/dist/services/surface-hosting-shelf-parity.fixtures.d.ts +1060 -0
  265. package/dist/services/surface-hosting-shelf-parity.fixtures.d.ts.map +1 -0
  266. package/dist/services/surface-hosting-shelf-parity.fixtures.js +3127 -0
  267. package/dist/services/surface-hosting.d.ts +92 -0
  268. package/dist/services/surface-hosting.d.ts.map +1 -0
  269. package/dist/services/surface-hosting.js +305 -0
  270. package/dist/services/surface-region.d.ts +8 -0
  271. package/dist/services/surface-region.d.ts.map +1 -0
  272. package/dist/services/surface-region.js +44 -0
  273. package/dist/services/system-graph.d.ts +2 -2
  274. package/dist/services/system-graph.js +2 -2
  275. package/dist/services/validate-dwv.d.ts +1 -1
  276. package/dist/services/validate-dwv.js +1 -1
  277. package/dist/store/actions/node-actions.d.ts +2 -2
  278. package/dist/store/actions/node-actions.d.ts.map +1 -1
  279. package/dist/store/actions/node-actions.js +50 -104
  280. package/dist/store/history-control.d.ts +3 -3
  281. package/dist/store/history-invalidation.d.ts +1 -1
  282. package/dist/store/history-invalidation.js +1 -1
  283. package/dist/store/use-interactive.d.ts +2 -2
  284. package/dist/store/use-live-terrain.d.ts +1 -1
  285. package/dist/store/use-scene.d.ts +4 -4
  286. package/dist/store/use-scene.d.ts.map +1 -1
  287. package/dist/store/use-scene.js +50 -32
  288. package/dist/systems/elevator/elevator-dispatch.d.ts +2 -2
  289. package/dist/systems/elevator/elevator-dispatch.js +1 -1
  290. package/dist/systems/elevator/elevator-geometry.d.ts +1 -1
  291. package/dist/systems/elevator/elevator-opening-sync.d.ts +1 -1
  292. package/dist/systems/elevator/elevator-opening-sync.js +2 -2
  293. package/dist/systems/elevator/elevator-opening-system.js +3 -3
  294. package/dist/systems/elevator/elevator-runtime.d.ts +3 -3
  295. package/dist/systems/elevator/elevator-runtime.js +3 -3
  296. package/dist/systems/elevator/elevator-service.d.ts +1 -1
  297. package/dist/systems/elevator/elevator-service.js +1 -1
  298. package/dist/systems/fence/fence-centerline.d.ts +2 -2
  299. package/dist/systems/fence/fence-centerline.js +2 -2
  300. package/dist/systems/fence/fence-spline.d.ts +2 -2
  301. package/dist/systems/roof/roof-elevation-system.js +3 -3
  302. package/dist/systems/roof/roof-elevation.d.ts +2 -2
  303. package/dist/systems/roof/roof-elevation.js +6 -6
  304. package/dist/systems/roof/roof-footprint.d.ts +1 -1
  305. package/dist/systems/roof/roof-footprint.js +3 -3
  306. package/dist/systems/slab/slab-placement.d.ts +1 -1
  307. package/dist/systems/slab/slab-support.d.ts +1 -1
  308. package/dist/systems/slab/slab-support.js +4 -4
  309. package/dist/systems/stair/stair-flight.d.ts +2 -2
  310. package/dist/systems/stair/stair-flight.js +2 -2
  311. package/dist/systems/stair/stair-footprint.d.ts +1 -1
  312. package/dist/systems/stair/stair-opening-preview.d.ts +248 -87
  313. package/dist/systems/stair/stair-opening-preview.d.ts.map +1 -1
  314. package/dist/systems/stair/stair-opening-preview.js +2 -2
  315. package/dist/systems/stair/stair-opening-sync.d.ts +1 -1
  316. package/dist/systems/stair/stair-opening-sync.js +6 -6
  317. package/dist/systems/stair/stair-opening-system.js +8 -8
  318. package/dist/systems/stair/stair-rise.d.ts +1 -1
  319. package/dist/systems/stair/stair-rise.js +3 -3
  320. package/dist/systems/wall/wall-curve.d.ts +2 -2
  321. package/dist/systems/wall/wall-footprint.d.ts +3 -3
  322. package/dist/systems/wall/wall-footprint.js +3 -3
  323. package/dist/systems/wall/wall-merge.d.ts +38 -0
  324. package/dist/systems/wall/wall-merge.d.ts.map +1 -0
  325. package/dist/systems/wall/wall-merge.js +240 -0
  326. package/dist/systems/wall/wall-mitering.d.ts +1 -1
  327. package/dist/systems/wall/wall-mitering.js +1 -1
  328. package/dist/systems/wall/wall-move.d.ts +1 -1
  329. package/dist/systems/wall/wall-operations.d.ts +28 -0
  330. package/dist/systems/wall/wall-operations.d.ts.map +1 -0
  331. package/dist/systems/wall/wall-operations.js +145 -0
  332. package/dist/systems/wall/wall-top.d.ts +1 -1
  333. package/dist/systems/wall/wall-topology.d.ts +9 -2
  334. package/dist/systems/wall/wall-topology.d.ts.map +1 -1
  335. package/dist/systems/wall/wall-topology.js +57 -9
  336. package/dist/utils/clone-scene-graph.d.ts +3 -3
  337. package/dist/utils/clone-scene-graph.d.ts.map +1 -1
  338. package/dist/utils/clone-scene-graph.js +9 -3
  339. package/dist/utils/scene-migrations.d.ts +3 -3
  340. package/dist/utils/scene-migrations.js +3 -3
  341. package/dist/utils/vertical-scene-migration.js +5 -5
  342. package/dist/validation/validate-build-json.d.ts +5 -2
  343. package/dist/validation/validate-build-json.d.ts.map +1 -1
  344. package/dist/validation/validate-build-json.js +57 -4
  345. package/package.json +15 -4
@@ -0,0 +1,342 @@
1
+ import { getFloorPlacedFootprints } from '../hooks/spatial-grid/floor-placed-footprints.js';
2
+ import { itemOverlapsPolygon } from '../lib/item-polygon-overlap.js';
3
+ import { pointInPolygon as containsPoint, polygonsOverlap, } from '../lib/polygon-relations.js';
4
+ import { getRenderableSlabPolygon } from '../lib/slab-polygon.js';
5
+ import { levelBaseElevationAt } from '../lib/terrain-support.js';
6
+ import { nodeRegistry } from '../registry/registry.js';
7
+ import { getBlockFaceFrame } from '../schema/nodes/block.js';
8
+ import { getRoofWallFaceFrame, roofFacePointToSegment } from '../schema/nodes/roof-segment-walls.js';
9
+ import { resolveCeilingHeight } from '../services/level-height.js';
10
+ import { getStoredLevelHeight } from '../services/storey.js';
11
+ import { surfaceRegionContainsPoint } from '../services/surface-region.js';
12
+ import { computeWallSlabSupport, pointInPolygon } from '../systems/slab/slab-support.js';
13
+ import { getWallThickness } from '../systems/wall/wall-footprint.js';
14
+ import { evaluateRecipe } from './recipe.js';
15
+ import { boundsOf, boxCorners, composeFrames, frame, IDENTITY_FRAME, transformPoint, } from './spatial.js';
16
+ export function isProceduralItem(node) {
17
+ return Boolean(node && typeof node === 'object' && 'type' in node && node.type === 'procedural-item');
18
+ }
19
+ function levelSurfaces(nodes, levelId) {
20
+ const siblings = Object.values(nodes).filter((n) => n.parentId === levelId);
21
+ return {
22
+ slabs: siblings.filter((n) => n.type === 'slab'),
23
+ walls: siblings.filter((n) => n.type === 'wall'),
24
+ };
25
+ }
26
+ export function proceduralLocalPose(node, nodes) {
27
+ const position = [...node.position], rotation = [...node.rotation];
28
+ if (node.recipe.mounting?.attachTo === 'ceiling' &&
29
+ node.parentId &&
30
+ nodes[node.parentId]?.type === 'ceiling') {
31
+ const reference = evaluateRecipe(node.recipe, node.parameters).surfaces.find((s) => s.id === node.recipe.mounting?.reference);
32
+ if (!reference)
33
+ throw new Error('Missing mounting reference');
34
+ const offset = transformPoint(frame([0, 0, 0], rotation), reference.position);
35
+ for (let i = 0; i < 3; i++)
36
+ position[i] = position[i] - offset[i];
37
+ return { position, rotation };
38
+ }
39
+ if (!node.wallId)
40
+ return { position, rotation };
41
+ const wall = nodes[node.wallId];
42
+ if (wall?.type !== 'wall')
43
+ throw new Error('Missing wall host');
44
+ const reference = evaluateRecipe(node.recipe, node.parameters).surfaces.find((s) => s.id === node.recipe.mounting?.reference);
45
+ if (!reference)
46
+ throw new Error('Missing mounting reference');
47
+ const sign = node.side === 'back' ? -1 : 1;
48
+ rotation[1] = sign < 0 ? Math.PI : 0;
49
+ position[0] -= reference.position[0] * sign;
50
+ position[1] -= reference.position[1];
51
+ position[2] = sign * (getWallThickness(wall) / 2 - reference.position[2] + node.position[2]);
52
+ return { position, rotation };
53
+ }
54
+ export function proceduralFootprint(node) {
55
+ const e = evaluateRecipe(node.recipe, node.parameters);
56
+ const center = e.min.map((v, i) => (v + e.max[i]) / 2);
57
+ const position = transformPoint(frame(node.position, node.rotation), center);
58
+ return { position, rotation: node.rotation, dimensions: e.dimensions };
59
+ }
60
+ function floorLift(node, nodes) {
61
+ if (!node.parentId || nodes[node.parentId]?.type !== 'level' || !('position' in node))
62
+ return 0;
63
+ const position = node.position;
64
+ const supportSlabId = node.supportSlabId;
65
+ const capability = nodeRegistry.get(node.type)?.capabilities.floorPlaced;
66
+ const { slabs, walls } = levelSurfaces(nodes, node.parentId);
67
+ const ground = levelBaseElevationAt(nodes, node.parentId, position[0], position[2]);
68
+ if (supportSlabId === 'ground')
69
+ return ground;
70
+ if (capability || node.type === 'cabinet' || node.type === 'cabinet-module') {
71
+ const footprints = capability
72
+ ? getFloorPlacedFootprints(capability, node, { nodes: nodes })
73
+ : [];
74
+ const candidatesFor = (footprint) => slabs.filter((slab) => {
75
+ const footprintPosition = footprint.position ?? position;
76
+ return (itemOverlapsPolygon(footprintPosition, footprint.dimensions, footprint.rotation, getRenderableSlabPolygon(slab, { walls, siblingSlabs: slabs }), 0.005) &&
77
+ !(slab.holes ?? []).some((hole) => pointInPolygon(footprintPosition[0], footprintPosition[2], hole)));
78
+ });
79
+ const candidates = footprints.map(candidatesFor);
80
+ const pinned = candidates.flat().find((slab) => slab.id === supportSlabId);
81
+ if (pinned)
82
+ return pinned.elevation ?? 0.05;
83
+ return candidates.length
84
+ ? Math.max(...candidates.map((slabs) => slabs.length ? Math.max(...slabs.map((slab) => slab.elevation ?? 0.05)) : ground))
85
+ : ground;
86
+ }
87
+ if (!(isProceduralItem(node) || node.type === 'item' || node.type === 'shelf'))
88
+ return 0;
89
+ const footprint = isProceduralItem(node)
90
+ ? proceduralFootprint(node)
91
+ : {
92
+ position: position,
93
+ dimensions: node.type === 'shelf'
94
+ ? [node.width, node.height, node.depth]
95
+ : node.asset.dimensions.map((v, i) => v * node.scale[i]),
96
+ rotation: node.rotation,
97
+ };
98
+ const candidates = slabs.filter((s) => {
99
+ const polygon = getRenderableSlabPolygon(s, { walls, siblingSlabs: slabs });
100
+ return (itemOverlapsPolygon(footprint.position, footprint.dimensions, footprint.rotation, polygon, 0.005) &&
101
+ !(s.holes ?? []).some((h) => pointInPolygon(footprint.position[0], footprint.position[2], h)));
102
+ });
103
+ const pinned = candidates.find((s) => s.id === supportSlabId);
104
+ return pinned
105
+ ? (pinned.elevation ?? 0.05)
106
+ : candidates.length
107
+ ? Math.max(...candidates.map((s) => s.elevation ?? 0.05))
108
+ : ground;
109
+ }
110
+ function nodeParentFrame(node, nodes, seen) {
111
+ if (!node.parentId)
112
+ return IDENTITY_FRAME;
113
+ let parentFrame = nodeLevelFrame(node.parentId, nodes, seen);
114
+ const parent = nodes[node.parentId];
115
+ if (isProceduralItem(parent) && parent.attachments[node.id] !== undefined) {
116
+ const surface = evaluateRecipe(parent.recipe, parent.parameters).surfaces.find((s) => s.id === parent.attachments[node.id]);
117
+ if (!surface)
118
+ throw new Error('Missing attachment surface');
119
+ parentFrame = composeFrames(parentFrame, frame(surface.position, surface.rotation));
120
+ }
121
+ return parentFrame;
122
+ }
123
+ export function nodeLevelFrame(id, nodes, seen = new Set()) {
124
+ if (seen.has(id) || seen.size > 32)
125
+ throw new Error('Cyclic or excessively deep hosting graph');
126
+ const node = nodes[id];
127
+ if (!node)
128
+ throw new Error(`Missing node ${id}`);
129
+ if (node.type === 'level')
130
+ return IDENTITY_FRAME;
131
+ seen.add(id);
132
+ if (node.type === 'ceiling') {
133
+ // Match the ceiling renderer's underside frame, including its 1 cm inset.
134
+ return frame([0, resolveCeilingHeight(node, nodes) - 0.01, 0], [0, 0, 0]);
135
+ }
136
+ if (node.type === 'wall') {
137
+ const { slabs, walls } = levelSurfaces(nodes, node.parentId ?? '');
138
+ const ground = levelBaseElevationAt(nodes, node.parentId ?? '', node.start[0], node.start[1]);
139
+ const support = computeWallSlabSupport(node, slabs, walls, node.supportSlabId, undefined, ground);
140
+ return frame([node.start[0], support.elevation + (node.supportOffset ?? 0), node.start[1]], [0, -Math.atan2(node.end[1] - node.start[1], node.end[0] - node.start[0]), 0]);
141
+ }
142
+ if (!(isProceduralItem(node) ||
143
+ node.type === 'item' ||
144
+ node.type === 'shelf' ||
145
+ node.type === 'cabinet' ||
146
+ node.type === 'cabinet-module')) {
147
+ const transform = node;
148
+ const rotation = typeof transform.rotation === 'number'
149
+ ? [0, transform.rotation, 0]
150
+ : transform.rotation;
151
+ const position = [...(transform.position ?? [0, 0, 0])];
152
+ const capability = nodeRegistry.get(node.type)?.capabilities.floorPlaced;
153
+ if (!capability?.applies || capability.applies(node)) {
154
+ position[1] += floorLift(node, nodes);
155
+ }
156
+ const local = node.type === 'slab' ? IDENTITY_FRAME : frame(position, rotation ?? [0, 0, 0]);
157
+ return node.parentId ? composeFrames(nodeParentFrame(node, nodes, seen), local) : local;
158
+ }
159
+ const pose = isProceduralItem(node)
160
+ ? proceduralLocalPose(node, nodes)
161
+ : {
162
+ position: [...node.position],
163
+ rotation: typeof node.rotation === 'number' ? [0, node.rotation, 0] : node.rotation,
164
+ };
165
+ const parent = node.parentId ? nodes[node.parentId] : undefined;
166
+ if (!node.parentId)
167
+ return frame(pose.position, pose.rotation);
168
+ if (node.type === 'item' && parent?.type === 'roof-segment' && node.roofFace) {
169
+ const face = getRoofWallFaceFrame(parent, node.roofFace);
170
+ const local = frame(roofFacePointToSegment(parent, node.roofFace, pose.position), pose.rotation);
171
+ local.axes = composeFrames(frame([0, 0, 0], [0, face.yaw, 0]), frame([0, 0, 0], pose.rotation)).axes;
172
+ return composeFrames(nodeLevelFrame(parent.id, nodes, seen), local);
173
+ }
174
+ if (node.type === 'item' && parent?.type === 'block' && node.blockFaceId) {
175
+ const face = getBlockFaceFrame(parent.topology, node.blockFaceId);
176
+ if (face) {
177
+ const host = nodeLevelFrame(parent.id, nodes, seen);
178
+ return composeFrames(host, composeFrames({ position: face.origin, axes: [face.xAxis, face.yAxis, face.normal] }, frame(pose.position, pose.rotation)));
179
+ }
180
+ }
181
+ const parentFrame = nodeParentFrame(node, nodes, seen);
182
+ if (parent?.type === 'level')
183
+ pose.position[1] += floorLift(node, nodes);
184
+ return composeFrames(parentFrame, frame(pose.position, pose.rotation));
185
+ }
186
+ function localBounds(node) {
187
+ if (isProceduralItem(node))
188
+ return evaluateRecipe(node.recipe, node.parameters);
189
+ const d = node.asset.dimensions.map((v, i) => v * node.scale[i]);
190
+ return { min: [-d[0] / 2, 0, -d[2] / 2], max: [d[0] / 2, d[1], d[2] / 2] };
191
+ }
192
+ export function attachmentBounds(child) {
193
+ const b = localBounds(child);
194
+ return boundsOf(boxCorners(b.min, b.max).map((p) => transformPoint(frame(child.position, child.rotation), p)));
195
+ }
196
+ export function attachmentRegionsOverlap(a, b) {
197
+ return (a.min[0] < b.max[0] - 1e-6 &&
198
+ a.max[0] > b.min[0] + 1e-6 &&
199
+ a.min[2] < b.max[2] - 1e-6 &&
200
+ a.max[2] > b.min[2] + 1e-6);
201
+ }
202
+ function ceilingContainsFootprint(outer, footprint) {
203
+ if (!footprint.every((p) => containsPoint(p, outer)))
204
+ return false;
205
+ // A concave boundary can cross a footprint whose corners all lie inside.
206
+ // Clip each boundary segment against the open, convex footprint interior.
207
+ return !outer.some((a, i) => {
208
+ const b = outer[(i + 1) % outer.length];
209
+ let enter = 0;
210
+ let exit = 1;
211
+ for (let j = 0; j < footprint.length; j++) {
212
+ const c = footprint[j], d = footprint[(j + 1) % footprint.length];
213
+ const distance = (p) => ((d[0] - c[0]) * (p[1] - c[1]) - (d[1] - c[1]) * (p[0] - c[0])) /
214
+ Math.hypot(d[0] - c[0], d[1] - c[1]) -
215
+ 1e-6;
216
+ const start = distance(a), end = distance(b);
217
+ if (start <= 0 && end <= 0)
218
+ return false;
219
+ if (start <= 0)
220
+ enter = Math.max(enter, -start / (end - start));
221
+ else if (end <= 0)
222
+ exit = Math.min(exit, start / (start - end));
223
+ if (enter >= exit)
224
+ return false;
225
+ }
226
+ return enter < exit;
227
+ });
228
+ }
229
+ export function validateProceduralRelations(raw, nodes) {
230
+ if (!isProceduralItem(raw))
231
+ return;
232
+ const node = raw, evaluation = evaluateRecipe(node.recipe, node.parameters);
233
+ const draft = node.metadata;
234
+ const awaitingHost = (draft?.isNew || draft?.isTransient) &&
235
+ !node.wallId &&
236
+ node.parentId &&
237
+ nodes[node.parentId]?.type === 'level';
238
+ if (node.recipe.mounting?.attachTo === 'ceiling' && !awaitingHost) {
239
+ const ceiling = node.parentId ? nodes[node.parentId] : undefined;
240
+ if (ceiling?.type !== 'ceiling' || node.wallId || node.side)
241
+ throw new Error('This design needs a ceiling host');
242
+ if (Math.abs(node.rotation[0]) > 1e-8 || Math.abs(node.rotation[2]) > 1e-8)
243
+ throw new Error('Ceiling designs allow Y rotation only');
244
+ if (Math.abs(node.position[1]) > 1e-6)
245
+ throw new Error('The top reference must be flush with the ceiling');
246
+ const pose = proceduralLocalPose(node, nodes);
247
+ const f = frame(pose.position, pose.rotation);
248
+ const b = boundsOf(boxCorners(evaluation.min, evaluation.max).map((p) => transformPoint(f, p)));
249
+ const height = nodeLevelFrame(ceiling.id, nodes).position[1];
250
+ const level = ceiling.parentId ? nodes[ceiling.parentId] : undefined;
251
+ if (b.min[1] + height < -1e-6 ||
252
+ b.max[1] > 1e-6 ||
253
+ b.max[1] + height > getStoredLevelHeight(level?.type === 'level' ? level : {}) + 1e-6)
254
+ throw new Error('The hanging design must fit below the ceiling within the level height');
255
+ const footprint = [
256
+ [evaluation.min[0], evaluation.min[2]],
257
+ [evaluation.max[0], evaluation.min[2]],
258
+ [evaluation.max[0], evaluation.max[2]],
259
+ [evaluation.min[0], evaluation.max[2]],
260
+ ].map(([x, z]) => {
261
+ const p = transformPoint(f, [x, 0, z]);
262
+ return [p[0], p[2]];
263
+ });
264
+ if (!ceilingContainsFootprint(ceiling.polygon, footprint) ||
265
+ ceiling.holes.some((hole) => polygonsOverlap(hole, footprint)))
266
+ throw new Error('The hanging design must fit inside the ceiling, outside its holes');
267
+ }
268
+ else if (node.recipe.mounting?.attachTo === 'wall-side' && !awaitingHost) {
269
+ const wall = node.wallId ? nodes[node.wallId] : undefined;
270
+ if (wall?.type !== 'wall' || node.parentId !== wall.id)
271
+ throw new Error('This design needs a wall host');
272
+ if (wall.curveOffset)
273
+ throw new Error('Curved wall mounting is not supported yet');
274
+ if (node.rotation.some((v) => Math.abs(v) > 1e-8))
275
+ throw new Error('Move the item onto a wall face or press R to flip it');
276
+ const pose = proceduralLocalPose(node, nodes);
277
+ const b = boundsOf(boxCorners(evaluation.min, evaluation.max).map((p) => transformPoint(frame(pose.position, pose.rotation), p)));
278
+ const length = Math.hypot(wall.end[0] - wall.start[0], wall.end[1] - wall.start[1]);
279
+ const level = wall.parentId ? nodes[wall.parentId] : undefined;
280
+ const height = wall.height ?? (level?.type === 'level' ? level.height : 2.5) ?? 2.5;
281
+ if (b.min[0] < -1e-6 ||
282
+ b.max[0] > length + 1e-6 ||
283
+ b.min[1] < -1e-6 ||
284
+ b.max[1] > height + 1e-6 ||
285
+ node.position[2] < 0)
286
+ throw new Error('The mounted item must fit on the wall');
287
+ }
288
+ else if (node.wallId ||
289
+ (node.parentId && ['wall', 'ceiling'].includes(nodes[node.parentId]?.type ?? '')))
290
+ throw new Error('A floor design cannot be attached to a wall or ceiling');
291
+ const regions = new Map();
292
+ for (const childId of node.children) {
293
+ const child = nodes[childId];
294
+ if (!child || child.parentId !== node.id)
295
+ throw new Error('Invalid hosted child link');
296
+ if (!(isProceduralItem(child) || child.type === 'item'))
297
+ throw new Error('Unsupported hosted child');
298
+ if (node.attachments[childId] === undefined)
299
+ continue;
300
+ const surface = evaluation.surfaces.find((s) => s.id === node.attachments[childId]);
301
+ if (!surface)
302
+ throw new Error('Choose a named attachment surface for the child');
303
+ const b = attachmentBounds(child);
304
+ if (!surfaceRegionContainsPoint({ kind: 'rect', size: [surface.size[0] / 2, surface.size[1] / 2] }, [(b.min[0] + b.max[0]) / 2, (b.min[2] + b.max[2]) / 2]) ||
305
+ Math.abs(b.min[1]) > 1e-6)
306
+ throw new Error(`The hosted item does not fit on ${surface.label}`);
307
+ // A fresh duplicate initially overlaps its source; only committed children occupy a surface.
308
+ if (child.metadata?.isNew === true)
309
+ continue;
310
+ const occupied = regions.get(surface.id) ?? [];
311
+ if (occupied.some((a) => attachmentRegionsOverlap(a, b)))
312
+ throw new Error(`Another item occupies ${surface.label}`);
313
+ occupied.push(b);
314
+ regions.set(surface.id, occupied);
315
+ }
316
+ }
317
+ export function queryProceduralItem(node, nodes) {
318
+ const e = evaluateRecipe(node.recipe, node.parameters), f = nodeLevelFrame(node.id, nodes[node.id] === node ? nodes : { ...nodes, [node.id]: node });
319
+ const bounds = boundsOf(boxCorners(e.min, e.max).map((p) => transformPoint(f, p)));
320
+ return {
321
+ id: node.id,
322
+ kind: node.type,
323
+ classification: node.recipe.classification ?? null,
324
+ hostId: node.parentId,
325
+ wallId: node.wallId ?? null,
326
+ parameters: e.parameters,
327
+ localBounds: { min: e.min, max: e.max, dimensions: e.dimensions },
328
+ levelBounds: bounds,
329
+ frame: f,
330
+ footprint: [
331
+ [bounds.min[0], bounds.min[2]],
332
+ [bounds.max[0], bounds.min[2]],
333
+ [bounds.max[0], bounds.max[2]],
334
+ [bounds.min[0], bounds.max[2]],
335
+ ],
336
+ surfaces: e.surfaces.map((s) => ({
337
+ ...s,
338
+ frame: composeFrames(f, frame(s.position, s.rotation)),
339
+ })),
340
+ children: node.children,
341
+ };
342
+ }
@@ -0,0 +1,144 @@
1
+ import { z } from 'zod';
2
+ export type Expr = number | string | {
3
+ op: 'add' | 'sub' | 'mul' | 'div' | 'min' | 'max';
4
+ args: Expr[];
5
+ } | {
6
+ op: 'floor' | 'ceil' | 'round' | 'abs';
7
+ args: [Expr];
8
+ } | {
9
+ op: 'mod';
10
+ args: [Expr, Expr];
11
+ };
12
+ export type Vec3 = [number, number, number];
13
+ export declare const RecipeSchema: z.ZodObject<{
14
+ version: z.ZodLiteral<1>;
15
+ name: z.ZodString;
16
+ description: z.ZodString;
17
+ classification: z.ZodOptional<z.ZodObject<{
18
+ category: z.ZodString;
19
+ functionTags: z.ZodArray<z.ZodString>;
20
+ tags: z.ZodArray<z.ZodString>;
21
+ }, z.core.$strict>>;
22
+ mounting: z.ZodOptional<z.ZodObject<{
23
+ attachTo: z.ZodEnum<{
24
+ ceiling: "ceiling";
25
+ "wall-side": "wall-side";
26
+ }>;
27
+ reference: z.ZodString;
28
+ }, z.core.$strict>>;
29
+ surfaces: z.ZodOptional<z.ZodArray<z.ZodObject<{
30
+ id: z.ZodString;
31
+ label: z.ZodString;
32
+ part: z.ZodOptional<z.ZodString>;
33
+ position: z.ZodTuple<[z.ZodType<Expr, unknown, z.core.$ZodTypeInternals<Expr, unknown>>, z.ZodType<Expr, unknown, z.core.$ZodTypeInternals<Expr, unknown>>, z.ZodType<Expr, unknown, z.core.$ZodTypeInternals<Expr, unknown>>], null>;
34
+ rotation: z.ZodOptional<z.ZodTuple<[z.ZodType<Expr, unknown, z.core.$ZodTypeInternals<Expr, unknown>>, z.ZodType<Expr, unknown, z.core.$ZodTypeInternals<Expr, unknown>>, z.ZodType<Expr, unknown, z.core.$ZodTypeInternals<Expr, unknown>>], null>>;
35
+ size: z.ZodTuple<[z.ZodType<Expr, unknown, z.core.$ZodTypeInternals<Expr, unknown>>, z.ZodType<Expr, unknown, z.core.$ZodTypeInternals<Expr, unknown>>], null>;
36
+ }, z.core.$strict>>>;
37
+ parameters: z.ZodArray<z.ZodObject<{
38
+ id: z.ZodString;
39
+ label: z.ZodString;
40
+ default: z.ZodNumber;
41
+ min: z.ZodNumber;
42
+ max: z.ZodNumber;
43
+ step: z.ZodNumber;
44
+ unit: z.ZodEnum<{
45
+ count: "count";
46
+ m: "m";
47
+ rad: "rad";
48
+ }>;
49
+ part: z.ZodOptional<z.ZodString>;
50
+ axis: z.ZodOptional<z.ZodEnum<{
51
+ x: "x";
52
+ y: "y";
53
+ z: "z";
54
+ }>>;
55
+ }, z.core.$strict>>;
56
+ slots: z.ZodArray<z.ZodObject<{
57
+ id: z.ZodString;
58
+ label: z.ZodString;
59
+ color: z.ZodString;
60
+ finish: z.ZodOptional<z.ZodEnum<{
61
+ wood: "wood";
62
+ glass: "glass";
63
+ metal: "metal";
64
+ }>>;
65
+ }, z.core.$strict>>;
66
+ parts: z.ZodArray<z.ZodObject<{
67
+ id: z.ZodString;
68
+ label: z.ZodString;
69
+ count: z.ZodType<Expr, unknown, z.core.$ZodTypeInternals<Expr, unknown>>;
70
+ shapes: z.ZodArray<z.ZodObject<{
71
+ id: z.ZodString;
72
+ primitive: z.ZodEnum<{
73
+ box: "box";
74
+ roundedBox: "roundedBox";
75
+ cylinder: "cylinder";
76
+ }>;
77
+ slot: z.ZodString;
78
+ size: z.ZodTuple<[z.ZodType<Expr, unknown, z.core.$ZodTypeInternals<Expr, unknown>>, z.ZodType<Expr, unknown, z.core.$ZodTypeInternals<Expr, unknown>>, z.ZodType<Expr, unknown, z.core.$ZodTypeInternals<Expr, unknown>>], null>;
79
+ position: z.ZodTuple<[z.ZodType<Expr, unknown, z.core.$ZodTypeInternals<Expr, unknown>>, z.ZodType<Expr, unknown, z.core.$ZodTypeInternals<Expr, unknown>>, z.ZodType<Expr, unknown, z.core.$ZodTypeInternals<Expr, unknown>>], null>;
80
+ rotation: z.ZodOptional<z.ZodTuple<[z.ZodType<Expr, unknown, z.core.$ZodTypeInternals<Expr, unknown>>, z.ZodType<Expr, unknown, z.core.$ZodTypeInternals<Expr, unknown>>, z.ZodType<Expr, unknown, z.core.$ZodTypeInternals<Expr, unknown>>], null>>;
81
+ radius: z.ZodOptional<z.ZodType<Expr, unknown, z.core.$ZodTypeInternals<Expr, unknown>>>;
82
+ support: z.ZodOptional<z.ZodBoolean>;
83
+ }, z.core.$strict>>;
84
+ }, z.core.$strict>>;
85
+ constraints: z.ZodArray<z.ZodObject<{
86
+ left: z.ZodType<Expr, unknown, z.core.$ZodTypeInternals<Expr, unknown>>;
87
+ relation: z.ZodEnum<{
88
+ lte: "lte";
89
+ gte: "gte";
90
+ }>;
91
+ right: z.ZodType<Expr, unknown, z.core.$ZodTypeInternals<Expr, unknown>>;
92
+ message: z.ZodString;
93
+ }, z.core.$strict>>;
94
+ }, z.core.$strict>;
95
+ export type Recipe = z.infer<typeof RecipeSchema>;
96
+ export type EvaluatedShape = {
97
+ id: string;
98
+ partId: string;
99
+ primitive: 'box' | 'roundedBox' | 'cylinder';
100
+ slot: string;
101
+ size: Vec3;
102
+ position: Vec3;
103
+ rotation: Vec3;
104
+ radius: number;
105
+ };
106
+ export type Surface = {
107
+ id: string;
108
+ label: string;
109
+ position: Vec3;
110
+ rotation: Vec3;
111
+ normal: Vec3;
112
+ size: [number, number];
113
+ };
114
+ export type Evaluation = {
115
+ shapes: EvaluatedShape[];
116
+ surfaces: Surface[];
117
+ min: Vec3;
118
+ max: Vec3;
119
+ dimensions: Vec3;
120
+ parameters: Record<string, number>;
121
+ triangles: number;
122
+ };
123
+ export declare const RECIPE_LIMITS: {
124
+ readonly bytes: 131072;
125
+ readonly depth: 24;
126
+ readonly expressions: 50000;
127
+ readonly shapes: 256;
128
+ readonly triangles: 100000;
129
+ readonly dimension: 30;
130
+ };
131
+ export declare function parseRecipe(input: unknown): Recipe;
132
+ export declare function evaluateRecipe(recipe: Recipe, values?: Record<string, number>): Evaluation;
133
+ export declare function sweepRecipe(recipe: Recipe): ({
134
+ index: number;
135
+ values: Record<string, number>;
136
+ valid: boolean;
137
+ error: null;
138
+ } | {
139
+ index: number;
140
+ values: Record<string, number>;
141
+ valid: boolean;
142
+ error: string;
143
+ })[];
144
+ //# sourceMappingURL=recipe.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recipe.d.ts","sourceRoot":"","sources":["../../src/procedural-items/recipe.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAGvB,MAAM,MAAM,IAAI,GACZ,MAAM,GACN,MAAM,GACN;IAAE,EAAE,EAAE,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,CAAC;IAAC,IAAI,EAAE,IAAI,EAAE,CAAA;CAAE,GACnE;IAAE,EAAE,EAAE,OAAO,GAAG,MAAM,GAAG,OAAO,GAAG,KAAK,CAAC;IAAC,IAAI,EAAE,CAAC,IAAI,CAAC,CAAA;CAAE,GACxD;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,IAAI,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;CAAE,CAAA;AACrC,MAAM,MAAM,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;AAsB3C,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAyFvB,CAAA;AACF,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAA;AACjD,MAAM,MAAM,cAAc,GAAG;IAC3B,EAAE,EAAE,MAAM,CAAA;IACV,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,KAAK,GAAG,YAAY,GAAG,UAAU,CAAA;IAC5C,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,IAAI,CAAA;IACV,QAAQ,EAAE,IAAI,CAAA;IACd,QAAQ,EAAE,IAAI,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;CACf,CAAA;AACD,MAAM,MAAM,OAAO,GAAG;IACpB,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,IAAI,CAAA;IACd,QAAQ,EAAE,IAAI,CAAA;IACd,MAAM,EAAE,IAAI,CAAA;IACZ,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CACvB,CAAA;AACD,MAAM,MAAM,UAAU,GAAG;IACvB,MAAM,EAAE,cAAc,EAAE,CAAA;IACxB,QAAQ,EAAE,OAAO,EAAE,CAAA;IACnB,GAAG,EAAE,IAAI,CAAA;IACT,GAAG,EAAE,IAAI,CAAA;IACT,UAAU,EAAE,IAAI,CAAA;IAChB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAClC,SAAS,EAAE,MAAM,CAAA;CAClB,CAAA;AACD,eAAO,MAAM,aAAa;;;;;;;CAOhB,CAAA;AAYV,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAsClD;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,GAAG,UAAU,CAqL9F;AAED,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM;;;;;;;;;;KA0BzC"}