@pascal-app/core 1.0.4 → 1.0.5

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 (866) hide show
  1. package/dist/agent-operations/__fixtures__/add-object-cases.d.ts +102 -90
  2. package/dist/agent-operations/__fixtures__/add-object-cases.d.ts.map +1 -1
  3. package/dist/agent-operations/__fixtures__/add-object-cases.js +301 -1
  4. package/dist/agent-operations/__fixtures__/add-stair-cases.d.ts +3 -0
  5. package/dist/agent-operations/__fixtures__/add-stair-cases.d.ts.map +1 -0
  6. package/dist/agent-operations/__fixtures__/add-stair-cases.js +176 -0
  7. package/dist/agent-operations/__fixtures__/build-room-cases.d.ts.map +1 -1
  8. package/dist/agent-operations/__fixtures__/build-room-cases.js +410 -40
  9. package/dist/agent-operations/__fixtures__/cases.d.ts +18 -3
  10. package/dist/agent-operations/__fixtures__/cases.d.ts.map +1 -1
  11. package/dist/agent-operations/__fixtures__/cases.js +183 -4
  12. package/dist/agent-operations/__fixtures__/corner-window-cases.d.ts +3 -0
  13. package/dist/agent-operations/__fixtures__/corner-window-cases.d.ts.map +1 -0
  14. package/dist/agent-operations/__fixtures__/corner-window-cases.js +155 -0
  15. package/dist/agent-operations/__fixtures__/design-brief-cases.d.ts +14 -0
  16. package/dist/agent-operations/__fixtures__/design-brief-cases.d.ts.map +1 -0
  17. package/dist/agent-operations/__fixtures__/design-brief-cases.js +709 -0
  18. package/dist/agent-operations/__fixtures__/finish-cases.d.ts +7 -0
  19. package/dist/agent-operations/__fixtures__/finish-cases.d.ts.map +1 -0
  20. package/dist/agent-operations/__fixtures__/finish-cases.js +758 -0
  21. package/dist/agent-operations/__fixtures__/lot-info-cases.d.ts +3 -0
  22. package/dist/agent-operations/__fixtures__/lot-info-cases.d.ts.map +1 -0
  23. package/dist/agent-operations/__fixtures__/lot-info-cases.js +370 -0
  24. package/dist/agent-operations/__fixtures__/merge-windows-cases.d.ts +3 -0
  25. package/dist/agent-operations/__fixtures__/merge-windows-cases.d.ts.map +1 -0
  26. package/dist/agent-operations/__fixtures__/merge-windows-cases.js +321 -0
  27. package/dist/agent-operations/__fixtures__/native-materials.d.ts +2237 -0
  28. package/dist/agent-operations/__fixtures__/native-materials.d.ts.map +1 -0
  29. package/dist/agent-operations/__fixtures__/native-materials.js +82 -0
  30. package/dist/agent-operations/__fixtures__/node-read-cases.d.ts +4 -0
  31. package/dist/agent-operations/__fixtures__/node-read-cases.d.ts.map +1 -0
  32. package/dist/agent-operations/__fixtures__/node-read-cases.js +639 -0
  33. package/dist/agent-operations/__fixtures__/notation-cases.d.ts +24 -0
  34. package/dist/agent-operations/__fixtures__/notation-cases.d.ts.map +1 -0
  35. package/dist/agent-operations/__fixtures__/notation-cases.js +356 -0
  36. package/dist/agent-operations/__fixtures__/place-items-cases.d.ts.map +1 -1
  37. package/dist/agent-operations/__fixtures__/place-items-cases.js +80 -2
  38. package/dist/agent-operations/__fixtures__/roof-bearing-cases.d.ts +19726 -0
  39. package/dist/agent-operations/__fixtures__/roof-bearing-cases.d.ts.map +1 -0
  40. package/dist/agent-operations/__fixtures__/roof-bearing-cases.js +106 -0
  41. package/dist/agent-operations/__fixtures__/roof-cases.d.ts +9 -0
  42. package/dist/agent-operations/__fixtures__/roof-cases.d.ts.map +1 -0
  43. package/dist/agent-operations/__fixtures__/roof-cases.js +382 -0
  44. package/dist/agent-operations/__fixtures__/room-cases.d.ts +2 -1
  45. package/dist/agent-operations/__fixtures__/room-cases.d.ts.map +1 -1
  46. package/dist/agent-operations/__fixtures__/room-cases.js +136 -1
  47. package/dist/agent-operations/__fixtures__/scene-check-cases.d.ts +4 -0
  48. package/dist/agent-operations/__fixtures__/scene-check-cases.d.ts.map +1 -0
  49. package/dist/agent-operations/__fixtures__/scene-check-cases.js +417 -0
  50. package/dist/agent-operations/__fixtures__/search-assets-cases.d.ts.map +1 -1
  51. package/dist/agent-operations/__fixtures__/search-assets-cases.js +15 -3
  52. package/dist/agent-operations/__fixtures__/site-cases.d.ts +290 -0
  53. package/dist/agent-operations/__fixtures__/site-cases.d.ts.map +1 -0
  54. package/dist/agent-operations/__fixtures__/site-cases.js +780 -0
  55. package/dist/agent-operations/__fixtures__/structure-cases.d.ts +1 -0
  56. package/dist/agent-operations/__fixtures__/structure-cases.d.ts.map +1 -1
  57. package/dist/agent-operations/__fixtures__/structure-cases.js +630 -3
  58. package/dist/agent-operations/__fixtures__/verify-scene-cases.d.ts +311 -1
  59. package/dist/agent-operations/__fixtures__/verify-scene-cases.d.ts.map +1 -1
  60. package/dist/agent-operations/__fixtures__/verify-scene-cases.js +59 -11
  61. package/dist/agent-operations/__fixtures__/view-assets-cases.d.ts +3 -0
  62. package/dist/agent-operations/__fixtures__/view-assets-cases.d.ts.map +1 -0
  63. package/dist/agent-operations/__fixtures__/view-assets-cases.js +155 -0
  64. package/dist/agent-operations/__fixtures__/view-scene-cases.d.ts +50 -0
  65. package/dist/agent-operations/__fixtures__/view-scene-cases.d.ts.map +1 -0
  66. package/dist/agent-operations/__fixtures__/view-scene-cases.js +425 -0
  67. package/dist/agent-operations/achieved.d.ts +5 -0
  68. package/dist/agent-operations/achieved.d.ts.map +1 -1
  69. package/dist/agent-operations/achieved.js +21 -1
  70. package/dist/agent-operations/add-column.d.ts.map +1 -1
  71. package/dist/agent-operations/add-column.js +3 -1
  72. package/dist/agent-operations/add-fence.d.ts +18 -0
  73. package/dist/agent-operations/add-fence.d.ts.map +1 -0
  74. package/dist/agent-operations/add-fence.js +48 -0
  75. package/dist/agent-operations/add-level.d.ts +4 -1
  76. package/dist/agent-operations/add-level.d.ts.map +1 -1
  77. package/dist/agent-operations/add-level.js +48 -12
  78. package/dist/agent-operations/add-object.d.ts +38 -9
  79. package/dist/agent-operations/add-object.d.ts.map +1 -1
  80. package/dist/agent-operations/add-object.js +172 -11
  81. package/dist/agent-operations/add-wall.d.ts +1 -3
  82. package/dist/agent-operations/add-wall.d.ts.map +1 -1
  83. package/dist/agent-operations/add-wall.js +35 -9
  84. package/dist/agent-operations/apply-changes.d.ts +7 -1
  85. package/dist/agent-operations/apply-changes.d.ts.map +1 -1
  86. package/dist/agent-operations/apply-changes.js +54 -22
  87. package/dist/agent-operations/apply-outcome.d.ts +6 -0
  88. package/dist/agent-operations/apply-outcome.d.ts.map +1 -1
  89. package/dist/agent-operations/apply-outcome.js +23 -8
  90. package/dist/agent-operations/asset-views.d.ts +75 -0
  91. package/dist/agent-operations/asset-views.d.ts.map +1 -0
  92. package/dist/agent-operations/asset-views.js +234 -0
  93. package/dist/agent-operations/author-scene.d.ts +157 -0
  94. package/dist/agent-operations/author-scene.d.ts.map +1 -0
  95. package/dist/agent-operations/author-scene.js +1076 -0
  96. package/dist/agent-operations/authored-scene-merge.d.ts +4 -0
  97. package/dist/agent-operations/authored-scene-merge.d.ts.map +1 -0
  98. package/dist/agent-operations/authored-scene-merge.js +96 -0
  99. package/dist/agent-operations/batch.d.ts +22 -0
  100. package/dist/agent-operations/batch.d.ts.map +1 -0
  101. package/dist/agent-operations/batch.js +104 -0
  102. package/dist/agent-operations/ceiling-object-observations.d.ts +31 -0
  103. package/dist/agent-operations/ceiling-object-observations.d.ts.map +1 -0
  104. package/dist/agent-operations/ceiling-object-observations.js +111 -0
  105. package/dist/agent-operations/corner-window.d.ts +19 -0
  106. package/dist/agent-operations/corner-window.d.ts.map +1 -0
  107. package/dist/agent-operations/corner-window.js +84 -0
  108. package/dist/agent-operations/create-roof.d.ts +32 -0
  109. package/dist/agent-operations/create-roof.d.ts.map +1 -0
  110. package/dist/agent-operations/create-roof.js +304 -0
  111. package/dist/agent-operations/create-room.d.ts +2 -0
  112. package/dist/agent-operations/create-room.d.ts.map +1 -1
  113. package/dist/agent-operations/create-room.js +73 -5
  114. package/dist/agent-operations/create-stair.d.ts +6 -28
  115. package/dist/agent-operations/create-stair.d.ts.map +1 -1
  116. package/dist/agent-operations/create-stair.js +187 -104
  117. package/dist/agent-operations/design-brief.d.ts +38 -0
  118. package/dist/agent-operations/design-brief.d.ts.map +1 -0
  119. package/dist/agent-operations/design-brief.js +300 -0
  120. package/dist/agent-operations/designs.d.ts +24 -0
  121. package/dist/agent-operations/designs.d.ts.map +1 -0
  122. package/dist/agent-operations/designs.js +48 -0
  123. package/dist/agent-operations/door-clearance.d.ts +16 -1
  124. package/dist/agent-operations/door-clearance.d.ts.map +1 -1
  125. package/dist/agent-operations/door-clearance.js +61 -4
  126. package/dist/agent-operations/duplicate-level.d.ts.map +1 -1
  127. package/dist/agent-operations/duplicate-level.js +2 -1
  128. package/dist/agent-operations/find-by-type.d.ts +14 -7
  129. package/dist/agent-operations/find-by-type.d.ts.map +1 -1
  130. package/dist/agent-operations/find-by-type.js +266 -43
  131. package/dist/agent-operations/furnish-room.d.ts +22 -1
  132. package/dist/agent-operations/furnish-room.d.ts.map +1 -1
  133. package/dist/agent-operations/furnish-room.js +66 -19
  134. package/dist/agent-operations/furniture-kind.d.ts +22 -0
  135. package/dist/agent-operations/furniture-kind.d.ts.map +1 -0
  136. package/dist/agent-operations/furniture-kind.js +69 -0
  137. package/dist/agent-operations/get-node.d.ts +5 -2
  138. package/dist/agent-operations/get-node.d.ts.map +1 -1
  139. package/dist/agent-operations/get-node.js +82 -10
  140. package/dist/agent-operations/hosted-services.d.ts +2 -1
  141. package/dist/agent-operations/hosted-services.d.ts.map +1 -1
  142. package/dist/agent-operations/index.d.ts +281 -69
  143. package/dist/agent-operations/index.d.ts.map +1 -1
  144. package/dist/agent-operations/index.js +66 -5
  145. package/dist/agent-operations/item-space.d.ts +22 -0
  146. package/dist/agent-operations/item-space.d.ts.map +1 -0
  147. package/dist/agent-operations/item-space.js +69 -0
  148. package/dist/agent-operations/layout-clearance.d.ts +52 -3
  149. package/dist/agent-operations/layout-clearance.d.ts.map +1 -1
  150. package/dist/agent-operations/layout-clearance.js +340 -30
  151. package/dist/agent-operations/level-height-fill.d.ts +12 -0
  152. package/dist/agent-operations/level-height-fill.d.ts.map +1 -0
  153. package/dist/agent-operations/level-height-fill.js +59 -0
  154. package/dist/agent-operations/level-reads.d.ts +5 -1
  155. package/dist/agent-operations/level-reads.d.ts.map +1 -1
  156. package/dist/agent-operations/level-reads.js +10 -3
  157. package/dist/agent-operations/list-levels.d.ts.map +1 -1
  158. package/dist/agent-operations/list-levels.js +23 -0
  159. package/dist/agent-operations/material-preset.d.ts.map +1 -1
  160. package/dist/agent-operations/material-preset.js +3 -9
  161. package/dist/agent-operations/material-refs.d.ts +7 -1
  162. package/dist/agent-operations/material-refs.d.ts.map +1 -1
  163. package/dist/agent-operations/material-refs.js +10 -5
  164. package/dist/agent-operations/merge-windows.d.ts +6 -0
  165. package/dist/agent-operations/merge-windows.d.ts.map +1 -0
  166. package/dist/agent-operations/merge-windows.js +27 -0
  167. package/dist/agent-operations/move-roofs.d.ts +9 -0
  168. package/dist/agent-operations/move-roofs.d.ts.map +1 -0
  169. package/dist/agent-operations/move-roofs.js +29 -0
  170. package/dist/agent-operations/paint.d.ts +2 -1
  171. package/dist/agent-operations/paint.d.ts.map +1 -1
  172. package/dist/agent-operations/paint.js +163 -53
  173. package/dist/agent-operations/photo-elevation.d.ts +155 -0
  174. package/dist/agent-operations/photo-elevation.d.ts.map +1 -0
  175. package/dist/agent-operations/photo-elevation.js +761 -0
  176. package/dist/agent-operations/place-in-room.d.ts +29 -0
  177. package/dist/agent-operations/place-in-room.d.ts.map +1 -0
  178. package/dist/agent-operations/place-in-room.js +403 -0
  179. package/dist/agent-operations/place-items.d.ts.map +1 -1
  180. package/dist/agent-operations/place-items.js +15 -2
  181. package/dist/agent-operations/plan-geometry.d.ts.map +1 -1
  182. package/dist/agent-operations/plan-geometry.js +3 -0
  183. package/dist/agent-operations/point-context.d.ts +139 -0
  184. package/dist/agent-operations/point-context.d.ts.map +1 -0
  185. package/dist/agent-operations/point-context.js +1 -0
  186. package/dist/agent-operations/project-files.d.ts +9 -0
  187. package/dist/agent-operations/project-files.d.ts.map +1 -0
  188. package/dist/agent-operations/project-files.js +25 -0
  189. package/dist/agent-operations/record-made.d.ts +18 -0
  190. package/dist/agent-operations/record-made.d.ts.map +1 -0
  191. package/dist/agent-operations/record-made.js +28 -0
  192. package/dist/agent-operations/roof-footprint.d.ts +24 -0
  193. package/dist/agent-operations/roof-footprint.d.ts.map +1 -0
  194. package/dist/agent-operations/roof-footprint.js +242 -0
  195. package/dist/agent-operations/roof-writes.d.ts +20 -0
  196. package/dist/agent-operations/roof-writes.d.ts.map +1 -0
  197. package/dist/agent-operations/roof-writes.js +165 -0
  198. package/dist/agent-operations/room-findings.d.ts +54 -0
  199. package/dist/agent-operations/room-findings.d.ts.map +1 -0
  200. package/dist/agent-operations/room-findings.js +143 -0
  201. package/dist/agent-operations/room-floor-script.d.ts +23 -0
  202. package/dist/agent-operations/room-floor-script.d.ts.map +1 -0
  203. package/dist/agent-operations/room-floor-script.js +54 -0
  204. package/dist/agent-operations/room-structure.d.ts +2 -2
  205. package/dist/agent-operations/room-structure.d.ts.map +1 -1
  206. package/dist/agent-operations/scene-checkpoint.d.ts +94 -0
  207. package/dist/agent-operations/scene-checkpoint.d.ts.map +1 -0
  208. package/dist/agent-operations/scene-checkpoint.js +176 -0
  209. package/dist/agent-operations/scene-queries.d.ts +3750 -3319
  210. package/dist/agent-operations/scene-queries.d.ts.map +1 -1
  211. package/dist/agent-operations/scene-queries.js +13 -23
  212. package/dist/agent-operations/scene-review.d.ts +52 -0
  213. package/dist/agent-operations/scene-review.d.ts.map +1 -0
  214. package/dist/agent-operations/scene-review.js +106 -0
  215. package/dist/agent-operations/scene-view.d.ts +82 -15
  216. package/dist/agent-operations/scene-view.d.ts.map +1 -1
  217. package/dist/agent-operations/scene-view.js +408 -51
  218. package/dist/agent-operations/search-assets.d.ts +2 -2
  219. package/dist/agent-operations/search-assets.d.ts.map +1 -1
  220. package/dist/agent-operations/search-assets.js +4 -3
  221. package/dist/agent-operations/search-materials.d.ts +9 -3
  222. package/dist/agent-operations/search-materials.d.ts.map +1 -1
  223. package/dist/agent-operations/search-materials.js +83 -29
  224. package/dist/agent-operations/set-checkpoint.d.ts +9 -0
  225. package/dist/agent-operations/set-checkpoint.d.ts.map +1 -0
  226. package/dist/agent-operations/set-checkpoint.js +31 -0
  227. package/dist/agent-operations/set-ground-level.d.ts +12 -0
  228. package/dist/agent-operations/set-ground-level.d.ts.map +1 -0
  229. package/dist/agent-operations/set-ground-level.js +61 -0
  230. package/dist/agent-operations/site.d.ts +21 -0
  231. package/dist/agent-operations/site.d.ts.map +1 -0
  232. package/dist/agent-operations/site.js +123 -0
  233. package/dist/agent-operations/types.d.ts +66 -7
  234. package/dist/agent-operations/types.d.ts.map +1 -1
  235. package/dist/agent-operations/verify-scene.d.ts +39 -5
  236. package/dist/agent-operations/verify-scene.d.ts.map +1 -1
  237. package/dist/agent-operations/verify-scene.js +223 -44
  238. package/dist/agent-operations/wall-face-script.d.ts +28 -0
  239. package/dist/agent-operations/wall-face-script.d.ts.map +1 -0
  240. package/dist/agent-operations/wall-face-script.js +62 -0
  241. package/dist/agent-operations/wall-object-observations.d.ts +41 -0
  242. package/dist/agent-operations/wall-object-observations.d.ts.map +1 -0
  243. package/dist/agent-operations/wall-object-observations.js +249 -0
  244. package/dist/agent-operations/wall-opening.d.ts +23 -23
  245. package/dist/agent-operations/wall-opening.d.ts.map +1 -1
  246. package/dist/agent-operations/wall-skirting.d.ts +24 -0
  247. package/dist/agent-operations/wall-skirting.d.ts.map +1 -0
  248. package/dist/agent-operations/wall-skirting.js +85 -0
  249. package/dist/agent-tools/add-object.d.ts +11 -7
  250. package/dist/agent-tools/add-object.d.ts.map +1 -1
  251. package/dist/agent-tools/add-object.js +17 -11
  252. package/dist/agent-tools/assets.d.ts +8 -0
  253. package/dist/agent-tools/assets.d.ts.map +1 -1
  254. package/dist/agent-tools/assets.js +13 -1
  255. package/dist/agent-tools/author-scene.d.ts +651 -0
  256. package/dist/agent-tools/author-scene.d.ts.map +1 -0
  257. package/dist/agent-tools/author-scene.js +252 -0
  258. package/dist/agent-tools/batch.d.ts +25 -0
  259. package/dist/agent-tools/batch.d.ts.map +1 -0
  260. package/dist/agent-tools/batch.js +61 -0
  261. package/dist/agent-tools/checkpoints.d.ts +13 -0
  262. package/dist/agent-tools/checkpoints.d.ts.map +1 -0
  263. package/dist/agent-tools/checkpoints.js +16 -0
  264. package/dist/agent-tools/clear-scene.d.ts.map +1 -1
  265. package/dist/agent-tools/collections.d.ts +6 -6
  266. package/dist/agent-tools/collections.d.ts.map +1 -1
  267. package/dist/agent-tools/columns.d.ts +18 -18
  268. package/dist/agent-tools/columns.js +2 -2
  269. package/dist/agent-tools/corner-window.d.ts +46 -0
  270. package/dist/agent-tools/corner-window.d.ts.map +1 -0
  271. package/dist/agent-tools/corner-window.js +47 -0
  272. package/dist/agent-tools/create-room.d.ts +26 -25
  273. package/dist/agent-tools/create-room.d.ts.map +1 -1
  274. package/dist/agent-tools/create-room.js +11 -4
  275. package/dist/agent-tools/design-brief.d.ts +408 -0
  276. package/dist/agent-tools/design-brief.d.ts.map +1 -0
  277. package/dist/agent-tools/design-brief.js +149 -0
  278. package/dist/agent-tools/designs.d.ts +34 -0
  279. package/dist/agent-tools/designs.d.ts.map +1 -0
  280. package/dist/agent-tools/designs.js +50 -0
  281. package/dist/agent-tools/fences.d.ts +28 -0
  282. package/dist/agent-tools/fences.d.ts.map +1 -0
  283. package/dist/agent-tools/fences.js +31 -0
  284. package/dist/agent-tools/find-by-type.d.ts +8 -1
  285. package/dist/agent-tools/find-by-type.d.ts.map +1 -1
  286. package/dist/agent-tools/find-by-type.js +23 -2
  287. package/dist/agent-tools/furnish-room.d.ts +10 -8
  288. package/dist/agent-tools/furnish-room.d.ts.map +1 -1
  289. package/dist/agent-tools/furnish-room.js +3 -1
  290. package/dist/agent-tools/hosted-services.d.ts +177 -141
  291. package/dist/agent-tools/hosted-services.d.ts.map +1 -1
  292. package/dist/agent-tools/hosted-services.js +47 -14
  293. package/dist/agent-tools/index.d.ts +894 -215
  294. package/dist/agent-tools/index.d.ts.map +1 -1
  295. package/dist/agent-tools/index.js +47 -3
  296. package/dist/agent-tools/levels.d.ts +11 -3
  297. package/dist/agent-tools/levels.d.ts.map +1 -1
  298. package/dist/agent-tools/levels.js +16 -5
  299. package/dist/agent-tools/measurement.d.ts +38 -20
  300. package/dist/agent-tools/measurement.d.ts.map +1 -1
  301. package/dist/agent-tools/measurement.js +117 -67
  302. package/dist/agent-tools/merge-windows.d.ts +10 -0
  303. package/dist/agent-tools/merge-windows.d.ts.map +1 -0
  304. package/dist/agent-tools/merge-windows.js +12 -0
  305. package/dist/agent-tools/nodes.d.ts.map +1 -1
  306. package/dist/agent-tools/nodes.js +1 -1
  307. package/dist/agent-tools/notation-inventory.d.ts +16 -0
  308. package/dist/agent-tools/notation-inventory.d.ts.map +1 -0
  309. package/dist/agent-tools/notation-inventory.js +105 -0
  310. package/dist/agent-tools/paint.d.ts +5 -5
  311. package/dist/agent-tools/paint.d.ts.map +1 -1
  312. package/dist/agent-tools/paint.js +1 -1
  313. package/dist/agent-tools/photo-elevation.d.ts +32 -0
  314. package/dist/agent-tools/photo-elevation.d.ts.map +1 -0
  315. package/dist/agent-tools/photo-elevation.js +73 -0
  316. package/dist/agent-tools/place-in-room.d.ts +35 -0
  317. package/dist/agent-tools/place-in-room.d.ts.map +1 -0
  318. package/dist/agent-tools/place-in-room.js +61 -0
  319. package/dist/agent-tools/place-items.d.ts +1 -1
  320. package/dist/agent-tools/place-items.js +2 -2
  321. package/dist/agent-tools/project-files.d.ts +189 -0
  322. package/dist/agent-tools/project-files.d.ts.map +1 -0
  323. package/dist/agent-tools/project-files.js +99 -0
  324. package/dist/agent-tools/refusal.d.ts.map +1 -1
  325. package/dist/agent-tools/retired.d.ts +21 -0
  326. package/dist/agent-tools/retired.d.ts.map +1 -0
  327. package/dist/agent-tools/retired.js +29 -0
  328. package/dist/agent-tools/roofs.d.ts +100 -0
  329. package/dist/agent-tools/roofs.d.ts.map +1 -0
  330. package/dist/agent-tools/roofs.js +96 -0
  331. package/dist/agent-tools/room-structure.d.ts +46 -38
  332. package/dist/agent-tools/room-structure.d.ts.map +1 -1
  333. package/dist/agent-tools/room-structure.js +30 -27
  334. package/dist/agent-tools/search-materials.d.ts +22 -3
  335. package/dist/agent-tools/search-materials.d.ts.map +1 -1
  336. package/dist/agent-tools/search-materials.js +13 -14
  337. package/dist/agent-tools/site.d.ts +27 -0
  338. package/dist/agent-tools/site.d.ts.map +1 -0
  339. package/dist/agent-tools/site.js +40 -0
  340. package/dist/agent-tools/sources.d.ts +12 -0
  341. package/dist/agent-tools/sources.d.ts.map +1 -0
  342. package/dist/agent-tools/sources.js +11 -0
  343. package/dist/agent-tools/stairs.d.ts +48 -28
  344. package/dist/agent-tools/stairs.d.ts.map +1 -1
  345. package/dist/agent-tools/stairs.js +65 -22
  346. package/dist/agent-tools/verify-scene.d.ts.map +1 -1
  347. package/dist/agent-tools/verify-scene.js +1 -1
  348. package/dist/agent-tools/view-scene.d.ts +50 -12
  349. package/dist/agent-tools/view-scene.d.ts.map +1 -1
  350. package/dist/agent-tools/view-scene.js +74 -31
  351. package/dist/agent-tools/wall-openings.d.ts +77 -73
  352. package/dist/agent-tools/wall-openings.d.ts.map +1 -1
  353. package/dist/agent-tools/wall-openings.js +9 -5
  354. package/dist/agent-tools/walls.d.ts +4 -4
  355. package/dist/agent-tools/walls.d.ts.map +1 -1
  356. package/dist/agent-tools/walls.js +7 -2
  357. package/dist/building/__fixtures__/wall-opening-cases.d.ts +454 -250
  358. package/dist/building/__fixtures__/wall-opening-cases.d.ts.map +1 -1
  359. package/dist/building/__fixtures__/wall-opening-cases.js +62 -2
  360. package/dist/building/corner-window.d.ts +56 -0
  361. package/dist/building/corner-window.d.ts.map +1 -0
  362. package/dist/building/corner-window.js +179 -0
  363. package/dist/building/ground-level.d.ts +26 -0
  364. package/dist/building/ground-level.d.ts.map +1 -0
  365. package/dist/building/ground-level.js +58 -0
  366. package/dist/building/index.d.ts +5 -0
  367. package/dist/building/index.d.ts.map +1 -1
  368. package/dist/building/index.js +5 -0
  369. package/dist/building/level-duplication.d.ts +7472 -6613
  370. package/dist/building/level-duplication.d.ts.map +1 -1
  371. package/dist/building/level-duplication.js +18 -4
  372. package/dist/building/level-insertion.d.ts +55 -0
  373. package/dist/building/level-insertion.d.ts.map +1 -0
  374. package/dist/building/level-insertion.js +35 -0
  375. package/dist/building/merge-windows.d.ts +58 -0
  376. package/dist/building/merge-windows.d.ts.map +1 -0
  377. package/dist/building/merge-windows.js +189 -0
  378. package/dist/building/opening-style-presets.d.ts +2 -2
  379. package/dist/building/opening-style-presets.d.ts.map +1 -1
  380. package/dist/building/photo-elevation.d.ts +125 -0
  381. package/dist/building/photo-elevation.d.ts.map +1 -0
  382. package/dist/building/photo-elevation.js +404 -0
  383. package/dist/building/wall-gaps.d.ts +13 -0
  384. package/dist/building/wall-gaps.d.ts.map +1 -0
  385. package/dist/building/wall-gaps.js +158 -0
  386. package/dist/building/wall-openings.d.ts +154 -119
  387. package/dist/building/wall-openings.d.ts.map +1 -1
  388. package/dist/building/wall-openings.js +37 -9
  389. package/dist/capture/schema.d.ts +22 -22
  390. package/dist/capture/source.d.ts.map +1 -1
  391. package/dist/capture/source.js +1 -1
  392. package/dist/commands/structure/create-zone.d.ts +12 -1
  393. package/dist/commands/structure/create-zone.d.ts.map +1 -1
  394. package/dist/commands/structure/create-zone.js +49 -0
  395. package/dist/commands/structure/divide-zone.d.ts +3 -3
  396. package/dist/commands/structure/index.d.ts +1 -1
  397. package/dist/commands/structure/index.d.ts.map +1 -1
  398. package/dist/commands/structure/index.js +1 -1
  399. package/dist/commands/structure/set-floor-foundation.d.ts +6 -6
  400. package/dist/commands/structure/set-zone-intent.d.ts +4 -0
  401. package/dist/commands/structure/set-zone-intent.d.ts.map +1 -1
  402. package/dist/commands/structure/set-zone-intent.js +19 -0
  403. package/dist/commands/structure/shared.d.ts +3642 -3213
  404. package/dist/commands/structure/shared.d.ts.map +1 -1
  405. package/dist/commands/structure/zone-wall-merge.d.ts +4149 -3334
  406. package/dist/commands/structure/zone-wall-merge.d.ts.map +1 -1
  407. package/dist/contracts/reference-inventory.d.ts.map +1 -1
  408. package/dist/contracts/reference-inventory.js +106 -26
  409. package/dist/events/bus.d.ts +22 -3
  410. package/dist/events/bus.d.ts.map +1 -1
  411. package/dist/events/capture-sessions.d.ts +5 -0
  412. package/dist/events/capture-sessions.d.ts.map +1 -0
  413. package/dist/events/capture-sessions.js +31 -0
  414. package/dist/hooks/scene-registry/scene-registry.d.ts.map +1 -1
  415. package/dist/hooks/spatial-grid/spatial-grid-manager.d.ts +1 -2
  416. package/dist/hooks/spatial-grid/spatial-grid-manager.d.ts.map +1 -1
  417. package/dist/hooks/spatial-grid/spatial-grid-manager.js +4 -6
  418. package/dist/hooks/spatial-grid/spatial-grid-sync.d.ts +3608 -3179
  419. package/dist/hooks/spatial-grid/spatial-grid-sync.d.ts.map +1 -1
  420. package/dist/hooks/spatial-grid/spatial-grid.d.ts.map +1 -1
  421. package/dist/hooks/spatial-grid/support-host-patch.d.ts.map +1 -1
  422. package/dist/hooks/spatial-grid/support-host-patch.js +11 -2
  423. package/dist/hooks/spatial-grid/use-spatial-query.d.ts +3 -3
  424. package/dist/hooks/spatial-grid/wall-spatial-grid.d.ts.map +1 -1
  425. package/dist/index.d.ts +37 -9
  426. package/dist/index.d.ts.map +1 -1
  427. package/dist/index.js +36 -9
  428. package/dist/lib/__fixtures__/mezzanine.d.ts +11800 -10132
  429. package/dist/lib/__fixtures__/mezzanine.d.ts.map +1 -1
  430. package/dist/lib/absorb-wall-separators.d.ts +3642 -3213
  431. package/dist/lib/absorb-wall-separators.d.ts.map +1 -1
  432. package/dist/lib/angle-accumulator.d.ts.map +1 -1
  433. package/dist/lib/artifact-store.d.ts.map +1 -1
  434. package/dist/lib/below-grade-footprints.d.ts +65 -0
  435. package/dist/lib/below-grade-footprints.d.ts.map +1 -0
  436. package/dist/lib/below-grade-footprints.js +181 -0
  437. package/dist/lib/building-footprint.d.ts +33 -0
  438. package/dist/lib/building-footprint.d.ts.map +1 -0
  439. package/dist/lib/building-footprint.js +89 -0
  440. package/dist/lib/corner-pair.d.ts +1129 -0
  441. package/dist/lib/corner-pair.d.ts.map +1 -0
  442. package/dist/lib/corner-pair.js +130 -0
  443. package/dist/lib/corner-snap.d.ts +54 -0
  444. package/dist/lib/corner-snap.d.ts.map +1 -0
  445. package/dist/lib/corner-snap.js +125 -0
  446. package/dist/lib/critically-damped.d.ts +11 -0
  447. package/dist/lib/critically-damped.d.ts.map +1 -0
  448. package/dist/lib/critically-damped.js +14 -0
  449. package/dist/lib/deepest-drawn.d.ts +18 -0
  450. package/dist/lib/deepest-drawn.d.ts.map +1 -0
  451. package/dist/lib/deepest-drawn.js +65 -0
  452. package/dist/lib/door-operation.d.ts +1 -1
  453. package/dist/lib/exterior-wall-loops.d.ts +17 -0
  454. package/dist/lib/exterior-wall-loops.d.ts.map +1 -0
  455. package/dist/lib/exterior-wall-loops.js +334 -0
  456. package/dist/lib/finish-script.d.ts +61 -0
  457. package/dist/lib/finish-script.d.ts.map +1 -0
  458. package/dist/lib/finish-script.js +86 -0
  459. package/dist/lib/floor-intent-changes.d.ts.map +1 -1
  460. package/dist/lib/floor-intent-changes.js +4 -4
  461. package/dist/lib/floor-plate-paint.d.ts +3 -1
  462. package/dist/lib/floor-plate-paint.d.ts.map +1 -1
  463. package/dist/lib/floor-plate-paint.js +24 -4
  464. package/dist/lib/floor-plates.d.ts +50 -50
  465. package/dist/lib/floor-script.d.ts +24 -0
  466. package/dist/lib/floor-script.d.ts.map +1 -0
  467. package/dist/lib/floor-script.js +51 -0
  468. package/dist/lib/foundation-construction.d.ts +73 -0
  469. package/dist/lib/foundation-construction.d.ts.map +1 -0
  470. package/dist/lib/foundation-construction.js +242 -0
  471. package/dist/lib/foundation-standard.d.ts +30 -0
  472. package/dist/lib/foundation-standard.d.ts.map +1 -0
  473. package/dist/lib/foundation-standard.js +30 -0
  474. package/dist/lib/foundation-wall.d.ts +36 -0
  475. package/dist/lib/foundation-wall.d.ts.map +1 -0
  476. package/dist/lib/foundation-wall.js +66 -0
  477. package/dist/lib/generic-foundation.d.ts +40 -0
  478. package/dist/lib/generic-foundation.d.ts.map +1 -0
  479. package/dist/lib/generic-foundation.js +200 -0
  480. package/dist/lib/geometry-script-node.d.ts +32 -3
  481. package/dist/lib/geometry-script-node.d.ts.map +1 -1
  482. package/dist/lib/geometry-script-node.js +26 -0
  483. package/dist/lib/grade-standing.d.ts +38 -0
  484. package/dist/lib/grade-standing.d.ts.map +1 -0
  485. package/dist/lib/grade-standing.js +137 -0
  486. package/dist/lib/ground-level.d.ts +20 -0
  487. package/dist/lib/ground-level.d.ts.map +1 -0
  488. package/dist/lib/ground-level.js +49 -0
  489. package/dist/lib/ground-over-part.d.ts +13 -0
  490. package/dist/lib/ground-over-part.d.ts.map +1 -0
  491. package/dist/lib/ground-over-part.js +94 -0
  492. package/dist/lib/ground-seat.d.ts +47 -0
  493. package/dist/lib/ground-seat.d.ts.map +1 -0
  494. package/dist/lib/ground-seat.js +61 -0
  495. package/dist/lib/ground-window.d.ts +39 -0
  496. package/dist/lib/ground-window.d.ts.map +1 -0
  497. package/dist/lib/ground-window.js +147 -0
  498. package/dist/lib/opening-floor-datum.d.ts.map +1 -1
  499. package/dist/lib/opening-floor-datum.js +2 -3
  500. package/dist/lib/own-floor-intent.d.ts.map +1 -1
  501. package/dist/lib/own-floor-intent.js +4 -4
  502. package/dist/lib/plate-surface.d.ts.map +1 -1
  503. package/dist/lib/plate-surface.js +3 -1
  504. package/dist/lib/point-ask.d.ts +9 -0
  505. package/dist/lib/point-ask.d.ts.map +1 -0
  506. package/dist/lib/point-ask.js +36 -0
  507. package/dist/lib/room-drawn-floor.d.ts +1 -1
  508. package/dist/lib/room-drawn-floor.d.ts.map +1 -1
  509. package/dist/lib/room-floor-feasibility.d.ts.map +1 -1
  510. package/dist/lib/room-floor-feasibility.js +3 -3
  511. package/dist/lib/room-graph.d.ts.map +1 -1
  512. package/dist/lib/room-graph.js +2 -0
  513. package/dist/lib/room-name.d.ts +2 -0
  514. package/dist/lib/room-name.d.ts.map +1 -1
  515. package/dist/lib/room-name.js +2 -0
  516. package/dist/lib/room-topology-index.d.ts.map +1 -1
  517. package/dist/lib/room-topology-index.js +1 -1
  518. package/dist/lib/room-zone-adoption.d.ts.map +1 -1
  519. package/dist/lib/script-inputs-key.d.ts +3 -0
  520. package/dist/lib/script-inputs-key.d.ts.map +1 -0
  521. package/dist/lib/script-inputs-key.js +13 -0
  522. package/dist/lib/setback-envelope.d.ts +95 -5
  523. package/dist/lib/setback-envelope.d.ts.map +1 -1
  524. package/dist/lib/setback-envelope.js +351 -35
  525. package/dist/lib/site-flatwork.d.ts +11 -0
  526. package/dist/lib/site-flatwork.d.ts.map +1 -0
  527. package/dist/lib/site-flatwork.js +11 -0
  528. package/dist/lib/site-ground-height.d.ts +13 -0
  529. package/dist/lib/site-ground-height.d.ts.map +1 -0
  530. package/dist/lib/site-ground-height.js +16 -0
  531. package/dist/lib/site-placement.d.ts +362 -0
  532. package/dist/lib/site-placement.d.ts.map +1 -0
  533. package/dist/lib/site-placement.js +942 -0
  534. package/dist/lib/snap-ease.d.ts +20 -0
  535. package/dist/lib/snap-ease.d.ts.map +1 -0
  536. package/dist/lib/snap-ease.js +50 -0
  537. package/dist/lib/structure-kernel.d.ts +1 -1
  538. package/dist/lib/structure-kernel.d.ts.map +1 -1
  539. package/dist/lib/structure-kernel.js +2 -0
  540. package/dist/lib/surface-support-references.d.ts +4 -0
  541. package/dist/lib/surface-support-references.d.ts.map +1 -0
  542. package/dist/lib/surface-support-references.js +19 -0
  543. package/dist/lib/terrain-support-query.d.ts +10 -0
  544. package/dist/lib/terrain-support-query.d.ts.map +1 -1
  545. package/dist/lib/terrain-support-query.js +1 -1
  546. package/dist/lib/wall-face-script.d.ts +66 -0
  547. package/dist/lib/wall-face-script.d.ts.map +1 -0
  548. package/dist/lib/wall-face-script.js +235 -0
  549. package/dist/lib/zone-colors.d.ts +1 -1
  550. package/dist/lib/zone-colors.d.ts.map +1 -1
  551. package/dist/lib/zone-quantities.d.ts.map +1 -1
  552. package/dist/lib/zone-quantities.js +4 -5
  553. package/dist/material-kinds.d.ts +9 -0
  554. package/dist/material-kinds.d.ts.map +1 -0
  555. package/dist/material-kinds.js +30 -0
  556. package/dist/material-library.d.ts +4 -4
  557. package/dist/material-library.d.ts.map +1 -1
  558. package/dist/material-library.js +72 -26
  559. package/dist/node-slots/index.d.ts +1 -0
  560. package/dist/node-slots/index.d.ts.map +1 -1
  561. package/dist/node-slots/index.js +7 -1
  562. package/dist/node-slots/roof.d.ts +5 -0
  563. package/dist/node-slots/roof.d.ts.map +1 -0
  564. package/dist/node-slots/roof.js +12 -0
  565. package/dist/node-slots/stair.d.ts +2 -0
  566. package/dist/node-slots/stair.d.ts.map +1 -1
  567. package/dist/node-slots/stair.js +6 -2
  568. package/dist/procedural-items/design-placement.d.ts.map +1 -1
  569. package/dist/procedural-items/design.d.ts +19 -19
  570. package/dist/procedural-items/fixtures.d.ts +297 -297
  571. package/dist/procedural-items/fixtures.d.ts.map +1 -1
  572. package/dist/procedural-items/integration.d.ts +106 -106
  573. package/dist/procedural-items/joints.d.ts +4 -4
  574. package/dist/procedural-items/library-colors.d.ts +22 -22
  575. package/dist/procedural-items/library-colors.d.ts.map +1 -1
  576. package/dist/procedural-items/motion-controller.d.ts.map +1 -1
  577. package/dist/procedural-items/node.d.ts +291 -291
  578. package/dist/procedural-items/query.d.ts +1 -1
  579. package/dist/procedural-items/query.d.ts.map +1 -1
  580. package/dist/procedural-items/recipe.d.ts +11 -11
  581. package/dist/procedural-items/recipe.d.ts.map +1 -1
  582. package/dist/procedural-items/section.d.ts.map +1 -1
  583. package/dist/registry/index.d.ts +1 -1
  584. package/dist/registry/index.d.ts.map +1 -1
  585. package/dist/registry/scene-api.d.ts +1 -0
  586. package/dist/registry/scene-api.d.ts.map +1 -1
  587. package/dist/registry/scene-api.js +3 -0
  588. package/dist/registry/subtree.d.ts.map +1 -1
  589. package/dist/registry/subtree.js +2 -0
  590. package/dist/registry/types.d.ts +120 -1
  591. package/dist/registry/types.d.ts.map +1 -1
  592. package/dist/schema/assembly.d.ts +41 -41
  593. package/dist/schema/asset-url.d.ts +1 -1
  594. package/dist/schema/asset-url.d.ts.map +1 -1
  595. package/dist/schema/base.d.ts +9 -9
  596. package/dist/schema/base.d.ts.map +1 -1
  597. package/dist/schema/camera.d.ts +1 -1
  598. package/dist/schema/collection-templates.d.ts +20 -20
  599. package/dist/schema/collection-templates.d.ts.map +1 -1
  600. package/dist/schema/geometry-metadata.d.ts +7 -7
  601. package/dist/schema/geometry-metadata.d.ts.map +1 -1
  602. package/dist/schema/geometry-source.d.ts +26 -16
  603. package/dist/schema/geometry-source.d.ts.map +1 -1
  604. package/dist/schema/geometry-source.js +14 -0
  605. package/dist/schema/index.d.ts +10 -7
  606. package/dist/schema/index.d.ts.map +1 -1
  607. package/dist/schema/index.js +10 -7
  608. package/dist/schema/material.d.ts +33 -33
  609. package/dist/schema/nodes/barrel-roof.d.ts +3 -0
  610. package/dist/schema/nodes/barrel-roof.d.ts.map +1 -0
  611. package/dist/schema/nodes/barrel-roof.js +11 -0
  612. package/dist/schema/nodes/block.d.ts +8 -8
  613. package/dist/schema/nodes/box-vent.d.ts +13 -13
  614. package/dist/schema/nodes/building.d.ts +9 -8
  615. package/dist/schema/nodes/building.d.ts.map +1 -1
  616. package/dist/schema/nodes/building.js +2 -0
  617. package/dist/schema/nodes/cabinet.d.ts +130 -129
  618. package/dist/schema/nodes/cabinet.d.ts.map +1 -1
  619. package/dist/schema/nodes/cabinet.js +1 -1
  620. package/dist/schema/nodes/ceiling.d.ts +15 -15
  621. package/dist/schema/nodes/chimney.d.ts +23 -23
  622. package/dist/schema/nodes/column.d.ts +207 -199
  623. package/dist/schema/nodes/column.d.ts.map +1 -1
  624. package/dist/schema/nodes/column.js +2 -0
  625. package/dist/schema/nodes/construction-dimension.d.ts +34 -34
  626. package/dist/schema/nodes/cupola.d.ts +15 -15
  627. package/dist/schema/nodes/curtain-wall.d.ts +21 -20
  628. package/dist/schema/nodes/curtain-wall.d.ts.map +1 -1
  629. package/dist/schema/nodes/curtain-wall.js +23 -0
  630. package/dist/schema/nodes/door.d.ts +50 -43
  631. package/dist/schema/nodes/door.d.ts.map +1 -1
  632. package/dist/schema/nodes/door.js +19 -0
  633. package/dist/schema/nodes/dormer.d.ts +37 -36
  634. package/dist/schema/nodes/dormer.d.ts.map +1 -1
  635. package/dist/schema/nodes/downspout.d.ts +17 -17
  636. package/dist/schema/nodes/duct-fitting.d.ts +24 -24
  637. package/dist/schema/nodes/duct-segment.d.ts +14 -14
  638. package/dist/schema/nodes/duct-terminal.d.ts +12 -12
  639. package/dist/schema/nodes/elevator.d.ts +15 -15
  640. package/dist/schema/nodes/eyebrow-vent.d.ts +13 -13
  641. package/dist/schema/nodes/fence-feature.d.ts +37 -37
  642. package/dist/schema/nodes/fence-types.d.ts +32 -0
  643. package/dist/schema/nodes/fence-types.d.ts.map +1 -0
  644. package/dist/schema/nodes/fence-types.js +22 -0
  645. package/dist/schema/nodes/fence.d.ts +43 -72
  646. package/dist/schema/nodes/fence.d.ts.map +1 -1
  647. package/dist/schema/nodes/fence.js +4 -20
  648. package/dist/schema/nodes/floor-opening.d.ts +8 -8
  649. package/dist/schema/nodes/guide.d.ts +8 -8
  650. package/dist/schema/nodes/gutter.d.ts +14 -14
  651. package/dist/schema/nodes/gutter.d.ts.map +1 -1
  652. package/dist/schema/nodes/gutter.js +6 -5
  653. package/dist/schema/nodes/hvac-equipment.d.ts +13 -13
  654. package/dist/schema/nodes/imported-mesh.d.ts +8 -8
  655. package/dist/schema/nodes/item.d.ts +30 -25
  656. package/dist/schema/nodes/item.d.ts.map +1 -1
  657. package/dist/schema/nodes/lean-to-extension.d.ts +36 -36
  658. package/dist/schema/nodes/level.d.ts +9 -9
  659. package/dist/schema/nodes/lineset.d.ts +8 -8
  660. package/dist/schema/nodes/liquid-line.d.ts +8 -8
  661. package/dist/schema/nodes/measurement.d.ts +8 -8
  662. package/dist/schema/nodes/opening-types.d.ts +13 -13
  663. package/dist/schema/nodes/opening-types.d.ts.map +1 -1
  664. package/dist/schema/nodes/pipe-fitting.d.ts +15 -15
  665. package/dist/schema/nodes/pipe-segment.d.ts +11 -11
  666. package/dist/schema/nodes/pipe-trap.d.ts +9 -9
  667. package/dist/schema/nodes/ridge-vent.d.ts +14 -14
  668. package/dist/schema/nodes/ridge-vent.d.ts.map +1 -1
  669. package/dist/schema/nodes/ridge-vent.js +3 -1
  670. package/dist/schema/nodes/roof-glazing-config.d.ts +90 -0
  671. package/dist/schema/nodes/roof-glazing-config.d.ts.map +1 -0
  672. package/dist/schema/nodes/roof-glazing-config.js +34 -0
  673. package/dist/schema/nodes/roof-glazing.d.ts +57 -0
  674. package/dist/schema/nodes/roof-glazing.d.ts.map +1 -0
  675. package/dist/schema/nodes/roof-glazing.js +514 -0
  676. package/dist/schema/nodes/roof-segment-resize.d.ts +4 -0
  677. package/dist/schema/nodes/roof-segment-resize.d.ts.map +1 -0
  678. package/dist/schema/nodes/roof-segment-resize.js +21 -0
  679. package/dist/schema/nodes/roof-segment-shape.d.ts +5 -0
  680. package/dist/schema/nodes/roof-segment-shape.d.ts.map +1 -1
  681. package/dist/schema/nodes/roof-segment-shape.js +44 -0
  682. package/dist/schema/nodes/roof-segment-walls.d.ts +1 -1
  683. package/dist/schema/nodes/roof-segment-walls.d.ts.map +1 -1
  684. package/dist/schema/nodes/roof-segment-walls.js +24 -0
  685. package/dist/schema/nodes/roof-segment.d.ts +153 -46
  686. package/dist/schema/nodes/roof-segment.d.ts.map +1 -1
  687. package/dist/schema/nodes/roof-segment.js +91 -20
  688. package/dist/schema/nodes/roof-types.d.ts +14 -0
  689. package/dist/schema/nodes/roof-types.d.ts.map +1 -0
  690. package/dist/schema/nodes/roof-types.js +14 -0
  691. package/dist/schema/nodes/roof.d.ts +49 -49
  692. package/dist/schema/nodes/scan.d.ts +8 -8
  693. package/dist/schema/nodes/separator.d.ts +8 -8
  694. package/dist/schema/nodes/shelf.d.ts +16 -16
  695. package/dist/schema/nodes/site-facts.d.ts +64 -0
  696. package/dist/schema/nodes/site-facts.d.ts.map +1 -0
  697. package/dist/schema/nodes/site-facts.js +73 -0
  698. package/dist/schema/nodes/site.d.ts +105 -63
  699. package/dist/schema/nodes/site.d.ts.map +1 -1
  700. package/dist/schema/nodes/site.js +7 -70
  701. package/dist/schema/nodes/skylight.d.ts +41 -41
  702. package/dist/schema/nodes/skylight.d.ts.map +1 -1
  703. package/dist/schema/nodes/slab.d.ts +21 -21
  704. package/dist/schema/nodes/solar-panel.d.ts +21 -21
  705. package/dist/schema/nodes/spawn.d.ts +8 -8
  706. package/dist/schema/nodes/stair-construction.d.ts +3 -3
  707. package/dist/schema/nodes/stair-defaults.d.ts +16 -0
  708. package/dist/schema/nodes/stair-defaults.d.ts.map +1 -0
  709. package/dist/schema/nodes/stair-defaults.js +15 -0
  710. package/dist/schema/nodes/stair-segment.d.ts +22 -22
  711. package/dist/schema/nodes/stair-types.d.ts +29 -0
  712. package/dist/schema/nodes/stair-types.d.ts.map +1 -0
  713. package/dist/schema/nodes/stair-types.js +23 -0
  714. package/dist/schema/nodes/stair.d.ts +51 -75
  715. package/dist/schema/nodes/stair.d.ts.map +1 -1
  716. package/dist/schema/nodes/stair.js +6 -20
  717. package/dist/schema/nodes/structural-grid.d.ts +8 -8
  718. package/dist/schema/nodes/surface-hole-metadata.d.ts +2 -2
  719. package/dist/schema/nodes/turbine-vent.d.ts +13 -13
  720. package/dist/schema/nodes/unit.d.ts +10 -10
  721. package/dist/schema/nodes/unit.d.ts.map +1 -1
  722. package/dist/schema/nodes/wall.d.ts +479 -146
  723. package/dist/schema/nodes/wall.d.ts.map +1 -1
  724. package/dist/schema/nodes/wall.js +19 -0
  725. package/dist/schema/nodes/window.d.ts +55 -39
  726. package/dist/schema/nodes/window.d.ts.map +1 -1
  727. package/dist/schema/nodes/window.js +10 -0
  728. package/dist/schema/nodes/zone.d.ts +231 -12
  729. package/dist/schema/nodes/zone.d.ts.map +1 -1
  730. package/dist/schema/nodes/zone.js +10 -0
  731. package/dist/schema/provenance.d.ts +21 -21
  732. package/dist/schema/scene-material.d.ts +5 -5
  733. package/dist/schema/site-presentation.d.ts +100 -0
  734. package/dist/schema/site-presentation.d.ts.map +1 -0
  735. package/dist/schema/site-presentation.js +83 -0
  736. package/dist/schema/types.d.ts +1954 -1414
  737. package/dist/schema/types.d.ts.map +1 -1
  738. package/dist/services/__fixtures__/wall-plane-top-boundary-repro.d.ts.map +1 -1
  739. package/dist/services/index.d.ts +5 -1
  740. package/dist/services/index.d.ts.map +1 -1
  741. package/dist/services/index.js +5 -1
  742. package/dist/services/level-height.d.ts.map +1 -1
  743. package/dist/services/level-height.js +7 -3
  744. package/dist/services/port-connectivity.d.ts +4 -0
  745. package/dist/services/port-connectivity.d.ts.map +1 -1
  746. package/dist/services/port-connectivity.js +35 -0
  747. package/dist/services/project-file-sink.d.ts +9 -0
  748. package/dist/services/project-file-sink.d.ts.map +1 -0
  749. package/dist/services/project-file-sink.js +13 -0
  750. package/dist/services/roof-bearing.d.ts +62 -0
  751. package/dist/services/roof-bearing.d.ts.map +1 -0
  752. package/dist/services/roof-bearing.js +234 -0
  753. package/dist/services/roof-level.d.ts +121 -0
  754. package/dist/services/roof-level.d.ts.map +1 -0
  755. package/dist/services/roof-level.js +280 -0
  756. package/dist/services/roof-move.d.ts +83 -0
  757. package/dist/services/roof-move.d.ts.map +1 -0
  758. package/dist/services/roof-move.js +316 -0
  759. package/dist/services/stair-surface-snap.d.ts +14 -0
  760. package/dist/services/stair-surface-snap.d.ts.map +1 -0
  761. package/dist/services/stair-surface-snap.js +116 -0
  762. package/dist/services/storey-datum.d.ts +12 -0
  763. package/dist/services/storey-datum.d.ts.map +1 -0
  764. package/dist/services/storey-datum.js +18 -0
  765. package/dist/services/storey.d.ts +51 -5
  766. package/dist/services/storey.d.ts.map +1 -1
  767. package/dist/services/storey.js +125 -8
  768. package/dist/solar-panel-presets.d.ts +2 -2
  769. package/dist/store/actions/node-actions.d.ts +3613 -3182
  770. package/dist/store/actions/node-actions.d.ts.map +1 -1
  771. package/dist/store/actions/node-actions.js +46 -1
  772. package/dist/store/derived-node-guard.d.ts.map +1 -1
  773. package/dist/store/history-control.d.ts +39 -0
  774. package/dist/store/history-control.d.ts.map +1 -1
  775. package/dist/store/history-control.js +84 -4
  776. package/dist/store/scene-annotations.d.ts +7267 -6409
  777. package/dist/store/scene-annotations.d.ts.map +1 -1
  778. package/dist/store/scene-preview.d.ts +16 -0
  779. package/dist/store/scene-preview.d.ts.map +1 -0
  780. package/dist/store/scene-preview.js +144 -0
  781. package/dist/store/use-live-node-overrides.d.ts.map +1 -1
  782. package/dist/store/use-live-terrain.d.ts.map +1 -1
  783. package/dist/store/use-live-transforms.d.ts.map +1 -1
  784. package/dist/store/use-scene.d.ts.map +1 -1
  785. package/dist/store/use-scene.js +37 -4
  786. package/dist/systems/elevator/elevator-dispatch.js +1 -1
  787. package/dist/systems/fence/fence-features.d.ts.map +1 -1
  788. package/dist/systems/owned-floor-openings.d.ts.map +1 -1
  789. package/dist/systems/owned-floor-openings.js +24 -3
  790. package/dist/systems/roof/roof-elevation-system.d.ts.map +1 -1
  791. package/dist/systems/roof/roof-elevation-system.js +9 -3
  792. package/dist/systems/roof/roof-elevation.d.ts +5 -0
  793. package/dist/systems/roof/roof-elevation.d.ts.map +1 -1
  794. package/dist/systems/roof/roof-elevation.js +91 -62
  795. package/dist/systems/slab/__fixtures__/floor-step.d.ts +4623 -3516
  796. package/dist/systems/slab/__fixtures__/floor-step.d.ts.map +1 -1
  797. package/dist/systems/slab/__fixtures__/raised-room.d.ts +5149 -4076
  798. package/dist/systems/slab/__fixtures__/raised-room.d.ts.map +1 -1
  799. package/dist/systems/slab/slab-support.d.ts +6 -3
  800. package/dist/systems/slab/slab-support.d.ts.map +1 -1
  801. package/dist/systems/slab/slab-support.js +78 -10
  802. package/dist/systems/stair/stair-detail-budget.d.ts +2 -2
  803. package/dist/systems/stair/stair-detail-budget.d.ts.map +1 -1
  804. package/dist/systems/stair/stair-footprint.d.ts +6 -0
  805. package/dist/systems/stair/stair-footprint.d.ts.map +1 -1
  806. package/dist/systems/stair/stair-footprint.js +27 -14
  807. package/dist/systems/stair/stair-layout.d.ts +2 -2
  808. package/dist/systems/stair/stair-opening-preview.d.ts +3643 -3214
  809. package/dist/systems/stair/stair-opening-preview.d.ts.map +1 -1
  810. package/dist/systems/stair/stair-presets.d.ts +73 -65
  811. package/dist/systems/stair/stair-presets.d.ts.map +1 -1
  812. package/dist/systems/stair/stair-presets.js +16 -9
  813. package/dist/systems/stair/stair-rail-path.d.ts +1 -1
  814. package/dist/systems/stair/stair-rise-query.d.ts +16 -0
  815. package/dist/systems/stair/stair-rise-query.d.ts.map +1 -1
  816. package/dist/systems/stair/stair-rise-query.js +57 -7
  817. package/dist/systems/stair/stair-sizing.d.ts +101 -99
  818. package/dist/systems/stair/stair-sizing.d.ts.map +1 -1
  819. package/dist/systems/wall/wall-assembly.d.ts +11 -0
  820. package/dist/systems/wall/wall-assembly.d.ts.map +1 -1
  821. package/dist/systems/wall/wall-assembly.js +21 -0
  822. package/dist/systems/wall/wall-curve.d.ts +5 -0
  823. package/dist/systems/wall/wall-curve.d.ts.map +1 -1
  824. package/dist/systems/wall/wall-curve.js +13 -0
  825. package/dist/systems/wall/wall-frame.d.ts.map +1 -1
  826. package/dist/systems/wall/wall-frame.js +8 -0
  827. package/dist/systems/wall/wall-room-sides.d.ts +8 -0
  828. package/dist/systems/wall/wall-room-sides.d.ts.map +1 -1
  829. package/dist/systems/wall/wall-room-sides.js +60 -7
  830. package/dist/systems/wall/wall-top.d.ts +7 -4
  831. package/dist/systems/wall/wall-top.d.ts.map +1 -1
  832. package/dist/systems/wall/wall-top.js +14 -6
  833. package/dist/systems/wall/wall-topology.d.ts +4 -0
  834. package/dist/systems/wall/wall-topology.d.ts.map +1 -1
  835. package/dist/systems/wall/wall-topology.js +4 -2
  836. package/dist/systems/wall/wall-trim.d.ts +7 -0
  837. package/dist/systems/wall/wall-trim.d.ts.map +1 -0
  838. package/dist/systems/wall/wall-trim.js +10 -0
  839. package/dist/utils/clone-scene-graph.d.ts.map +1 -1
  840. package/dist/utils/clone-scene-graph.js +8 -0
  841. package/dist/utils/ensure-scene-openings.d.ts +7420 -6562
  842. package/dist/utils/ensure-scene-openings.d.ts.map +1 -1
  843. package/dist/utils/floor-piece-adoption.d.ts +2 -2
  844. package/dist/utils/floor-plate-migration.d.ts +3746 -3317
  845. package/dist/utils/floor-plate-migration.d.ts.map +1 -1
  846. package/dist/utils/floor-plate-migration.js +2 -2
  847. package/dist/utils/heal-scene-graph.d.ts +12 -0
  848. package/dist/utils/heal-scene-graph.d.ts.map +1 -1
  849. package/dist/utils/heal-scene-graph.js +40 -23
  850. package/dist/utils/legacy-wall-datums.d.ts.map +1 -1
  851. package/dist/utils/legacy-wall-datums.js +2 -2
  852. package/dist/utils/owned-floor-opening-migration.d.ts +3642 -3213
  853. package/dist/utils/owned-floor-opening-migration.d.ts.map +1 -1
  854. package/dist/utils/reconcile-structure-on-load.d.ts +3730 -7777
  855. package/dist/utils/reconcile-structure-on-load.d.ts.map +1 -1
  856. package/dist/utils/scene-migrations.d.ts +1 -1
  857. package/dist/utils/scene-migrations.d.ts.map +1 -1
  858. package/dist/utils/scene-migrations.js +1 -1
  859. package/dist/utils/semantic-equal.d.ts +3 -0
  860. package/dist/utils/semantic-equal.d.ts.map +1 -0
  861. package/dist/utils/semantic-equal.js +26 -0
  862. package/dist/utils/structure-id.d.ts.map +1 -1
  863. package/dist/utils/types.d.ts.map +1 -1
  864. package/dist/utils/wall-face-migration.d.ts +1 -1
  865. package/dist/utils/wall-face-migration.d.ts.map +1 -1
  866. package/package.json +36 -10
@@ -0,0 +1,1076 @@
1
+ import { refuse } from '../agent-tools/refusal.js';
2
+ import { doorTypeFields } from '../building/door-types.js';
3
+ import { DOOR_STYLES, doorStyleLook, getWindowStyleOverrides, WINDOW_STYLES, } from '../building/opening-style-presets.js';
4
+ import { windowTakesStyle, windowTypeFields } from '../building/window-types.js';
5
+ import { floorRoomFaces } from '../lib/floor-room-faces.js';
6
+ import { matchScriptSlotsToLibrary, requireMeasured, scriptedSize, scriptSource, } from '../lib/geometry-script-node.js';
7
+ import { detectSpacesForLevel } from '../lib/space-detection.js';
8
+ import { reconcileSceneStructure } from '../lib/structure-reconcile.js';
9
+ import { wallFaceScriptInputs } from '../lib/wall-face-script.js';
10
+ import { nearestLibraryColorRef } from '../procedural-items/library-colors.js';
11
+ import { ColumnNode, DoorNode, LevelNode, SlabNode, WallNode, WindowNode, ZoneNode, } from '../schema/index.js';
12
+ import { DoorType, WindowType } from '../schema/nodes/opening-types.js';
13
+ import { resolveCeilingHeight } from '../services/level-height.js';
14
+ import { CEILING_DRAW_OFFSET } from '../services/storey.js';
15
+ import { getWallLocalFaceZ } from '../systems/wall/wall-frame.js';
16
+ import { roomFaceCover } from '../systems/wall/wall-room-sides.js';
17
+ import { migrateRoomZones } from '../utils/room-zone-migration.js';
18
+ import { addObject } from './add-object.js';
19
+ import { authoredSceneChanges } from './authored-scene-merge.js';
20
+ import { paint } from './paint.js';
21
+ import { pointInPolygon, projectWorldPointToWallLocalX } from './plan-geometry.js';
22
+ import { resolveInlinePaintMaterial } from './scene-materials.js';
23
+ import { setWallSkirting } from './wall-skirting.js';
24
+ const JOIN_REACH = 0.3;
25
+ const THIN_SLAB = 0.02;
26
+ const MANY_SLABS = 20;
27
+ const MANY_REGIONS = 24;
28
+ const HEX = /^#[0-9a-f]{6}$/i;
29
+ const GLASS = 'library:preset-glass';
30
+ /**
31
+ * Explicit payload keys retain their identities across revisions; derived nodes use the
32
+ * conversion's retained seed. A changed payload never remints every existing wall or item.
33
+ */
34
+ function idFactory(seed, previous = {}) {
35
+ const counts = new Map();
36
+ return (kind, key) => {
37
+ const n = (counts.get(kind) ?? 0) + 1;
38
+ counts.set(kind, n);
39
+ if (key && previous[key]?.startsWith(`${kind}_`))
40
+ return previous[key];
41
+ let hash = 0x811c9dc5;
42
+ for (const ch of `${seed}:${kind}:${key ?? n}`)
43
+ hash = Math.imul(hash ^ ch.charCodeAt(0), 0x01000193) >>> 0;
44
+ return `${kind}_as${hash.toString(16).padStart(8, '0')}`;
45
+ };
46
+ }
47
+ function payloadSeed(payload) {
48
+ let hash = 0x811c9dc5;
49
+ for (const ch of JSON.stringify(payload))
50
+ hash = Math.imul(hash ^ ch.charCodeAt(0), 0x01000193) >>> 0;
51
+ return hash.toString(16);
52
+ }
53
+ const dist = (a, b) => Math.hypot(a[0] - b[0], a[1] - b[1]);
54
+ const metres = (value) => `${value.toFixed(2)} m`;
55
+ /**
56
+ * Where a wall end meets another wall's centerline: the projection onto that line, as long as it
57
+ * lands on the wall or within reach past its ends. The line, not the segment, so a partition
58
+ * stopping short of a wall extends to it, and the wall it meets does not slide to the partition.
59
+ */
60
+ function nearestOnSegment(p, a, b) {
61
+ const len = Math.hypot(b[0] - a[0], b[1] - a[1]) || 1;
62
+ const t = ((p[0] - a[0]) * (b[0] - a[0]) + (p[1] - a[1]) * (b[1] - a[1])) / (len * len);
63
+ if (t * len < -JOIN_REACH || (t - 1) * len > JOIN_REACH)
64
+ return { point: [p[0], p[1]], distance: Number.POSITIVE_INFINITY };
65
+ const q = [a[0] + t * (b[0] - a[0]), a[1] + t * (b[1] - a[1])];
66
+ return { point: q, distance: dist(p, q) };
67
+ }
68
+ const cross = (o, a, b) => (a[0] - o[0]) * (b[1] - o[1]) - (a[1] - o[1]) * (b[0] - o[0]);
69
+ /** Whether two segments cross each other's interior (touching ends and shared edges do not). */
70
+ function segmentsCross(a, b, c, d) {
71
+ const [d1, d2, d3, d4] = [cross(c, d, a), cross(c, d, b), cross(a, b, c), cross(a, b, d)];
72
+ return d1 * d2 < 0 && d3 * d4 < 0;
73
+ }
74
+ /** Whether two polygons share interior area: a slab flush against a wall's face does not. */
75
+ function polygonsOverlap(a, b) {
76
+ if (a.some((p) => pointInPolygon(p, b, false)) || b.some((p) => pointInPolygon(p, a, false)))
77
+ return true;
78
+ for (let i = 0; i < a.length; i++)
79
+ for (let j = 0; j < b.length; j++)
80
+ if (segmentsCross(a[i], a[(i + 1) % a.length], b[j], b[(j + 1) % b.length]))
81
+ return true;
82
+ return false;
83
+ }
84
+ /** A wall's footprint, pulled in by a few millimetres so a slab meeting its face is not on it. */
85
+ function wallFootprint(wall) {
86
+ const inset = 0.005;
87
+ const [dx, dz] = [wall.end[0] - wall.start[0], wall.end[1] - wall.start[1]];
88
+ const len = Math.hypot(dx, dz) || 1;
89
+ const [ux, uz] = [dx / len, dz / len];
90
+ const half = Math.max(wall.thickness / 2 - inset, 0.001);
91
+ const s = [wall.start[0] + ux * inset, wall.start[1] + uz * inset];
92
+ const e = [wall.end[0] - ux * inset, wall.end[1] - uz * inset];
93
+ return [
94
+ [s[0] - uz * half, s[1] + ux * half],
95
+ [e[0] - uz * half, e[1] + ux * half],
96
+ [e[0] + uz * half, e[1] - ux * half],
97
+ [s[0] + uz * half, s[1] - ux * half],
98
+ ];
99
+ }
100
+ function toLocal(frame, world) {
101
+ const [dx, dy, dz] = [
102
+ world[0] - frame.position[0],
103
+ world[1] - frame.position[1],
104
+ world[2] - frame.position[2],
105
+ ];
106
+ const [c, s] = [Math.cos(frame.yaw), Math.sin(frame.yaw)];
107
+ return [c * dx - s * dz, dy, s * dx + c * dz];
108
+ }
109
+ const MATTE = { roughness: 0.9, metalness: 0 };
110
+ /**
111
+ * The finish a payload value writes. A library or scene ref passes through; a hex colour is kept
112
+ * as an exact native material, one scene material per distinct colour and surface across the
113
+ * payload, named by them. A host that keeps no scene materials gets the nearest library colour,
114
+ * said once.
115
+ */
116
+ function finishPool(context, say) {
117
+ const materials = context.materials
118
+ ? { ...context.materials }
119
+ : undefined;
120
+ const created = [];
121
+ let snapped = false;
122
+ return {
123
+ materials,
124
+ created,
125
+ ref(value, surface = MATTE) {
126
+ if (value.startsWith('library:') || value.startsWith('scene:'))
127
+ return { ref: value };
128
+ if (!HEX.test(value))
129
+ return { error: `${value} is no colour: give #rrggbb or library:<id>.` };
130
+ const hex = value.toLowerCase();
131
+ if (!materials) {
132
+ if (!snapped)
133
+ say('this host keeps no scene materials: colours written as the nearest library colour');
134
+ snapped = true;
135
+ return { ref: nearestLibraryColorRef(hex).ref };
136
+ }
137
+ const resolved = resolveInlinePaintMaterial(materials, {
138
+ properties: {
139
+ color: hex,
140
+ roughness: surface.roughness,
141
+ metalness: surface.metalness,
142
+ opacity: 1,
143
+ transparent: false,
144
+ side: 'front',
145
+ },
146
+ }, surface.roughness === MATTE.roughness && surface.metalness === MATTE.metalness
147
+ ? hex
148
+ : `${hex}, roughness ${+surface.roughness.toFixed(2)}, metalness ${+surface.metalness.toFixed(2)}`);
149
+ if (resolved.created) {
150
+ materials[resolved.sceneMaterial.id] = resolved.sceneMaterial;
151
+ created.push(resolved.sceneMaterial);
152
+ }
153
+ return { ref: resolved.ref };
154
+ },
155
+ };
156
+ }
157
+ const isDoorType = (type) => DoorType.options.includes(type);
158
+ const isWindowType = (type) => WindowType.options.includes(type);
159
+ const isDoorStyle = (style) => DOOR_STYLES.includes(style);
160
+ const isWindowStyle = (style) => WINDOW_STYLES.includes(style);
161
+ const CEILING_POINT_CODE = `export const mount = 'ceiling'
162
+ export default function build({ THREE }) {
163
+ const material = new THREE.MeshStandardMaterial({ color: '#ffffff' })
164
+ material.name = 'slot_body'
165
+ return new THREE.Mesh(new THREE.CylinderGeometry(0.03, 0.03, 0.008, 24), material)
166
+ }`;
167
+ /** Candidate modules, compiled by the host before room derivation decides which points are used. */
168
+ export function authorSceneCeilingPoints(payload) {
169
+ return payload.levels.flatMap((level, index) => level.lights.flatMap((light, i) => light.fixture ? [] : [{ id: `light/${index}/${i}`, code: CEILING_POINT_CODE }]));
170
+ }
171
+ /**
172
+ * The rooms whose floor finish is a module, by their zone once the write made it: the host reads
173
+ * each room's floor (`floorScriptInputs`), compiles the module for it and writes it with
174
+ * `setRoomFloorScript`, which core cannot do without a three.js runtime. A room whose seed found
175
+ * no enclosure has no zone and is already a defect.
176
+ */
177
+ export function authorSceneFloorScripts(payload, report) {
178
+ return payload.levels.flatMap((level, index) => level.rooms.flatMap((room, i) => {
179
+ const roomId = `room/${index}/${i}`;
180
+ const zoneId = report.ids[roomId];
181
+ return room.floorCode && zoneId ? [{ roomId, zoneId, code: room.floorCode }] : [];
182
+ }));
183
+ }
184
+ /**
185
+ * Which faces the payload's face modules build on, and why the others cannot be: a wall's own
186
+ * `faceLeft` (face a) and `faceRight` (face b), then each room's `wallCode` on the faces its floor
187
+ * meets (the spans of the room the zone was derived from, the faces `setWallSkirting` runs along),
188
+ * where a wall's own module wins. A face with nothing to build on (a curved or curtain wall) or
189
+ * that no room looks into is a `no_face` defect.
190
+ */
191
+ function resolveFaceScripts(payload, ids, nodes) {
192
+ const scripts = [];
193
+ const defects = [];
194
+ const warnings = [];
195
+ const side = (face) => (face === 'a' ? 'left' : 'right');
196
+ const add = (wallId, face, nodeId, code, toHeight) => scripts.push({ wallId, face, nodeId, code, ...(toHeight === undefined ? {} : { toHeight }) });
197
+ const flat = 'is curved, a curtain wall or has no height';
198
+ payload.levels.forEach((level, index) => {
199
+ const walls = (level.walls ?? []).flatMap((spec) => {
200
+ const nodeId = ids[spec.id];
201
+ return nodeId && nodes[nodeId]?.type === 'wall' ? [{ spec, nodeId }] : [];
202
+ });
203
+ const owned = new Set();
204
+ for (const { spec, nodeId } of walls) {
205
+ for (const [face, module] of [
206
+ ['a', spec.faceLeft],
207
+ ['b', spec.faceRight],
208
+ ]) {
209
+ if (!module)
210
+ continue;
211
+ owned.add(`${nodeId}/${face}`);
212
+ const id = `${spec.id}/${face}`;
213
+ if (!wallFaceScriptInputs(nodes, nodeId, face, module.toHeight))
214
+ defects.push({
215
+ id,
216
+ code: 'no_face',
217
+ message: `Wall ${spec.id} ${flat}: its ${side(face)} face has nothing a script can build on and keeps its paint.`,
218
+ });
219
+ else if (roomFaceCover(nodes, nodeId)[face] === 'none')
220
+ defects.push({
221
+ id,
222
+ code: 'no_face',
223
+ message: `No room looks into the ${side(face)} face of wall ${spec.id} (left and right as seen from its start to its end): its face script was not written.`,
224
+ });
225
+ else
226
+ add(spec.id, face, nodeId, module.code, module.toHeight);
227
+ }
228
+ }
229
+ const byRoom = new Map();
230
+ for (const [i, room] of level.rooms.entries()) {
231
+ const roomId = `room/${index}/${i}`;
232
+ const zone = nodes[ids[roomId] ?? ''];
233
+ if (!room.wallCode || zone?.type !== 'zone')
234
+ continue;
235
+ const boundaries = Object.values(nodes).filter((n) => n.parentId === zone.parentId && (n.type === 'wall' || n.type === 'separator'));
236
+ const zoneWalls = [...zone.boundaryWallIds].sort().join();
237
+ const derived = floorRoomFaces(boundaries).find((r) => [...new Set(r.spans.filter((s) => s.kind === 'wall').map((s) => s.boundaryId))]
238
+ .sort()
239
+ .join() === zoneWalls && pointInPolygon(room.seed, r.referencePolygon));
240
+ const faces = new Set((derived?.spans ?? [])
241
+ .filter((s) => s.kind === 'wall' && s.t1 > s.t0)
242
+ .map((s) => `${s.boundaryId}/${s.face}`));
243
+ if (!faces.size) {
244
+ defects.push({
245
+ id: roomId,
246
+ code: 'no_face',
247
+ message: `No wall face looks into "${room.name}": its wallCode was not written.`,
248
+ });
249
+ continue;
250
+ }
251
+ for (const { spec, nodeId } of walls) {
252
+ for (const face of ['a', 'b']) {
253
+ const key = `${nodeId}/${face}`;
254
+ if (!faces.has(key) || owned.has(key))
255
+ continue;
256
+ const other = byRoom.get(key);
257
+ if (other) {
258
+ if (other.code !== room.wallCode || other.toHeight !== room.wallToHeight)
259
+ warnings.push({
260
+ id: `${spec.id}/${face}`,
261
+ code: 'face_shared',
262
+ message: `The ${side(face)} face of wall ${spec.id} looks into "${other.name}" and "${room.name}": it is built by "${other.name}"'s wallCode.`,
263
+ });
264
+ continue;
265
+ }
266
+ byRoom.set(key, { name: room.name, code: room.wallCode, toHeight: room.wallToHeight });
267
+ if (!wallFaceScriptInputs(nodes, nodeId, face, room.wallToHeight))
268
+ defects.push({
269
+ id: `${spec.id}/${face}`,
270
+ code: 'no_face',
271
+ message: `Wall ${spec.id} ${flat}: "${room.name}"'s wallCode was not written on its ${side(face)} face, which keeps its paint.`,
272
+ });
273
+ else
274
+ add(spec.id, face, nodeId, room.wallCode, room.wallToHeight);
275
+ }
276
+ }
277
+ }
278
+ });
279
+ return { scripts, defects, warnings };
280
+ }
281
+ /** Below this share a floor or face finish leaves enough of its host bare to be worth a warning. */
282
+ const FINISH_COVERED = 0.98;
283
+ const figure = (value) => String(Math.round(value * 100) / 100);
284
+ /** A bare patch on a floor, by the edges of the floor's bounds it runs along, and its extent. */
285
+ function floorPatch({ min, max }, polygon) {
286
+ const reach = 0.05;
287
+ const xs = polygon.map(([x]) => x);
288
+ const zs = polygon.map(([, z]) => z);
289
+ const touches = {
290
+ north: min[1] <= Math.min(...zs) + reach,
291
+ south: max[1] >= Math.max(...zs) - reach,
292
+ west: min[0] <= Math.min(...xs) + reach,
293
+ east: max[0] >= Math.max(...xs) - reach,
294
+ };
295
+ const sides = Object.keys(touches).filter((side) => touches[side]);
296
+ const ns = sides.filter((side) => side === 'north' || side === 'south');
297
+ const ew = sides.filter((side) => side === 'west' || side === 'east');
298
+ const where = sides.length === 0
299
+ ? 'inside the floor'
300
+ : sides.length === 1
301
+ ? `along the ${sides[0]} edge`
302
+ : sides.length > 2
303
+ ? 'over most of the floor'
304
+ : ns.length === 1
305
+ ? `in the ${ns[0]}-${ew[0]} corner`
306
+ : `across the floor from ${sides[0]} to ${sides[1]}`;
307
+ return `${where} (${figure(max[0] - min[0])} × ${figure(max[1] - min[1])} m, x ${figure(min[0])} to ${figure(max[0])}, z ${figure(min[1])} to ${figure(max[1])})`;
308
+ }
309
+ /**
310
+ * The `finish_gaps` warning for a floor or face script whose build leaves part of its host bare:
311
+ * its `coverage` under FINISH_COVERED with at least one bare patch, each named by where it lies.
312
+ * Joints make no patch, so a tiled finish is never warned for its joints alone. Null otherwise.
313
+ */
314
+ export function authorSceneFinishGaps(id, manifest, host) {
315
+ const { coverage, uncovered } = manifest;
316
+ if (coverage === undefined || coverage >= FINISH_COVERED || !uncovered?.length)
317
+ return null;
318
+ const share = `${Math.round(coverage * 100)}%`;
319
+ const message = 'room' in host
320
+ ? `The floor finish of "${host.room}" covers ${share} of its floor: uncovered ${uncovered.map((patch) => floorPatch(patch, host.polygon)).join('; ')}.`
321
+ : `The finish on the ${host.face === 'a' ? 'left' : 'right'} face of wall ${host.wall} covers ${share} of the face: uncovered ${uncovered
322
+ .map(({ min, max }) => `${figure(min[0])} to ${figure(max[0])} m along the wall from its start, ${figure(min[1])} to ${figure(max[1])} m up (${figure(max[0] - min[0])} × ${figure(max[1] - min[1])} m)`)
323
+ .join('; ')}.`;
324
+ return { id, code: 'finish_gaps', message };
325
+ }
326
+ /**
327
+ * The wall faces whose finish is a module, once the write made the walls and the rooms: the host
328
+ * reads each face (`wallFaceScriptInputs`), compiles the module for it and writes it with
329
+ * `setWallFaceScript`, which core cannot do without a three.js runtime. The faces that cannot take
330
+ * one are already `no_face` defects in the operation's report.
331
+ */
332
+ export function authorSceneFaceScripts(payload, report, nodes) {
333
+ return resolveFaceScripts(payload, report.ids, nodes).scripts;
334
+ }
335
+ export function authorScene(scene, input, context) {
336
+ const { payload } = input;
337
+ const sourceKeys = new Set();
338
+ const claimSourceKey = (key) => {
339
+ if (sourceKeys.has(key))
340
+ refuse('duplicate_source_id', `Source id "${key}" is repeated. Give every wall and item a unique id across all levels; opening and generated-part keys must also remain distinct.`, { id: key, mutationApplied: false });
341
+ sourceKeys.add(key);
342
+ };
343
+ payload.levels.forEach((level, index) => {
344
+ claimSourceKey(`level/${index}`);
345
+ for (const [kind, parts] of [
346
+ ['room', level.rooms],
347
+ ['slab', level.slabs],
348
+ ['column', level.columns],
349
+ ['light', level.lights],
350
+ ])
351
+ parts?.forEach((_, i) => {
352
+ claimSourceKey(`${kind}/${index}/${i}`);
353
+ });
354
+ for (const wall of level.walls ?? []) {
355
+ claimSourceKey(wall.id);
356
+ wall.openings?.forEach((_, i) => {
357
+ claimSourceKey(`${wall.id}/${i}`);
358
+ });
359
+ }
360
+ for (const item of level.items ?? [])
361
+ claimSourceKey(item.id);
362
+ });
363
+ const buildings = Object.values(scene).filter((n) => n.type === 'building');
364
+ const selected = input.buildingId ?? (context.activeLevelId ? scene[context.activeLevelId]?.parentId : undefined);
365
+ const building = selected
366
+ ? buildings.find((node) => node.id === selected)
367
+ : buildings.length === 1
368
+ ? buildings[0]
369
+ : undefined;
370
+ if (!building)
371
+ refuse('no_building', 'The scene has no building to put the levels in.');
372
+ const existingLevels = Object.values(scene).filter((n) => n.type === 'level' && n.parentId === building.id);
373
+ const saved = building.metadata?.authorSceneState;
374
+ const previous = saved?.version === 1 &&
375
+ saved.buildingId === building.id &&
376
+ saved.nodes &&
377
+ saved.ids &&
378
+ typeof saved.seed === 'string'
379
+ ? saved
380
+ : undefined;
381
+ const converted = Boolean(previous) || existingLevels.some((l) => l.metadata?.authorScene);
382
+ if (converted && !input.replace)
383
+ refuse('conversion_exists', 'This scene already holds a conversion. Pass replace: true to write over it.');
384
+ if (!previous &&
385
+ (converted ||
386
+ existingLevels.some((level) => Object.values(scene).some((node) => node.parentId === level.id))))
387
+ refuse('existing_design', 'This building already contains work without a retained conversion baseline. Use its native edit tools or convert into a separate building; existing geometry will not be replaced.', { mutationApplied: false });
388
+ const seed = previous?.seed ?? `${building.id}:${payloadSeed(payload)}`;
389
+ const mint = idFactory(seed, previous?.ids);
390
+ const report = {
391
+ levels: 0,
392
+ walls: 0,
393
+ doors: 0,
394
+ windows: 0,
395
+ rooms: 0,
396
+ roomsNamed: 0,
397
+ slabs: 0,
398
+ columns: 0,
399
+ items: 0,
400
+ lights: 0,
401
+ floorScripts: 0,
402
+ faceScripts: 0,
403
+ snapped: [],
404
+ defaults: [],
405
+ warnings: [],
406
+ defects: [],
407
+ notes: [...payload.notes],
408
+ ids: {},
409
+ };
410
+ const defect = (id, code, message) => report.defects.push({ id, code, message });
411
+ const warn = (id, code, message) => report.warnings.push({ id, code, message });
412
+ const say = (sentence) => report.defaults.push(sentence);
413
+ const finishes = finishPool(context, say);
414
+ const finishRef = (value, id, surface) => {
415
+ if (!value)
416
+ return undefined;
417
+ const got = finishes.ref(value, surface);
418
+ if ('error' in got) {
419
+ defect(id, 'invalid_color', got.error);
420
+ return undefined;
421
+ }
422
+ return got.ref;
423
+ };
424
+ const exactSlots = (compiled, id) => {
425
+ const slots = matchScriptSlotsToLibrary(compiled.manifest);
426
+ for (const slot of compiled.manifest.slots) {
427
+ // Glass keeps the glass add_object writes, drawn see-through and letting light pass. A
428
+ // scene material carries no emission, so an emissive slot keeps the module's own material
429
+ // (the library match leaves it alone) and a bulb stays lit.
430
+ if (!slot.color || slot.emissive || slots[slot.id] === GLASS)
431
+ continue;
432
+ const ref = finishRef(slot.color, id, {
433
+ roughness: slot.roughness ?? MATTE.roughness,
434
+ metalness: slot.metalness ?? MATTE.metalness,
435
+ });
436
+ if (ref)
437
+ slots[slot.id] = ref;
438
+ }
439
+ return slots;
440
+ };
441
+ const paintContext = (levelId) => ({
442
+ ...context,
443
+ activeLevelId: levelId,
444
+ ...(finishes.materials ? { materials: finishes.materials } : {}),
445
+ });
446
+ // A separate candidate contains only its building and ancestors, never another building's work.
447
+ const draft = {};
448
+ let ancestor = building;
449
+ while (ancestor && !draft[ancestor.id]) {
450
+ draft[ancestor.id] = { ...ancestor, children: [] };
451
+ ancestor = ancestor.parentId ? scene[ancestor.parentId] : undefined;
452
+ }
453
+ const scaffoldIds = new Set(Object.keys(draft));
454
+ const levelNodes = [];
455
+ const itemNodeIds = new Map();
456
+ const itemFrames = new Map();
457
+ const skirtings = [];
458
+ let untypedWindows = 0;
459
+ payload.levels.forEach((level, index) => {
460
+ const levelNode = LevelNode.parse({
461
+ object: 'node',
462
+ type: 'level',
463
+ id: mint('level', `level/${index}`),
464
+ parentId: building.id,
465
+ visible: true,
466
+ metadata: { authorScene: { elevation: level.elevation } },
467
+ name: level.name,
468
+ level: index,
469
+ children: [],
470
+ });
471
+ draft[levelNode.id] = levelNode;
472
+ report.ids[`level/${index}`] = levelNode.id;
473
+ levelNodes.push(levelNode);
474
+ const place = (node) => {
475
+ draft[node.id] = node;
476
+ levelNode.children.push(node.id);
477
+ };
478
+ // ---------- walls, joined ----------
479
+ const walls = (level.walls ?? []).map((w) => ({
480
+ spec: w,
481
+ start: [...w.start],
482
+ end: [...w.end],
483
+ }));
484
+ for (const w of walls) {
485
+ for (const end of ['start', 'end']) {
486
+ const pt = w[end];
487
+ let best = null;
488
+ for (const o of walls) {
489
+ if (o === w)
490
+ continue;
491
+ const near = nearestOnSegment(pt, o.start, o.end);
492
+ if (near.distance < JOIN_REACH && (!best || near.distance < best.distance))
493
+ best = near;
494
+ }
495
+ if (best && best.distance > 0.001) {
496
+ report.snapped.push({
497
+ id: w.spec.id,
498
+ end,
499
+ movedM: Math.round(best.distance * 1000) / 1000,
500
+ });
501
+ w[end] = best.point;
502
+ }
503
+ }
504
+ }
505
+ const wallNodes = new Map();
506
+ for (const w of walls) {
507
+ if (dist(w.start, w.end) < 0.05) {
508
+ defect(w.spec.id, 'wall_too_short', 'The wall is shorter than 5 cm after joining.');
509
+ continue;
510
+ }
511
+ const node = WallNode.parse({
512
+ object: 'node',
513
+ type: 'wall',
514
+ id: mint('wall', w.spec.id),
515
+ parentId: levelNode.id,
516
+ visible: true,
517
+ metadata: { authorScene: { id: w.spec.id } },
518
+ children: [],
519
+ start: w.start,
520
+ end: w.end,
521
+ height: w.spec.height,
522
+ thickness: w.spec.thickness,
523
+ });
524
+ place(node);
525
+ wallNodes.set(w.spec.id, { ...w, node });
526
+ if (w.spec.skirting)
527
+ skirtings.push({
528
+ id: w.spec.id,
529
+ nodeId: node.id,
530
+ levelId: levelNode.id,
531
+ skirting: w.spec.skirting,
532
+ });
533
+ report.ids[w.spec.id] = node.id;
534
+ report.walls++;
535
+ // ---------- its openings ----------
536
+ const length = dist(w.start, w.end);
537
+ (w.spec.openings ?? []).forEach((o, i) => {
538
+ const id = `${w.spec.id}/${i}`;
539
+ // A module supplies geometry; the declared type still describes how the opening works.
540
+ let compiled;
541
+ if (o.code) {
542
+ compiled = input.compiled[id];
543
+ if (!compiled) {
544
+ defect(id, 'compile_failed', input.compileErrors?.[id] ?? 'The module did not compile.');
545
+ return;
546
+ }
547
+ if (compiled.mount !== 'wall') {
548
+ defect(id, 'wrong_mount', `A ${o.kind}'s module uses mount 'wall', not '${compiled.mount}'.`);
549
+ return;
550
+ }
551
+ try {
552
+ requireMeasured(compiled, { label: o.name ?? id, tool: 'author_scene' });
553
+ }
554
+ catch (error) {
555
+ const e = error;
556
+ defect(id, e.code ?? 'unmeasurable_object', e.message ?? String(error));
557
+ return;
558
+ }
559
+ if (o.style)
560
+ say(`${o.kind} ${id}: style ignored, its module builds it`);
561
+ }
562
+ const [width, height] = compiled ? scriptedSize(compiled.manifest) : [o.width, o.height];
563
+ if (width > length + 0.01) {
564
+ defect(id, 'opening_wider_than_wall', `${o.kind} ${width.toFixed(2)} m wide on a ${length.toFixed(2)} m wall.`);
565
+ return;
566
+ }
567
+ const x = Math.min(Math.max(o.along, width / 2), length - width / 2);
568
+ if (Math.abs(x - o.along) > 0.01)
569
+ say(`${o.kind} ${id}: moved ${Math.abs(x - o.along).toFixed(2)} m along the wall to fit inside it`);
570
+ const common = {
571
+ object: 'node',
572
+ id: mint(o.kind, id),
573
+ parentId: node.id,
574
+ visible: true,
575
+ metadata: { authorScene: { id, color: o.color ?? null } },
576
+ wallId: node.id,
577
+ width,
578
+ height,
579
+ rotation: [0, 0, 0],
580
+ ...(o.name ? { name: o.name } : {}),
581
+ ...(compiled
582
+ ? {
583
+ source: scriptSource(compiled, { category: o.kind }),
584
+ slots: exactSlots(compiled, id),
585
+ }
586
+ : {}),
587
+ };
588
+ let opening;
589
+ if (o.kind === 'door') {
590
+ const type = o.type;
591
+ if (type && !isDoorType(type))
592
+ defect(id, 'type_mismatch', `${type} is a window type; the door is written hinged.`);
593
+ const style = o.style && !compiled ? o.style : undefined;
594
+ if (style && !isDoorStyle(style))
595
+ defect(id, 'style_mismatch', `${style} is a window style; the door keeps its panel leaf.`);
596
+ const hingesSide = o.hinge === 'end' ? 'right' : 'left';
597
+ const handleSide = hingesSide === 'right' ? 'left' : 'right';
598
+ if (o.hinge)
599
+ say(`door ${id}: handle set opposite the hinge (${handleSide})`);
600
+ opening = DoorNode.parse({
601
+ ...common,
602
+ type: 'door',
603
+ position: [x, height / 2, 0],
604
+ ...(type && isDoorType(type) ? doorTypeFields(type) : {}),
605
+ ...(style && isDoorStyle(style) ? doorStyleLook(style) : {}),
606
+ ...(o.leaves ? { leafCount: o.leaves } : {}),
607
+ hingesSide,
608
+ handleSide,
609
+ ...(o.swing ? { swingDirection: o.swing === 'back' ? 'outward' : 'inward' } : {}),
610
+ });
611
+ report.doors++;
612
+ }
613
+ else {
614
+ const type = o.type;
615
+ if (type && !isWindowType(type))
616
+ defect(id, 'type_mismatch', `${type} is a door type; the window is written fixed.`);
617
+ const windowType = type && isWindowType(type) ? type : undefined;
618
+ if (!windowType && !compiled)
619
+ untypedWindows++;
620
+ const style = o.style && !compiled ? o.style : undefined;
621
+ if (style && !isWindowStyle(style))
622
+ defect(id, 'style_mismatch', `${style} is a door style; the window keeps a single pane.`);
623
+ const takesStyle = windowTakesStyle(windowType ?? 'fixed');
624
+ if (style && isWindowStyle(style) && !takesStyle)
625
+ say(`window ${id}: style ${style} dropped, a ${windowType} window draws its own sashes`);
626
+ opening = WindowNode.parse({
627
+ ...common,
628
+ type: 'window',
629
+ position: [x, o.sill + height / 2, 0],
630
+ ...(windowType ? windowTypeFields(windowType) : {}),
631
+ ...(style && isWindowStyle(style) && takesStyle ? getWindowStyleOverrides(style) : {}),
632
+ });
633
+ report.windows++;
634
+ }
635
+ const panel = o.kind === 'door' ? finishRef(o.color, id) : undefined;
636
+ const frame = finishRef(o.frameColor ?? o.color, id);
637
+ if (panel || frame)
638
+ opening = {
639
+ ...opening,
640
+ slots: {
641
+ ...('slots' in opening ? opening.slots : {}),
642
+ ...(panel ? { panel } : {}),
643
+ ...(frame ? { frame } : {}),
644
+ },
645
+ };
646
+ draft[opening.id] = opening;
647
+ report.ids[id] = opening.id;
648
+ node.children.push(opening.id);
649
+ });
650
+ }
651
+ // ---------- slabs and columns ----------
652
+ const slabs = level.slabs ?? [];
653
+ if (slabs.length > MANY_SLABS)
654
+ warn(`level/${index}`, 'many_slabs', `${slabs.length} slabs on "${level.name}": Pascal builds floor plates, caps and ceilings itself; a slab is a terrace, a platform, a balcony.`);
655
+ slabs.forEach((s, i) => {
656
+ const id = `slab/${index}/${i}`;
657
+ const label = s.name ? `"${s.name}"` : `slab ${i}`;
658
+ const polygon = s.polygon;
659
+ // A slab over a wall's footprint, higher than half the wall: a cap, which would lift the
660
+ // wall onto it. Pascal caps its walls itself.
661
+ const lifted = [...wallNodes.values()].find((w) => s.top > w.spec.height / 2 &&
662
+ polygonsOverlap(polygon, wallFootprint({ ...w, thickness: w.spec.thickness })));
663
+ if (lifted) {
664
+ defect(id, 'slab_over_wall', `${label} overlaps wall ${lifted.spec.id} with its top at ${metres(s.top)}, above half the wall's ${metres(lifted.spec.height)}: it would lift the wall onto it. Pascal builds a wall's cap itself; fold it into the wall.`);
665
+ return;
666
+ }
667
+ if (s.thickness < THIN_SLAB)
668
+ warn(id, 'thin_slab', `${label} is ${(s.thickness * 1000).toFixed(0)} mm thick: a slab is a terrace, a platform, a balcony; a finish goes on the room's floor.`);
669
+ const finish = finishRef(s.finish, id);
670
+ const node = SlabNode.parse({
671
+ object: 'node',
672
+ type: 'slab',
673
+ id: mint('slab', id),
674
+ parentId: levelNode.id,
675
+ visible: true,
676
+ metadata: { authorScene: { finish: s.finish ?? null } },
677
+ ...(s.name ? { name: s.name } : {}),
678
+ polygon: s.polygon,
679
+ elevation: s.top,
680
+ thickness: s.thickness,
681
+ ...(finish ? { slots: { surface: finish } } : {}),
682
+ ...(s.railing?.length
683
+ ? { railing: s.railing.map((r) => ({ start: r.start, end: r.end })) }
684
+ : {}),
685
+ });
686
+ place(node);
687
+ report.ids[id] = node.id;
688
+ report.slabs++;
689
+ });
690
+ (level.columns ?? []).forEach((c, i) => {
691
+ const node = ColumnNode.parse({
692
+ object: 'node',
693
+ type: 'column',
694
+ id: mint('column', `column/${index}/${i}`),
695
+ parentId: levelNode.id,
696
+ visible: true,
697
+ metadata: { authorScene: { color: c.color ?? null } },
698
+ ...(c.name ? { name: c.name } : {}),
699
+ position: [c.position[0], 0, c.position[1]],
700
+ crossSection: 'square',
701
+ width: c.width,
702
+ depth: c.depth,
703
+ height: c.height,
704
+ baseHeight: 0,
705
+ capitalHeight: 0,
706
+ });
707
+ place(node);
708
+ report.ids[`column/${index}/${i}`] = node.id;
709
+ report.columns++;
710
+ });
711
+ // ---------- items, hosts first ----------
712
+ const pending = [...(level.items ?? [])];
713
+ let progress = true;
714
+ while (pending.length && progress) {
715
+ progress = false;
716
+ for (const item of [...pending]) {
717
+ const hostItemId = item.host ? itemNodeIds.get(item.host) : undefined;
718
+ const hostWall = item.host && !hostItemId ? wallNodes.get(item.host) : undefined;
719
+ if (item.host && !hostItemId && !hostWall)
720
+ continue;
721
+ pending.splice(pending.indexOf(item), 1);
722
+ progress = true;
723
+ const compiled = input.compiled[item.id];
724
+ if (!compiled) {
725
+ defect(item.id, 'compile_failed', input.compileErrors?.[item.id] ?? 'The module did not compile.');
726
+ continue;
727
+ }
728
+ const world = [item.position[0], item.position[1], item.position[2]];
729
+ const yaw = (item.rotation * Math.PI) / 180;
730
+ let placed;
731
+ if (hostWall) {
732
+ // On the wall as place_items puts a wall-side item there: along it from its start, the
733
+ // payload's height for its bottom, on the face nearest the point, facing the room.
734
+ const [width, height] = scriptedSize(compiled.manifest);
735
+ const wallHeight = hostWall.spec.height;
736
+ if (height > wallHeight) {
737
+ defect(item.id, 'item_too_tall', `"${item.name}" is ${metres(height)} tall; wall ${item.host} is ${metres(wallHeight)}.`);
738
+ continue;
739
+ }
740
+ const length = dist(hostWall.start, hostWall.end);
741
+ const along = projectWorldPointToWallLocalX(hostWall, world);
742
+ const x = Math.max(width / 2, Math.min(length - width / 2, along));
743
+ const y = Math.max(0, Math.min(wallHeight - height, world[1]));
744
+ const [dx, dz] = [
745
+ hostWall.end[0] - hostWall.start[0],
746
+ hostWall.end[1] - hostWall.start[1],
747
+ ];
748
+ // The wall's left (its local +z) is its front.
749
+ const localZ = (-dz * (world[0] - hostWall.start[0]) + dx * (world[2] - hostWall.start[1])) / length;
750
+ const left = localZ >= 0;
751
+ const faceZ = getWallLocalFaceZ(hostWall.node, left ? 'a' : 'b');
752
+ const offset = (localZ - faceZ) * (left ? 1 : -1);
753
+ const z = faceZ + (left ? 1 : -1) * Math.max(0, offset);
754
+ if (offset < -1e-9)
755
+ say(`${item.id}: point inside wall ${item.host}, moved to its nearest face`);
756
+ if (item.rotation)
757
+ say(`${item.id}: rotation ignored on wall ${item.host}, it faces the room`);
758
+ const [ux, uz] = [dx / length, dz / length];
759
+ placed = {
760
+ compiled: { ...compiled, mount: 'wall-side' },
761
+ parentId: hostWall.node.id,
762
+ position: [x, y, z],
763
+ rotation: left ? 0 : 180,
764
+ side: left ? 'front' : 'back',
765
+ wallT: x / length,
766
+ frame: {
767
+ position: [
768
+ hostWall.start[0] + ux * x - uz * z,
769
+ y,
770
+ hostWall.start[1] + uz * x + ux * z,
771
+ ],
772
+ yaw: -Math.atan2(dz, dx) + (left ? 0 : Math.PI),
773
+ },
774
+ };
775
+ }
776
+ else {
777
+ const host = hostItemId ? itemFrames.get(item.host) : undefined;
778
+ placed = {
779
+ compiled,
780
+ parentId: hostItemId ?? levelNode.id,
781
+ position: host ? toLocal(host, world) : world,
782
+ rotation: host ? item.rotation - (host.yaw * 180) / Math.PI : item.rotation,
783
+ frame: { position: world, yaw },
784
+ };
785
+ }
786
+ try {
787
+ const outcome = addObject(draft, {
788
+ compiled: { ...placed.compiled, nodeId: mint('item', item.id) },
789
+ name: item.name,
790
+ category: item.category,
791
+ reason: `author_scene: ${item.name}`,
792
+ position: placed.position,
793
+ rotation: placed.rotation,
794
+ parentId: placed.parentId,
795
+ ...(placed.side ? { side: placed.side } : {}),
796
+ }, { ...context, activeLevelId: levelNode.id });
797
+ for (const { node, parentId } of outcome.changes?.create ?? []) {
798
+ draft[node.id] = {
799
+ ...node,
800
+ slots: exactSlots(compiled, item.id),
801
+ ...(placed.wallT === undefined ? {} : { wallT: placed.wallT }),
802
+ };
803
+ const parent = draft[parentId ?? levelNode.id];
804
+ parent.children = [...(parent.children ?? []), node.id];
805
+ itemNodeIds.set(item.id, node.id);
806
+ itemFrames.set(item.id, placed.frame);
807
+ report.ids[item.id] = node.id;
808
+ report.items++;
809
+ }
810
+ }
811
+ catch (error) {
812
+ const e = error;
813
+ defect(item.id, e.code ?? 'item_refused', e.message ?? String(error));
814
+ }
815
+ }
816
+ }
817
+ for (const item of pending)
818
+ defect(item.id, 'host_missing', `Its host ${item.host} was not placed.`);
819
+ // ---------- wall paint, through the editor's paint: both faces, or each its own ----------
820
+ for (const w of walls) {
821
+ const node = wallNodes.get(w.spec.id)?.node;
822
+ if (!node)
823
+ continue;
824
+ const faces = {
825
+ a: w.spec.colorLeft ?? w.spec.color,
826
+ b: w.spec.colorRight ?? w.spec.color,
827
+ };
828
+ const coats = [];
829
+ if (faces.a && faces.a === faces.b) {
830
+ const ref = finishRef(faces.a, w.spec.id);
831
+ if (ref)
832
+ coats.push({ material: ref });
833
+ }
834
+ else
835
+ for (const face of ['a', 'b']) {
836
+ const ref = finishRef(faces[face], w.spec.id);
837
+ if (ref)
838
+ coats.push({ role: face, material: ref });
839
+ }
840
+ for (const coat of coats) {
841
+ try {
842
+ const { changes } = paint(draft, { targets: [node.id], ...coat }, paintContext(levelNode.id));
843
+ for (const u of changes?.update ?? [])
844
+ draft[u.id] = { ...draft[u.id], ...u.data };
845
+ }
846
+ catch (error) {
847
+ defect(w.spec.id, 'paint_refused', error.message);
848
+ }
849
+ }
850
+ }
851
+ });
852
+ report.levels = levelNodes.length;
853
+ if (untypedWindows)
854
+ say(`${untypedWindows} window${untypedWindows === 1 ? ' has' : 's have'} no type: written fixed (cannot open); give type`);
855
+ // ---------- which face of each wall looks into a room: read from the plan, as the editor does ----------
856
+ for (const levelNode of levelNodes) {
857
+ const boundaries = Object.values(draft).filter((n) => n.parentId === levelNode.id && (n.type === 'wall' || n.type === 'separator'));
858
+ for (const { wallId, ...sides } of detectSpacesForLevel(levelNode.id, boundaries).wallUpdates)
859
+ draft[wallId] = { ...draft[wallId], ...sides };
860
+ }
861
+ // ---------- rooms: Pascal's own derivation, then the payload's names and floors ----------
862
+ const { nodes: withZones, createdZoneIds } = migrateRoomZones(draft);
863
+ const zones = createdZoneIds.map((id) => ZoneNode.parse(withZones[id]));
864
+ for (const zone of zones) {
865
+ draft[zone.id] = zone;
866
+ const level = draft[zone.parentId];
867
+ draft[zone.parentId] = { ...level, children: [...level.children, zone.id] };
868
+ report.rooms++;
869
+ }
870
+ const claimed = new Map();
871
+ payload.levels.forEach((level, index) => {
872
+ const levelNode = levelNodes[index];
873
+ for (const [i, room] of level.rooms.entries()) {
874
+ const id = `room/${index}/${i}`;
875
+ const zone = zones.find((z) => z.parentId === levelNode.id && pointInPolygon(room.seed, z.polygon));
876
+ // Two seeds in one enclosure: the walls do not separate the rooms the payload names.
877
+ if (zone && claimed.has(zone.id)) {
878
+ defect(id, 'room_shares_enclosure', `"${room.name}" and "${claimed.get(zone.id)}" are one enclosure: no wall separates them.`);
879
+ continue;
880
+ }
881
+ if (!zone) {
882
+ defect(id, 'room_not_enclosed', `No closed room around (${room.seed[0]}, ${room.seed[1]}) "${room.name}": its walls do not meet.`);
883
+ continue;
884
+ }
885
+ if (room.floorRegions.length > MANY_REGIONS)
886
+ warn(id, 'many_regions', `"${room.name}" has ${room.floorRegions.length} floor regions: regions are fixed polygons that do not follow a resize; use one floor finish.`);
887
+ const finish = finishRef(room.floor, id);
888
+ const regions = room.floorRegions.map((r, k) => ({
889
+ id: `region_${k}`,
890
+ polygon: r.polygon,
891
+ finish: finishRef(r.finish, id) ?? r.finish,
892
+ }));
893
+ draft[zone.id] = ZoneNode.parse({
894
+ ...zone,
895
+ name: room.name,
896
+ spaceRole: 'room',
897
+ ...(finish || regions.length
898
+ ? {
899
+ floor: {
900
+ ...zone.floor,
901
+ ...(finish ? { finish } : {}),
902
+ ...(regions.length ? { regions } : {}),
903
+ },
904
+ }
905
+ : {}),
906
+ metadata: { ...zone.metadata, authorScene: { seed: room.seed } },
907
+ });
908
+ claimed.set(zone.id, room.name);
909
+ report.ids[id] = zone.id;
910
+ report.roomsNamed++;
911
+ }
912
+ });
913
+ // ---------- floors and ceilings, as the editor derives them on load ----------
914
+ const structure = reconcileSceneStructure({
915
+ nodes: draft,
916
+ levelIds: levelNodes.map((l) => l.id),
917
+ mintId: (kind) => mint(kind),
918
+ });
919
+ const written = { ...structure.nodes };
920
+ // ---------- skirting, native on each wall, along the faces its rooms stand on ----------
921
+ for (const { id, nodeId, levelId, skirting } of skirtings) {
922
+ const finish = finishRef(skirting.color, id);
923
+ try {
924
+ const { changes } = setWallSkirting(written, {
925
+ wallIds: [nodeId],
926
+ height: skirting.height,
927
+ depth: skirting.depth,
928
+ ...(finish ? { finish } : {}),
929
+ }, paintContext(levelId));
930
+ for (const u of changes?.update ?? [])
931
+ written[u.id] = { ...written[u.id], ...u.data };
932
+ }
933
+ catch (error) {
934
+ const e = error;
935
+ defect(id, 'skirting_refused', e.code === 'side_unknown'
936
+ ? `No room stands on either face of wall ${id}: its skirting was not written.`
937
+ : `Wall ${id}: ${e.message ?? String(error)}`);
938
+ }
939
+ }
940
+ // ---------- face modules: which faces they build on is known now; the host compiles them ----------
941
+ const faces = resolveFaceScripts(payload, report.ids, written);
942
+ report.defects.push(...faces.defects);
943
+ report.warnings.push(...faces.warnings);
944
+ // Ceilings exist only after structure reconciliation; lights can now use their room's host.
945
+ payload.levels.forEach((level, index) => {
946
+ const levelNode = levelNodes[index];
947
+ for (const [i, light] of level.lights.entries()) {
948
+ const id = `light/${index}/${i}`;
949
+ const at = [light.position[0], light.position[1], light.position[2]];
950
+ let hostId = light.fixture ? itemNodeIds.get(light.fixture) : undefined;
951
+ let hostFrame = light.fixture ? itemFrames.get(light.fixture) : undefined;
952
+ const room = !light.fixture
953
+ ? Object.values(written).find((node) => node.type === 'zone' &&
954
+ node.spaceRole === 'room' &&
955
+ node.parentId === levelNode.id &&
956
+ pointInPolygon([at[0], at[2]], node.polygon) &&
957
+ !node.holes.some((hole) => pointInPolygon([at[0], at[2]], hole)))
958
+ : undefined;
959
+ const ceiling = room
960
+ ? Object.values(written).find((node) => node.type === 'ceiling' && node.zoneId === room.id && node.parentId === levelNode.id)
961
+ : undefined;
962
+ if (ceiling) {
963
+ const compiled = input.compiled[id];
964
+ if (!compiled) {
965
+ defect(id, 'compile_failed', input.compileErrors?.[id] ?? 'The ceiling point module did not compile.');
966
+ continue;
967
+ }
968
+ try {
969
+ const outcome = addObject(written, {
970
+ compiled: { ...compiled, nodeId: mint('item', id) },
971
+ name: `Ceiling point in ${room.name}`,
972
+ category: 'light',
973
+ reason: 'author_scene: ceiling point for a light without a fixture',
974
+ parentId: ceiling.id,
975
+ position: [at[0], 0, at[2]],
976
+ rotation: 0,
977
+ }, { ...context, activeLevelId: levelNode.id });
978
+ const node = outcome.changes.create[0].node;
979
+ written[node.id] = { ...node, slots: exactSlots(compiled, id) };
980
+ written[ceiling.id] = { ...ceiling, children: [...ceiling.children, node.id] };
981
+ hostId = node.id;
982
+ hostFrame = {
983
+ position: [at[0], resolveCeilingHeight(ceiling, written) - CEILING_DRAW_OFFSET, at[2]],
984
+ yaw: 0,
985
+ };
986
+ report.ids[id] = node.id;
987
+ report.items++;
988
+ say(`light at [${at.join(', ')}] has no fixture: a ceiling point in ${room.name}`);
989
+ }
990
+ catch (error) {
991
+ const e = error;
992
+ defect(id, e.code ?? 'item_refused', e.message ?? String(error));
993
+ continue;
994
+ }
995
+ }
996
+ if (!hostId) {
997
+ let best = null;
998
+ for (const item of level.items ?? []) {
999
+ const frame = itemFrames.get(item.id);
1000
+ if (!frame)
1001
+ continue;
1002
+ const d = Math.hypot(frame.position[0] - at[0], frame.position[2] - at[2]);
1003
+ if (!best || d < best.d)
1004
+ best = { key: item.id, d };
1005
+ }
1006
+ if (!best) {
1007
+ defect(id, 'light_unhosted', 'No item on this level to hold the light; Pascal keeps lights inside objects.');
1008
+ continue;
1009
+ }
1010
+ hostId = itemNodeIds.get(best.key);
1011
+ hostFrame = itemFrames.get(best.key);
1012
+ say(`light at [${at.join(', ')}] has no fixture: ${!light.fixture ? 'no room contains its point; ' : ''}hosted on the nearest item ${best.key} (${best.d.toFixed(2)} m away); moving that item moves the light`);
1013
+ }
1014
+ const hostNode = written[hostId];
1015
+ const interactive = hostNode.asset.interactive ?? { controls: [], effects: [] };
1016
+ const controls = interactive.controls.some((c) => c.kind === 'toggle')
1017
+ ? interactive.controls
1018
+ : [...interactive.controls, { kind: 'toggle', label: 'Lights', default: true }];
1019
+ const effects = [
1020
+ ...interactive.effects,
1021
+ {
1022
+ kind: 'light',
1023
+ color: light.color,
1024
+ intensityRange: [0, light.intensity],
1025
+ offset: toLocal(hostFrame, at),
1026
+ },
1027
+ ];
1028
+ written[hostNode.id] = {
1029
+ ...hostNode,
1030
+ asset: { ...hostNode.asset, interactive: { controls, effects } },
1031
+ };
1032
+ report.lights++;
1033
+ }
1034
+ });
1035
+ const nodes = Object.fromEntries(Object.entries(written).filter(([id]) => !scaffoldIds.has(id)));
1036
+ const candidate = {
1037
+ version: 1,
1038
+ buildingId: building.id,
1039
+ seed,
1040
+ ids: report.ids,
1041
+ nodes,
1042
+ };
1043
+ const outcome = {
1044
+ result: report,
1045
+ candidate,
1046
+ buildingId: building.id,
1047
+ changes: finishes.created.length ? { materials: finishes.created } : {},
1048
+ };
1049
+ return input.prepareOnly ? outcome : finalizeAuthorScene(scene, outcome);
1050
+ }
1051
+ /** Commit the complete candidate after the host has compiled all of its finishes. */
1052
+ export function finalizeAuthorScene(scene, outcome) {
1053
+ const building = scene[outcome.buildingId];
1054
+ if (building?.type !== 'building')
1055
+ refuse('no_building', 'The target building no longer exists.');
1056
+ const previous = building.metadata?.authorSceneState;
1057
+ const base = previous?.nodes ??
1058
+ Object.fromEntries(Object.values(scene)
1059
+ .filter((node) => node.type === 'level' && node.parentId === building.id)
1060
+ .map((node) => [node.id, node]));
1061
+ const changes = authoredSceneChanges(scene, base, outcome.candidate.nodes);
1062
+ return {
1063
+ ...outcome,
1064
+ changes: {
1065
+ ...changes,
1066
+ ...(outcome.changes?.materials ? { materials: outcome.changes.materials } : {}),
1067
+ update: [
1068
+ ...(changes.update ?? []),
1069
+ {
1070
+ id: building.id,
1071
+ data: { metadata: { ...building.metadata, authorSceneState: outcome.candidate } },
1072
+ },
1073
+ ],
1074
+ },
1075
+ };
1076
+ }