@pascal-app/nodes 1.0.0-beta.4 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (863) hide show
  1. package/LICENSE +21 -0
  2. package/dist/block/commands.d.ts +68 -0
  3. package/dist/block/commands.d.ts.map +1 -0
  4. package/dist/block/commands.js +1144 -0
  5. package/dist/block/contextual-help.d.ts +3 -0
  6. package/dist/block/contextual-help.d.ts.map +1 -0
  7. package/dist/block/contextual-help.js +38 -0
  8. package/dist/block/definition.d.ts +8 -0
  9. package/dist/block/definition.d.ts.map +1 -0
  10. package/dist/block/definition.js +126 -0
  11. package/dist/block/edit-session.d.ts +16 -0
  12. package/dist/block/edit-session.d.ts.map +1 -0
  13. package/dist/block/edit-session.js +32 -0
  14. package/dist/block/face-host.d.ts +3 -0
  15. package/dist/block/face-host.d.ts.map +1 -0
  16. package/dist/block/face-host.js +178 -0
  17. package/dist/block/floorplan.d.ts +3 -0
  18. package/dist/block/floorplan.d.ts.map +1 -0
  19. package/dist/block/floorplan.js +43 -0
  20. package/dist/block/geometry-snap.d.ts +18 -0
  21. package/dist/block/geometry-snap.d.ts.map +1 -0
  22. package/dist/block/geometry-snap.js +137 -0
  23. package/dist/block/geometry.d.ts +11 -0
  24. package/dist/block/geometry.d.ts.map +1 -0
  25. package/dist/block/geometry.js +146 -0
  26. package/dist/block/gesture-wheel.d.ts +8 -0
  27. package/dist/block/gesture-wheel.d.ts.map +1 -0
  28. package/dist/block/gesture-wheel.js +7 -0
  29. package/dist/block/interaction-sfx.d.ts +3 -0
  30. package/dist/block/interaction-sfx.d.ts.map +1 -0
  31. package/dist/block/interaction-sfx.js +16 -0
  32. package/dist/block/last-operation.d.ts +48 -0
  33. package/dist/block/last-operation.d.ts.map +1 -0
  34. package/dist/block/last-operation.js +120 -0
  35. package/dist/block/loop-cut-interaction.d.ts +5 -0
  36. package/dist/block/loop-cut-interaction.d.ts.map +1 -0
  37. package/dist/block/loop-cut-interaction.js +13 -0
  38. package/dist/block/material-slots.d.ts +61 -0
  39. package/dist/block/material-slots.d.ts.map +1 -0
  40. package/dist/block/material-slots.js +131 -0
  41. package/dist/block/modal-face-operation.d.ts +13 -0
  42. package/dist/block/modal-face-operation.d.ts.map +1 -0
  43. package/dist/block/modal-face-operation.js +40 -0
  44. package/dist/block/modal-session.d.ts +15 -0
  45. package/dist/block/modal-session.d.ts.map +1 -0
  46. package/dist/block/modal-session.js +40 -0
  47. package/dist/block/modal-transform.d.ts +30 -0
  48. package/dist/block/modal-transform.d.ts.map +1 -0
  49. package/dist/block/modal-transform.js +144 -0
  50. package/dist/block/paint.d.ts +3 -0
  51. package/dist/block/paint.d.ts.map +1 -0
  52. package/dist/block/paint.js +136 -0
  53. package/dist/block/panel.d.ts +2 -0
  54. package/dist/block/panel.d.ts.map +1 -0
  55. package/dist/block/panel.js +234 -0
  56. package/dist/block/parametrics.d.ts +4 -0
  57. package/dist/block/parametrics.d.ts.map +1 -0
  58. package/dist/block/parametrics.js +9 -0
  59. package/dist/block/preview.d.ts +6 -0
  60. package/dist/block/preview.d.ts.map +1 -0
  61. package/dist/block/preview.js +46 -0
  62. package/dist/block/rotation-drag.d.ts +5 -0
  63. package/dist/block/rotation-drag.d.ts.map +1 -0
  64. package/dist/block/rotation-drag.js +18 -0
  65. package/dist/block/schema.d.ts +2 -0
  66. package/dist/block/schema.d.ts.map +1 -0
  67. package/dist/block/schema.js +1 -0
  68. package/dist/block/selection-geometry.d.ts +9 -0
  69. package/dist/block/selection-geometry.d.ts.map +1 -0
  70. package/dist/block/selection-geometry.js +31 -0
  71. package/dist/block/selection-model.d.ts +17 -0
  72. package/dist/block/selection-model.d.ts.map +1 -0
  73. package/dist/block/selection-model.js +84 -0
  74. package/dist/block/selection.d.ts +4 -0
  75. package/dist/block/selection.d.ts.map +1 -0
  76. package/dist/block/selection.js +2570 -0
  77. package/dist/block/slots.d.ts +4 -0
  78. package/dist/block/slots.d.ts.map +1 -0
  79. package/dist/block/slots.js +17 -0
  80. package/dist/block/tool.d.ts +3 -0
  81. package/dist/block/tool.d.ts.map +1 -0
  82. package/dist/block/tool.js +174 -0
  83. package/dist/block/toolbar-state.d.ts +46 -0
  84. package/dist/block/toolbar-state.d.ts.map +1 -0
  85. package/dist/block/toolbar-state.js +67 -0
  86. package/dist/block/use-block-face-operation.d.ts +39 -0
  87. package/dist/block/use-block-face-operation.d.ts.map +1 -0
  88. package/dist/block/use-block-face-operation.js +218 -0
  89. package/dist/box-vent/definition.d.ts.map +1 -1
  90. package/dist/box-vent/definition.js +8 -5
  91. package/dist/box-vent/geometry.d.ts +4 -0
  92. package/dist/box-vent/geometry.d.ts.map +1 -1
  93. package/dist/box-vent/geometry.js +76 -44
  94. package/dist/box-vent/paint.d.ts +4 -0
  95. package/dist/box-vent/paint.d.ts.map +1 -0
  96. package/dist/box-vent/paint.js +40 -0
  97. package/dist/box-vent/panel.js +1 -1
  98. package/dist/box-vent/parametrics.js +3 -3
  99. package/dist/box-vent/renderer.d.ts.map +1 -1
  100. package/dist/box-vent/renderer.js +29 -10
  101. package/dist/cabinet/compartment-card.d.ts.map +1 -1
  102. package/dist/cabinet/compartment-card.js +11 -3
  103. package/dist/cabinet/continuous-placement.d.ts +3 -0
  104. package/dist/cabinet/continuous-placement.d.ts.map +1 -1
  105. package/dist/cabinet/continuous-placement.js +6 -0
  106. package/dist/cabinet/definition.d.ts.map +1 -1
  107. package/dist/cabinet/definition.js +400 -54
  108. package/dist/cabinet/flame-index.d.ts +3 -0
  109. package/dist/cabinet/flame-index.d.ts.map +1 -0
  110. package/dist/cabinet/flame-index.js +13 -0
  111. package/dist/cabinet/floorplan-move.d.ts.map +1 -1
  112. package/dist/cabinet/floorplan-move.js +91 -22
  113. package/dist/cabinet/geometry/fridge.d.ts.map +1 -1
  114. package/dist/cabinet/geometry/fridge.js +25 -1
  115. package/dist/cabinet/geometry/fronts.d.ts +4 -0
  116. package/dist/cabinet/geometry/fronts.d.ts.map +1 -1
  117. package/dist/cabinet/geometry/fronts.js +1 -1
  118. package/dist/cabinet/geometry/run.d.ts.map +1 -1
  119. package/dist/cabinet/geometry/run.js +19 -1
  120. package/dist/cabinet/geometry.d.ts.map +1 -1
  121. package/dist/cabinet/geometry.js +63 -1
  122. package/dist/cabinet/index.d.ts +1 -0
  123. package/dist/cabinet/index.d.ts.map +1 -1
  124. package/dist/cabinet/index.js +1 -0
  125. package/dist/cabinet/insertion.d.ts +19 -0
  126. package/dist/cabinet/insertion.d.ts.map +1 -0
  127. package/dist/cabinet/insertion.js +49 -0
  128. package/dist/cabinet/move-frame.d.ts.map +1 -1
  129. package/dist/cabinet/move-frame.js +68 -2
  130. package/dist/cabinet/panel-context.d.ts +7 -0
  131. package/dist/cabinet/panel-context.d.ts.map +1 -0
  132. package/dist/cabinet/panel-context.js +16 -0
  133. package/dist/cabinet/panel-visibility.d.ts +9 -0
  134. package/dist/cabinet/panel-visibility.d.ts.map +1 -0
  135. package/dist/cabinet/panel-visibility.js +26 -0
  136. package/dist/cabinet/panel.d.ts.map +1 -1
  137. package/dist/cabinet/panel.js +221 -37
  138. package/dist/cabinet/placement-dimensions.d.ts +42 -0
  139. package/dist/cabinet/placement-dimensions.d.ts.map +1 -0
  140. package/dist/cabinet/placement-dimensions.js +227 -0
  141. package/dist/cabinet/placement-snap.d.ts +21 -1
  142. package/dist/cabinet/placement-snap.d.ts.map +1 -1
  143. package/dist/cabinet/placement-snap.js +48 -6
  144. package/dist/cabinet/preset-width-debt.d.ts +7 -0
  145. package/dist/cabinet/preset-width-debt.d.ts.map +1 -0
  146. package/dist/cabinet/preset-width-debt.js +45 -0
  147. package/dist/cabinet/presets.d.ts.map +1 -1
  148. package/dist/cabinet/presets.js +14 -13
  149. package/dist/cabinet/profiles.d.ts +14 -0
  150. package/dist/cabinet/profiles.d.ts.map +1 -0
  151. package/dist/cabinet/profiles.js +30 -0
  152. package/dist/cabinet/quick-actions.d.ts.map +1 -1
  153. package/dist/cabinet/quick-actions.js +8 -24
  154. package/dist/cabinet/reveals.d.ts +37 -0
  155. package/dist/cabinet/reveals.d.ts.map +1 -0
  156. package/dist/cabinet/reveals.js +13 -0
  157. package/dist/cabinet/run-layout.d.ts +90 -4
  158. package/dist/cabinet/run-layout.d.ts.map +1 -1
  159. package/dist/cabinet/run-layout.js +408 -23
  160. package/dist/cabinet/run-ops.d.ts +202 -10
  161. package/dist/cabinet/run-ops.d.ts.map +1 -1
  162. package/dist/cabinet/run-ops.js +520 -33
  163. package/dist/cabinet/run-panel.d.ts +6 -2
  164. package/dist/cabinet/run-panel.d.ts.map +1 -1
  165. package/dist/cabinet/run-panel.js +285 -108
  166. package/dist/cabinet/stack-transitions.d.ts.map +1 -1
  167. package/dist/cabinet/stack-transitions.js +35 -24
  168. package/dist/cabinet/stack.d.ts +169 -1
  169. package/dist/cabinet/stack.d.ts.map +1 -1
  170. package/dist/cabinet/stack.js +57 -18
  171. package/dist/cabinet/system.d.ts +2 -0
  172. package/dist/cabinet/system.d.ts.map +1 -1
  173. package/dist/cabinet/system.js +28 -8
  174. package/dist/cabinet/tool.d.ts.map +1 -1
  175. package/dist/cabinet/tool.js +616 -91
  176. package/dist/cabinet/validation.d.ts +27 -0
  177. package/dist/cabinet/validation.d.ts.map +1 -0
  178. package/dist/cabinet/validation.js +56 -0
  179. package/dist/cabinet/wall-height-presets.d.ts +12 -0
  180. package/dist/cabinet/wall-height-presets.d.ts.map +1 -0
  181. package/dist/cabinet/wall-height-presets.js +15 -0
  182. package/dist/cabinet/wall-snap.d.ts +27 -3
  183. package/dist/cabinet/wall-snap.d.ts.map +1 -1
  184. package/dist/cabinet/wall-snap.js +278 -62
  185. package/dist/cabinet/widths.d.ts +10 -0
  186. package/dist/cabinet/widths.d.ts.map +1 -0
  187. package/dist/cabinet/widths.js +13 -0
  188. package/dist/ceiling/definition.d.ts.map +1 -1
  189. package/dist/ceiling/definition.js +7 -1
  190. package/dist/ceiling/floorplan-affordances.d.ts +8 -8
  191. package/dist/ceiling/materials.d.ts.map +1 -1
  192. package/dist/ceiling/materials.js +0 -1
  193. package/dist/ceiling/panel.d.ts.map +1 -1
  194. package/dist/ceiling/panel.js +8 -2
  195. package/dist/ceiling/parametrics.js +1 -1
  196. package/dist/chimney/definition.js +1 -1
  197. package/dist/chimney/panel.js +1 -1
  198. package/dist/chimney/parametrics.js +3 -3
  199. package/dist/column/definition.d.ts.map +1 -1
  200. package/dist/column/definition.js +22 -4
  201. package/dist/column/panel.d.ts.map +1 -1
  202. package/dist/column/panel.js +37 -7
  203. package/dist/column/parametrics.d.ts.map +1 -1
  204. package/dist/column/parametrics.js +5 -3
  205. package/dist/column/tool.d.ts.map +1 -1
  206. package/dist/column/tool.js +50 -14
  207. package/dist/cupola/definition.d.ts.map +1 -1
  208. package/dist/cupola/definition.js +15 -6
  209. package/dist/cupola/geometry.d.ts +6 -0
  210. package/dist/cupola/geometry.d.ts.map +1 -1
  211. package/dist/cupola/geometry.js +60 -13
  212. package/dist/cupola/paint.d.ts +4 -0
  213. package/dist/cupola/paint.d.ts.map +1 -0
  214. package/dist/cupola/paint.js +39 -0
  215. package/dist/cupola/panel.js +1 -1
  216. package/dist/cupola/parametrics.js +3 -3
  217. package/dist/cupola/renderer.d.ts.map +1 -1
  218. package/dist/cupola/renderer.js +27 -8
  219. package/dist/door/floorplan-move.d.ts.map +1 -1
  220. package/dist/door/floorplan-move.js +1 -1
  221. package/dist/door/move-tool.d.ts.map +1 -1
  222. package/dist/door/move-tool.js +86 -32
  223. package/dist/door/panel.d.ts.map +1 -1
  224. package/dist/door/panel.js +1 -1
  225. package/dist/door/parametrics.js +2 -2
  226. package/dist/door/tool.d.ts.map +1 -1
  227. package/dist/door/tool.js +16 -4
  228. package/dist/dormer/csg-geometry.d.ts +6 -42
  229. package/dist/dormer/csg-geometry.d.ts.map +1 -1
  230. package/dist/dormer/csg-geometry.js +38 -209
  231. package/dist/dormer/definition.d.ts +4 -12
  232. package/dist/dormer/definition.d.ts.map +1 -1
  233. package/dist/dormer/definition.js +18 -193
  234. package/dist/dormer/floorplan.d.ts +3 -3
  235. package/dist/dormer/floorplan.d.ts.map +1 -1
  236. package/dist/dormer/floorplan.js +6 -17
  237. package/dist/dormer/geometry.d.ts +5 -24
  238. package/dist/dormer/geometry.d.ts.map +1 -1
  239. package/dist/dormer/geometry.js +64 -41
  240. package/dist/dormer/index.d.ts +1 -1
  241. package/dist/dormer/index.d.ts.map +1 -1
  242. package/dist/dormer/index.js +1 -1
  243. package/dist/dormer/move-tool.d.ts.map +1 -1
  244. package/dist/dormer/move-tool.js +31 -3
  245. package/dist/dormer/panel-windows-section.d.ts +9 -0
  246. package/dist/dormer/panel-windows-section.d.ts.map +1 -0
  247. package/dist/dormer/panel-windows-section.js +7 -0
  248. package/dist/dormer/panel.d.ts.map +1 -1
  249. package/dist/dormer/panel.js +100 -18
  250. package/dist/dormer/parametrics.d.ts.map +1 -1
  251. package/dist/dormer/parametrics.js +8 -77
  252. package/dist/dormer/placement-guides.d.ts.map +1 -1
  253. package/dist/dormer/placement-guides.js +5 -4
  254. package/dist/dormer/preview.d.ts.map +1 -1
  255. package/dist/dormer/preview.js +9 -1
  256. package/dist/dormer/renderer.d.ts.map +1 -1
  257. package/dist/dormer/renderer.js +24 -26
  258. package/dist/dormer/tool.d.ts.map +1 -1
  259. package/dist/dormer/tool.js +3 -1
  260. package/dist/dormer/window-layout.d.ts +15 -0
  261. package/dist/dormer/window-layout.d.ts.map +1 -0
  262. package/dist/dormer/window-layout.js +59 -0
  263. package/dist/downspout/definition.d.ts.map +1 -1
  264. package/dist/downspout/definition.js +17 -4
  265. package/dist/downspout/geometry.d.ts.map +1 -1
  266. package/dist/downspout/geometry.js +10 -0
  267. package/dist/downspout/inspector-editors.d.ts.map +1 -1
  268. package/dist/downspout/inspector-editors.js +9 -1
  269. package/dist/downspout/parametrics.d.ts.map +1 -1
  270. package/dist/downspout/parametrics.js +2 -1
  271. package/dist/downspout/renderer.d.ts.map +1 -1
  272. package/dist/downspout/renderer.js +19 -3
  273. package/dist/downspout/system.d.ts +7 -0
  274. package/dist/downspout/system.d.ts.map +1 -0
  275. package/dist/downspout/system.js +114 -0
  276. package/dist/duct-fitting/accessory-geometry.d.ts +4 -0
  277. package/dist/duct-fitting/accessory-geometry.d.ts.map +1 -0
  278. package/dist/duct-fitting/accessory-geometry.js +47 -0
  279. package/dist/duct-fitting/definition.d.ts.map +1 -1
  280. package/dist/duct-fitting/definition.js +11 -1
  281. package/dist/duct-fitting/floorplan.d.ts.map +1 -1
  282. package/dist/duct-fitting/floorplan.js +8 -0
  283. package/dist/duct-fitting/geometry.d.ts.map +1 -1
  284. package/dist/duct-fitting/geometry.js +52 -38
  285. package/dist/duct-fitting/parametrics.d.ts.map +1 -1
  286. package/dist/duct-fitting/parametrics.js +78 -15
  287. package/dist/duct-fitting/ports.d.ts +1 -0
  288. package/dist/duct-fitting/ports.d.ts.map +1 -1
  289. package/dist/duct-fitting/ports.js +46 -0
  290. package/dist/duct-fitting/tool.d.ts +19 -0
  291. package/dist/duct-fitting/tool.d.ts.map +1 -1
  292. package/dist/duct-fitting/tool.js +126 -34
  293. package/dist/duct-segment/continuation.d.ts +21 -0
  294. package/dist/duct-segment/continuation.d.ts.map +1 -0
  295. package/dist/duct-segment/continuation.js +167 -0
  296. package/dist/duct-segment/definition.d.ts.map +1 -1
  297. package/dist/duct-segment/definition.js +19 -18
  298. package/dist/duct-segment/floorplan.d.ts.map +1 -1
  299. package/dist/duct-segment/floorplan.js +43 -0
  300. package/dist/duct-segment/geometry.d.ts.map +1 -1
  301. package/dist/duct-segment/geometry.js +3 -0
  302. package/dist/duct-segment/move-tool.d.ts.map +1 -1
  303. package/dist/duct-segment/move-tool.js +33 -6
  304. package/dist/duct-segment/parametrics.d.ts.map +1 -1
  305. package/dist/duct-segment/parametrics.js +45 -1
  306. package/dist/duct-segment/selection.d.ts +3 -4
  307. package/dist/duct-segment/selection.d.ts.map +1 -1
  308. package/dist/duct-segment/selection.js +186 -158
  309. package/dist/duct-segment/tool.d.ts +37 -0
  310. package/dist/duct-segment/tool.d.ts.map +1 -1
  311. package/dist/duct-segment/tool.js +305 -678
  312. package/dist/duct-terminal/parametrics.js +2 -2
  313. package/dist/duct-terminal/tool.d.ts.map +1 -1
  314. package/dist/duct-terminal/tool.js +37 -7
  315. package/dist/elevator/definition.d.ts.map +1 -1
  316. package/dist/elevator/definition.js +2 -0
  317. package/dist/elevator/panel.d.ts.map +1 -1
  318. package/dist/elevator/panel.js +7 -7
  319. package/dist/elevator/system.d.ts.map +1 -1
  320. package/dist/elevator/system.js +10 -1
  321. package/dist/eyebrow-vent/definition.d.ts.map +1 -1
  322. package/dist/eyebrow-vent/definition.js +8 -5
  323. package/dist/eyebrow-vent/geometry.d.ts +4 -0
  324. package/dist/eyebrow-vent/geometry.d.ts.map +1 -1
  325. package/dist/eyebrow-vent/geometry.js +60 -15
  326. package/dist/eyebrow-vent/paint.d.ts +4 -0
  327. package/dist/eyebrow-vent/paint.d.ts.map +1 -0
  328. package/dist/eyebrow-vent/paint.js +33 -0
  329. package/dist/eyebrow-vent/panel.js +1 -1
  330. package/dist/eyebrow-vent/parametrics.js +3 -3
  331. package/dist/eyebrow-vent/renderer.d.ts.map +1 -1
  332. package/dist/eyebrow-vent/renderer.js +27 -8
  333. package/dist/fence/curve-tool.d.ts.map +1 -1
  334. package/dist/fence/curve-tool.js +14 -9
  335. package/dist/fence/definition.d.ts.map +1 -1
  336. package/dist/fence/definition.js +2 -1
  337. package/dist/fence/floorplan-affordances.d.ts +1 -0
  338. package/dist/fence/floorplan-affordances.d.ts.map +1 -1
  339. package/dist/fence/floorplan-affordances.js +30 -1
  340. package/dist/fence/floorplan.d.ts.map +1 -1
  341. package/dist/fence/floorplan.js +14 -0
  342. package/dist/fence/move-control-point-tool.d.ts.map +1 -1
  343. package/dist/fence/move-control-point-tool.js +13 -8
  344. package/dist/fence/move-tangent-tool.d.ts.map +1 -1
  345. package/dist/fence/move-tangent-tool.js +13 -8
  346. package/dist/fence/parametrics.js +3 -3
  347. package/dist/fence/tool.d.ts.map +1 -1
  348. package/dist/fence/tool.js +55 -31
  349. package/dist/gutter/corner-mitre.d.ts.map +1 -1
  350. package/dist/gutter/corner-mitre.js +47 -7
  351. package/dist/gutter/definition.d.ts.map +1 -1
  352. package/dist/gutter/definition.js +23 -13
  353. package/dist/gutter/eave-align.d.ts.map +1 -1
  354. package/dist/gutter/eave-align.js +10 -0
  355. package/dist/gutter/eave-snap.d.ts +1 -1
  356. package/dist/gutter/eave-snap.d.ts.map +1 -1
  357. package/dist/gutter/eave-snap.js +10 -23
  358. package/dist/gutter/geometry.d.ts.map +1 -1
  359. package/dist/gutter/geometry.js +126 -8
  360. package/dist/gutter/outlet-lookup.d.ts.map +1 -1
  361. package/dist/gutter/outlet-lookup.js +22 -1
  362. package/dist/gutter/paint.d.ts +3 -0
  363. package/dist/gutter/paint.d.ts.map +1 -0
  364. package/dist/gutter/paint.js +6 -0
  365. package/dist/gutter/parametrics.d.ts.map +1 -1
  366. package/dist/gutter/parametrics.js +4 -1
  367. package/dist/gutter/renderer.d.ts.map +1 -1
  368. package/dist/gutter/renderer.js +63 -7
  369. package/dist/gutter/trim-clip.d.ts +3 -0
  370. package/dist/gutter/trim-clip.d.ts.map +1 -0
  371. package/dist/gutter/trim-clip.js +5 -0
  372. package/dist/hvac-equipment/parametrics.js +3 -3
  373. package/dist/hvac-equipment/tool.d.ts.map +1 -1
  374. package/dist/hvac-equipment/tool.js +12 -2
  375. package/dist/index.d.ts +5 -2
  376. package/dist/index.d.ts.map +1 -1
  377. package/dist/index.js +9 -2
  378. package/dist/item/definition.d.ts.map +1 -1
  379. package/dist/item/definition.js +10 -2
  380. package/dist/item/floorplan-move.d.ts.map +1 -1
  381. package/dist/item/floorplan-move.js +20 -1
  382. package/dist/item/floorplan.d.ts.map +1 -1
  383. package/dist/item/floorplan.js +22 -1
  384. package/dist/item/move-tool.d.ts +28 -1
  385. package/dist/item/move-tool.d.ts.map +1 -1
  386. package/dist/item/move-tool.js +14 -2
  387. package/dist/item/renderer.d.ts.map +1 -1
  388. package/dist/item/renderer.js +16 -6
  389. package/dist/item/system.d.ts +5 -0
  390. package/dist/item/system.d.ts.map +1 -1
  391. package/dist/item/system.js +7 -1
  392. package/dist/lean-to-extension/arc.d.ts +14 -0
  393. package/dist/lean-to-extension/arc.d.ts.map +1 -0
  394. package/dist/lean-to-extension/arc.js +56 -0
  395. package/dist/lean-to-extension/assembly.d.ts +61 -0
  396. package/dist/lean-to-extension/assembly.d.ts.map +1 -0
  397. package/dist/lean-to-extension/assembly.js +761 -0
  398. package/dist/lean-to-extension/canopy-joint.d.ts +35 -0
  399. package/dist/lean-to-extension/canopy-joint.d.ts.map +1 -0
  400. package/dist/lean-to-extension/canopy-joint.js +234 -0
  401. package/dist/lean-to-extension/conical-host.d.ts +15 -0
  402. package/dist/lean-to-extension/conical-host.d.ts.map +1 -0
  403. package/dist/lean-to-extension/conical-host.js +113 -0
  404. package/dist/lean-to-extension/corner-joint.d.ts +29 -0
  405. package/dist/lean-to-extension/corner-joint.d.ts.map +1 -0
  406. package/dist/lean-to-extension/corner-joint.js +1202 -0
  407. package/dist/lean-to-extension/definition.d.ts +4 -0
  408. package/dist/lean-to-extension/definition.d.ts.map +1 -0
  409. package/dist/lean-to-extension/definition.js +433 -0
  410. package/dist/lean-to-extension/floorplan-affordances.d.ts +4 -0
  411. package/dist/lean-to-extension/floorplan-affordances.d.ts.map +1 -0
  412. package/dist/lean-to-extension/floorplan-affordances.js +144 -0
  413. package/dist/lean-to-extension/floorplan-move.d.ts +3 -0
  414. package/dist/lean-to-extension/floorplan-move.d.ts.map +1 -0
  415. package/dist/lean-to-extension/floorplan-move.js +157 -0
  416. package/dist/lean-to-extension/floorplan-tool.d.ts +4 -0
  417. package/dist/lean-to-extension/floorplan-tool.d.ts.map +1 -0
  418. package/dist/lean-to-extension/floorplan-tool.js +385 -0
  419. package/dist/lean-to-extension/floorplan.d.ts +3 -0
  420. package/dist/lean-to-extension/floorplan.d.ts.map +1 -0
  421. package/dist/lean-to-extension/floorplan.js +373 -0
  422. package/dist/lean-to-extension/geometry.d.ts +7 -0
  423. package/dist/lean-to-extension/geometry.d.ts.map +1 -0
  424. package/dist/lean-to-extension/geometry.js +662 -0
  425. package/dist/lean-to-extension/index.d.ts +8 -0
  426. package/dist/lean-to-extension/index.d.ts.map +1 -0
  427. package/dist/lean-to-extension/index.js +7 -0
  428. package/dist/lean-to-extension/layout.d.ts +108 -0
  429. package/dist/lean-to-extension/layout.d.ts.map +1 -0
  430. package/dist/lean-to-extension/layout.js +477 -0
  431. package/dist/lean-to-extension/managed-preview.d.ts +3 -0
  432. package/dist/lean-to-extension/managed-preview.d.ts.map +1 -0
  433. package/dist/lean-to-extension/managed-preview.js +93 -0
  434. package/dist/lean-to-extension/move-tool.d.ts +8 -0
  435. package/dist/lean-to-extension/move-tool.d.ts.map +1 -0
  436. package/dist/lean-to-extension/move-tool.js +202 -0
  437. package/dist/lean-to-extension/paint.d.ts +2 -0
  438. package/dist/lean-to-extension/paint.d.ts.map +1 -0
  439. package/dist/lean-to-extension/paint.js +16 -0
  440. package/dist/lean-to-extension/parametrics.d.ts +4 -0
  441. package/dist/lean-to-extension/parametrics.d.ts.map +1 -0
  442. package/dist/lean-to-extension/parametrics.js +570 -0
  443. package/dist/lean-to-extension/placement-scope.d.ts +3 -0
  444. package/dist/lean-to-extension/placement-scope.d.ts.map +1 -0
  445. package/dist/lean-to-extension/placement-scope.js +4 -0
  446. package/dist/lean-to-extension/placement-validation.d.ts +4 -0
  447. package/dist/lean-to-extension/placement-validation.d.ts.map +1 -0
  448. package/dist/lean-to-extension/placement-validation.js +324 -0
  449. package/dist/lean-to-extension/placement.d.ts +59 -0
  450. package/dist/lean-to-extension/placement.d.ts.map +1 -0
  451. package/dist/lean-to-extension/placement.js +331 -0
  452. package/dist/lean-to-extension/plan-footprint.d.ts +10 -0
  453. package/dist/lean-to-extension/plan-footprint.d.ts.map +1 -0
  454. package/dist/lean-to-extension/plan-footprint.js +27 -0
  455. package/dist/lean-to-extension/preview-geometry.d.ts +7 -0
  456. package/dist/lean-to-extension/preview-geometry.d.ts.map +1 -0
  457. package/dist/lean-to-extension/preview-geometry.js +40 -0
  458. package/dist/lean-to-extension/preview.d.ts +7 -0
  459. package/dist/lean-to-extension/preview.d.ts.map +1 -0
  460. package/dist/lean-to-extension/preview.js +20 -0
  461. package/dist/lean-to-extension/renderer.d.ts +6 -0
  462. package/dist/lean-to-extension/renderer.d.ts.map +1 -0
  463. package/dist/lean-to-extension/renderer.js +34 -0
  464. package/dist/lean-to-extension/roof-attachment.d.ts +28 -0
  465. package/dist/lean-to-extension/roof-attachment.d.ts.map +1 -0
  466. package/dist/lean-to-extension/roof-attachment.js +376 -0
  467. package/dist/lean-to-extension/schema.d.ts +2 -0
  468. package/dist/lean-to-extension/schema.d.ts.map +1 -0
  469. package/dist/lean-to-extension/schema.js +1 -0
  470. package/dist/lean-to-extension/slots.d.ts +5 -0
  471. package/dist/lean-to-extension/slots.d.ts.map +1 -0
  472. package/dist/lean-to-extension/slots.js +15 -0
  473. package/dist/lean-to-extension/system.d.ts +7 -0
  474. package/dist/lean-to-extension/system.d.ts.map +1 -0
  475. package/dist/lean-to-extension/system.js +726 -0
  476. package/dist/lean-to-extension/tool.d.ts +3 -0
  477. package/dist/lean-to-extension/tool.d.ts.map +1 -0
  478. package/dist/lean-to-extension/tool.js +580 -0
  479. package/dist/lean-to-extension/wall-target.d.ts +10 -0
  480. package/dist/lean-to-extension/wall-target.d.ts.map +1 -0
  481. package/dist/lean-to-extension/wall-target.js +29 -0
  482. package/dist/lineset/definition.d.ts.map +1 -1
  483. package/dist/lineset/definition.js +1 -0
  484. package/dist/liquid-line/definition.d.ts.map +1 -1
  485. package/dist/liquid-line/definition.js +1 -0
  486. package/dist/measurement/renderer.d.ts.map +1 -1
  487. package/dist/measurement/renderer.js +6 -5
  488. package/dist/measurement/surface-query.js +5 -5
  489. package/dist/measurement/tool.d.ts.map +1 -1
  490. package/dist/measurement/tool.js +7 -5
  491. package/dist/pipe-fitting/definition.d.ts.map +1 -1
  492. package/dist/pipe-fitting/definition.js +16 -2
  493. package/dist/pipe-fitting/floorplan.d.ts.map +1 -1
  494. package/dist/pipe-fitting/floorplan.js +4 -0
  495. package/dist/pipe-fitting/geometry.d.ts +3 -5
  496. package/dist/pipe-fitting/geometry.d.ts.map +1 -1
  497. package/dist/pipe-fitting/geometry.js +154 -21
  498. package/dist/pipe-fitting/inline-insertion.d.ts +13 -0
  499. package/dist/pipe-fitting/inline-insertion.d.ts.map +1 -0
  500. package/dist/pipe-fitting/inline-insertion.js +96 -0
  501. package/dist/pipe-fitting/parametrics.d.ts.map +1 -1
  502. package/dist/pipe-fitting/parametrics.js +17 -3
  503. package/dist/pipe-fitting/ports.d.ts.map +1 -1
  504. package/dist/pipe-fitting/ports.js +8 -1
  505. package/dist/pipe-fitting/tool.d.ts +26 -0
  506. package/dist/pipe-fitting/tool.d.ts.map +1 -1
  507. package/dist/pipe-fitting/tool.js +182 -37
  508. package/dist/pipe-segment/continuation.d.ts +22 -0
  509. package/dist/pipe-segment/continuation.d.ts.map +1 -0
  510. package/dist/pipe-segment/continuation.js +146 -0
  511. package/dist/pipe-segment/definition.d.ts.map +1 -1
  512. package/dist/pipe-segment/definition.js +23 -7
  513. package/dist/pipe-segment/floorplan.d.ts.map +1 -1
  514. package/dist/pipe-segment/floorplan.js +42 -0
  515. package/dist/pipe-segment/geometry.d.ts +2 -1
  516. package/dist/pipe-segment/geometry.d.ts.map +1 -1
  517. package/dist/pipe-segment/geometry.js +4 -1
  518. package/dist/pipe-segment/move-tool.d.ts.map +1 -1
  519. package/dist/pipe-segment/move-tool.js +25 -5
  520. package/dist/pipe-segment/parametrics.d.ts.map +1 -1
  521. package/dist/pipe-segment/parametrics.js +45 -0
  522. package/dist/pipe-segment/selection.d.ts +3 -4
  523. package/dist/pipe-segment/selection.d.ts.map +1 -1
  524. package/dist/pipe-segment/selection.js +169 -105
  525. package/dist/pipe-segment/slope.d.ts +5 -0
  526. package/dist/pipe-segment/slope.d.ts.map +1 -0
  527. package/dist/pipe-segment/slope.js +10 -0
  528. package/dist/pipe-segment/tool.d.ts.map +1 -1
  529. package/dist/pipe-segment/tool.js +325 -545
  530. package/dist/pipe-trap/tool.d.ts.map +1 -1
  531. package/dist/pipe-trap/tool.js +15 -2
  532. package/dist/ridge-vent/definition.js +1 -1
  533. package/dist/ridge-vent/panel.d.ts.map +1 -1
  534. package/dist/ridge-vent/panel.js +2 -2
  535. package/dist/ridge-vent/parametrics.js +1 -1
  536. package/dist/ridge-vent/renderer.d.ts.map +1 -1
  537. package/dist/ridge-vent/renderer.js +2 -2
  538. package/dist/roof/conical-roof-placement.d.ts +36 -0
  539. package/dist/roof/conical-roof-placement.d.ts.map +1 -0
  540. package/dist/roof/conical-roof-placement.js +134 -0
  541. package/dist/roof/conical-roof.d.ts +3 -0
  542. package/dist/roof/conical-roof.d.ts.map +1 -0
  543. package/dist/roof/conical-roof.js +53 -0
  544. package/dist/roof/definition.d.ts +3 -10
  545. package/dist/roof/definition.d.ts.map +1 -1
  546. package/dist/roof/definition.js +83 -13
  547. package/dist/roof/floorplan.d.ts +3 -10
  548. package/dist/roof/floorplan.d.ts.map +1 -1
  549. package/dist/roof/floorplan.js +139 -165
  550. package/dist/roof/index.d.ts +1 -0
  551. package/dist/roof/index.d.ts.map +1 -1
  552. package/dist/roof/index.js +1 -0
  553. package/dist/roof/panel.d.ts.map +1 -1
  554. package/dist/roof/panel.js +22 -23
  555. package/dist/roof/renderer.d.ts.map +1 -1
  556. package/dist/roof/roof-footprint-source.d.ts +16 -0
  557. package/dist/roof/roof-footprint-source.d.ts.map +1 -0
  558. package/dist/roof/roof-footprint-source.js +14 -0
  559. package/dist/roof/roof-footprint.d.ts +25 -0
  560. package/dist/roof/roof-footprint.d.ts.map +1 -0
  561. package/dist/roof/roof-footprint.js +94 -0
  562. package/dist/roof/roof-placement-mode.d.ts +18 -0
  563. package/dist/roof/roof-placement-mode.d.ts.map +1 -0
  564. package/dist/roof/roof-placement-mode.js +24 -0
  565. package/dist/roof/tool.d.ts +10 -0
  566. package/dist/roof/tool.d.ts.map +1 -0
  567. package/dist/roof/tool.js +922 -0
  568. package/dist/roof-segment/definition.d.ts.map +1 -1
  569. package/dist/roof-segment/definition.js +52 -8
  570. package/dist/roof-segment/floorplan-affordances.d.ts +5 -6
  571. package/dist/roof-segment/floorplan-affordances.d.ts.map +1 -1
  572. package/dist/roof-segment/floorplan-affordances.js +64 -18
  573. package/dist/roof-segment/floorplan.d.ts +3 -2
  574. package/dist/roof-segment/floorplan.d.ts.map +1 -1
  575. package/dist/roof-segment/floorplan.js +95 -46
  576. package/dist/roof-segment/panel.d.ts.map +1 -1
  577. package/dist/roof-segment/panel.js +122 -27
  578. package/dist/scan/definition.d.ts +2 -3
  579. package/dist/scan/definition.d.ts.map +1 -1
  580. package/dist/scan/definition.js +9 -7
  581. package/dist/scan/parametrics.d.ts.map +1 -1
  582. package/dist/scan/parametrics.js +13 -1
  583. package/dist/scan/renderer.d.ts.map +1 -1
  584. package/dist/scan/renderer.js +8 -2
  585. package/dist/shared/accessory-cursor.d.ts +7 -0
  586. package/dist/shared/accessory-cursor.d.ts.map +1 -0
  587. package/dist/shared/accessory-cursor.js +83 -0
  588. package/dist/shared/accessory-floorplan.d.ts +4 -0
  589. package/dist/shared/accessory-floorplan.d.ts.map +1 -0
  590. package/dist/shared/accessory-floorplan.js +51 -0
  591. package/dist/shared/accessory-geometry.d.ts +7 -0
  592. package/dist/shared/accessory-geometry.d.ts.map +1 -0
  593. package/dist/shared/accessory-geometry.js +79 -0
  594. package/dist/shared/accessory-placement.d.ts +10 -0
  595. package/dist/shared/accessory-placement.d.ts.map +1 -0
  596. package/dist/shared/accessory-placement.js +126 -0
  597. package/dist/shared/accessory-snapping.d.ts +5 -0
  598. package/dist/shared/accessory-snapping.d.ts.map +1 -0
  599. package/dist/shared/accessory-snapping.js +40 -0
  600. package/dist/shared/automatic-run-end-cap.d.ts +11 -0
  601. package/dist/shared/automatic-run-end-cap.d.ts.map +1 -0
  602. package/dist/shared/automatic-run-end-cap.js +159 -0
  603. package/dist/shared/block-face-host.d.ts +15 -0
  604. package/dist/shared/block-face-host.d.ts.map +1 -0
  605. package/dist/shared/block-face-host.js +36 -0
  606. package/dist/shared/connection-compatibility.d.ts +8 -0
  607. package/dist/shared/connection-compatibility.d.ts.map +1 -0
  608. package/dist/shared/connection-compatibility.js +28 -0
  609. package/dist/shared/connection-feedback.d.ts +10 -0
  610. package/dist/shared/connection-feedback.d.ts.map +1 -0
  611. package/dist/shared/connection-feedback.js +17 -0
  612. package/dist/shared/distribution-run-contract.d.ts +49 -0
  613. package/dist/shared/distribution-run-contract.d.ts.map +1 -0
  614. package/dist/shared/distribution-run-contract.js +30 -0
  615. package/dist/shared/distribution-run-tool.d.ts +107 -0
  616. package/dist/shared/distribution-run-tool.d.ts.map +1 -0
  617. package/dist/shared/distribution-run-tool.js +941 -0
  618. package/dist/shared/dormer-wall-opening-placement.d.ts +21 -0
  619. package/dist/shared/dormer-wall-opening-placement.d.ts.map +1 -0
  620. package/dist/shared/dormer-wall-opening-placement.js +101 -0
  621. package/dist/shared/duct-adapter.d.ts +10 -0
  622. package/dist/shared/duct-adapter.d.ts.map +1 -0
  623. package/dist/shared/duct-adapter.js +43 -0
  624. package/dist/shared/elbow-branch-continuation.d.ts +20 -0
  625. package/dist/shared/elbow-branch-continuation.d.ts.map +1 -0
  626. package/dist/shared/elbow-branch-continuation.js +200 -0
  627. package/dist/shared/fitting-clearance.d.ts +5 -0
  628. package/dist/shared/fitting-clearance.d.ts.map +1 -0
  629. package/dist/shared/fitting-clearance.js +11 -0
  630. package/dist/shared/fitting-deletion-cleanup.d.ts +14 -0
  631. package/dist/shared/fitting-deletion-cleanup.d.ts.map +1 -0
  632. package/dist/shared/fitting-deletion-cleanup.js +297 -0
  633. package/dist/shared/fitting-surface-support.d.ts +5 -0
  634. package/dist/shared/fitting-surface-support.d.ts.map +1 -0
  635. package/dist/shared/fitting-surface-support.js +42 -0
  636. package/dist/shared/fitting-tool-options.d.ts +4 -0
  637. package/dist/shared/fitting-tool-options.d.ts.map +1 -0
  638. package/dist/shared/fitting-tool-options.js +175 -0
  639. package/dist/shared/floor-placement.d.ts +1 -1
  640. package/dist/shared/floor-placement.d.ts.map +1 -1
  641. package/dist/shared/floor-placement.js +13 -33
  642. package/dist/shared/ghost-materials.d.ts.map +1 -1
  643. package/dist/shared/ghost-materials.js +2 -1
  644. package/dist/shared/lean-to-post-omissions.d.ts +8 -0
  645. package/dist/shared/lean-to-post-omissions.d.ts.map +1 -0
  646. package/dist/shared/lean-to-post-omissions.js +51 -0
  647. package/dist/shared/mep-fitting-actions.d.ts +5 -0
  648. package/dist/shared/mep-fitting-actions.d.ts.map +1 -0
  649. package/dist/shared/mep-fitting-actions.js +16 -0
  650. package/dist/shared/mep-ghost.d.ts.map +1 -1
  651. package/dist/shared/mep-ghost.js +19 -1
  652. package/dist/shared/mep-presets.d.ts +11 -0
  653. package/dist/shared/mep-presets.d.ts.map +1 -0
  654. package/dist/shared/mep-presets.js +34 -0
  655. package/dist/shared/node-batch/candidates.d.ts +29 -0
  656. package/dist/shared/node-batch/candidates.d.ts.map +1 -0
  657. package/dist/shared/node-batch/candidates.js +260 -0
  658. package/dist/shared/node-batch/store.d.ts +26 -0
  659. package/dist/shared/node-batch/store.d.ts.map +1 -0
  660. package/dist/shared/node-batch/store.js +319 -0
  661. package/dist/shared/node-batch/system.d.ts +8 -0
  662. package/dist/shared/node-batch/system.d.ts.map +1 -0
  663. package/dist/shared/node-batch/system.js +569 -0
  664. package/dist/shared/node-batch/types.d.ts +99 -0
  665. package/dist/shared/node-batch/types.d.ts.map +1 -0
  666. package/dist/shared/node-batch/types.js +4 -0
  667. package/dist/shared/opening-move-history.d.ts +47 -0
  668. package/dist/shared/opening-move-history.d.ts.map +1 -0
  669. package/dist/shared/opening-move-history.js +18 -0
  670. package/dist/shared/opening-move-wall-gate.d.ts +55 -0
  671. package/dist/shared/opening-move-wall-gate.d.ts.map +1 -0
  672. package/dist/shared/opening-move-wall-gate.js +44 -0
  673. package/dist/shared/path-point-affordance.d.ts +2 -2
  674. package/dist/shared/path-point-affordance.d.ts.map +1 -1
  675. package/dist/shared/path-point-affordance.js +30 -6
  676. package/dist/shared/placeholder-geometry.d.ts.map +1 -1
  677. package/dist/shared/placeholder-geometry.js +4 -0
  678. package/dist/shared/ports.d.ts +20 -3
  679. package/dist/shared/ports.d.ts.map +1 -1
  680. package/dist/shared/ports.js +148 -7
  681. package/dist/shared/primitive-uv.d.ts +17 -0
  682. package/dist/shared/primitive-uv.d.ts.map +1 -0
  683. package/dist/shared/primitive-uv.js +107 -0
  684. package/dist/shared/reducer-size.d.ts +2 -0
  685. package/dist/shared/reducer-size.d.ts.map +1 -0
  686. package/dist/shared/reducer-size.js +12 -0
  687. package/dist/shared/ridge-snap.js +1 -1
  688. package/dist/shared/roof-surface.d.ts.map +1 -1
  689. package/dist/shared/roof-surface.js +17 -2
  690. package/dist/shared/run-cursor.d.ts +22 -0
  691. package/dist/shared/run-cursor.d.ts.map +1 -0
  692. package/dist/shared/run-cursor.js +19 -0
  693. package/dist/shared/run-direction-feedback.d.ts +20 -0
  694. package/dist/shared/run-direction-feedback.d.ts.map +1 -0
  695. package/dist/shared/run-direction-feedback.js +139 -0
  696. package/dist/shared/run-hanger-controls.d.ts +7 -0
  697. package/dist/shared/run-hanger-controls.d.ts.map +1 -0
  698. package/dist/shared/run-hanger-controls.js +44 -0
  699. package/dist/shared/run-hanger-inspector.d.ts +5 -0
  700. package/dist/shared/run-hanger-inspector.d.ts.map +1 -0
  701. package/dist/shared/run-hanger-inspector.js +43 -0
  702. package/dist/shared/run-hanger-mode.d.ts +11 -0
  703. package/dist/shared/run-hanger-mode.d.ts.map +1 -0
  704. package/dist/shared/run-hanger-mode.js +32 -0
  705. package/dist/shared/run-hanger-system.d.ts +3 -0
  706. package/dist/shared/run-hanger-system.d.ts.map +1 -0
  707. package/dist/shared/run-hanger-system.js +39 -0
  708. package/dist/shared/run-hangers.d.ts +25 -0
  709. package/dist/shared/run-hangers.d.ts.map +1 -0
  710. package/dist/shared/run-hangers.js +261 -0
  711. package/dist/shared/run-port-snap.d.ts +11 -0
  712. package/dist/shared/run-port-snap.d.ts.map +1 -0
  713. package/dist/shared/run-port-snap.js +19 -0
  714. package/dist/shared/run-screen-direction.d.ts +5 -0
  715. package/dist/shared/run-screen-direction.d.ts.map +1 -0
  716. package/dist/shared/run-screen-direction.js +24 -0
  717. package/dist/shared/selection-handles.d.ts +4 -0
  718. package/dist/shared/selection-handles.d.ts.map +1 -1
  719. package/dist/shared/selection-handles.js +10 -0
  720. package/dist/shared/slot-paint.d.ts +8 -1
  721. package/dist/shared/slot-paint.d.ts.map +1 -1
  722. package/dist/shared/slot-paint.js +120 -27
  723. package/dist/shared/surface-paint.d.ts +1 -2
  724. package/dist/shared/surface-paint.d.ts.map +1 -1
  725. package/dist/shared/surface-paint.js +9 -20
  726. package/dist/shared/system-check-panel.d.ts +6 -0
  727. package/dist/shared/system-check-panel.d.ts.map +1 -0
  728. package/dist/shared/system-check-panel.js +62 -0
  729. package/dist/shared/system-checks.d.ts +9 -0
  730. package/dist/shared/system-checks.d.ts.map +1 -0
  731. package/dist/shared/system-checks.js +131 -0
  732. package/dist/shared/wall-attach-target.d.ts +14 -2
  733. package/dist/shared/wall-attach-target.d.ts.map +1 -1
  734. package/dist/shared/wall-attach-target.js +108 -4
  735. package/dist/shared/wall-opening-clearance.d.ts +19 -0
  736. package/dist/shared/wall-opening-clearance.d.ts.map +1 -0
  737. package/dist/shared/wall-opening-clearance.js +28 -0
  738. package/dist/shared/wall-run-move.d.ts +17 -0
  739. package/dist/shared/wall-run-move.d.ts.map +1 -0
  740. package/dist/shared/wall-run-move.js +56 -0
  741. package/dist/shelf/parametrics.js +4 -4
  742. package/dist/site/renderer.d.ts.map +1 -1
  743. package/dist/site/renderer.js +40 -28
  744. package/dist/site/terrain-geometry.d.ts +1 -1
  745. package/dist/site/terrain-geometry.d.ts.map +1 -1
  746. package/dist/site/terrain-geometry.js +35 -9
  747. package/dist/site/terrain-mesh.d.ts +5 -0
  748. package/dist/site/terrain-mesh.d.ts.map +1 -1
  749. package/dist/site/terrain-mesh.js +63 -34
  750. package/dist/skylight/definition.js +1 -1
  751. package/dist/skylight/panel.js +1 -1
  752. package/dist/skylight/parametrics.js +2 -2
  753. package/dist/slab/definition.d.ts.map +1 -1
  754. package/dist/slab/definition.js +6 -1
  755. package/dist/slab/dependency-tracker.d.ts +3 -0
  756. package/dist/slab/dependency-tracker.d.ts.map +1 -0
  757. package/dist/slab/dependency-tracker.js +104 -0
  758. package/dist/slab/floorplan-affordances.d.ts +8 -8
  759. package/dist/slab/geometry.d.ts.map +1 -1
  760. package/dist/slab/geometry.js +16 -2
  761. package/dist/slab/panel.d.ts.map +1 -1
  762. package/dist/slab/panel.js +1 -1
  763. package/dist/slab/parametrics.js +1 -1
  764. package/dist/slab/system.d.ts.map +1 -1
  765. package/dist/slab/system.js +8 -64
  766. package/dist/solar-panel/definition.js +1 -1
  767. package/dist/solar-panel/panel.js +1 -1
  768. package/dist/solar-panel/parametrics.js +2 -2
  769. package/dist/stair/panel.d.ts.map +1 -1
  770. package/dist/stair/panel.js +18 -13
  771. package/dist/stair/stair-type.d.ts +18 -0
  772. package/dist/stair/stair-type.d.ts.map +1 -0
  773. package/dist/stair/stair-type.js +25 -0
  774. package/dist/stair-segment/panel.d.ts.map +1 -1
  775. package/dist/stair-segment/panel.js +44 -5
  776. package/dist/turbine-vent/definition.d.ts.map +1 -1
  777. package/dist/turbine-vent/definition.js +8 -5
  778. package/dist/turbine-vent/geometry.d.ts.map +1 -1
  779. package/dist/turbine-vent/geometry.js +48 -18
  780. package/dist/turbine-vent/paint.d.ts +4 -0
  781. package/dist/turbine-vent/paint.d.ts.map +1 -0
  782. package/dist/turbine-vent/paint.js +35 -0
  783. package/dist/turbine-vent/panel.js +1 -1
  784. package/dist/turbine-vent/parametrics.js +2 -2
  785. package/dist/turbine-vent/renderer.d.ts.map +1 -1
  786. package/dist/turbine-vent/renderer.js +31 -9
  787. package/dist/wall/curve-eligibility.d.ts +3 -0
  788. package/dist/wall/curve-eligibility.d.ts.map +1 -0
  789. package/dist/wall/curve-eligibility.js +10 -0
  790. package/dist/wall/curve-tool.d.ts +3 -4
  791. package/dist/wall/curve-tool.d.ts.map +1 -1
  792. package/dist/wall/curve-tool.js +24 -23
  793. package/dist/wall/definition.d.ts +1 -1
  794. package/dist/wall/definition.d.ts.map +1 -1
  795. package/dist/wall/definition.js +36 -13
  796. package/dist/wall/floorplan-affordances.d.ts +1 -0
  797. package/dist/wall/floorplan-affordances.d.ts.map +1 -1
  798. package/dist/wall/floorplan-affordances.js +46 -7
  799. package/dist/wall/floorplan-move.d.ts +3 -4
  800. package/dist/wall/floorplan-move.d.ts.map +1 -1
  801. package/dist/wall/floorplan-move.js +122 -9
  802. package/dist/wall/floorplan.d.ts.map +1 -1
  803. package/dist/wall/floorplan.js +19 -23
  804. package/dist/wall/move-shared.d.ts.map +1 -1
  805. package/dist/wall/move-shared.js +10 -7
  806. package/dist/wall/paint.d.ts.map +1 -1
  807. package/dist/wall/paint.js +2 -0
  808. package/dist/wall/panel.d.ts.map +1 -1
  809. package/dist/wall/panel.js +62 -27
  810. package/dist/wall/parametrics.js +2 -2
  811. package/dist/wall/pointer-transparency.d.ts +128 -0
  812. package/dist/wall/pointer-transparency.d.ts.map +1 -0
  813. package/dist/wall/pointer-transparency.js +147 -0
  814. package/dist/wall/renderer.d.ts.map +1 -1
  815. package/dist/wall/renderer.js +65 -8
  816. package/dist/wall/selection-hit-owner.d.ts +53 -0
  817. package/dist/wall/selection-hit-owner.d.ts.map +1 -0
  818. package/dist/wall/selection-hit-owner.js +79 -0
  819. package/dist/wall/system.d.ts +5 -0
  820. package/dist/wall/system.d.ts.map +1 -1
  821. package/dist/wall/system.js +71 -26
  822. package/dist/wall/tool.d.ts.map +1 -1
  823. package/dist/wall/tool.js +29 -27
  824. package/dist/wall/treatment-level-data.d.ts +6 -1
  825. package/dist/wall/treatment-level-data.d.ts.map +1 -1
  826. package/dist/wall/treatment-level-data.js +82 -5
  827. package/dist/wall/treatments.d.ts +1 -0
  828. package/dist/wall/treatments.d.ts.map +1 -1
  829. package/dist/wall/treatments.js +5 -0
  830. package/dist/wall/wall-batch-system.d.ts +55 -0
  831. package/dist/wall/wall-batch-system.d.ts.map +1 -0
  832. package/dist/wall/wall-batch-system.js +486 -0
  833. package/dist/wall/wall-batch.d.ts +66 -0
  834. package/dist/wall/wall-batch.d.ts.map +1 -0
  835. package/dist/wall/wall-batch.js +169 -0
  836. package/dist/window/definition.d.ts +2 -1
  837. package/dist/window/definition.d.ts.map +1 -1
  838. package/dist/window/definition.js +51 -24
  839. package/dist/window/floorplan-move.d.ts.map +1 -1
  840. package/dist/window/floorplan-move.js +1 -1
  841. package/dist/window/move-tool.d.ts +7 -5
  842. package/dist/window/move-tool.d.ts.map +1 -1
  843. package/dist/window/move-tool.js +344 -58
  844. package/dist/window/panel.d.ts.map +1 -1
  845. package/dist/window/panel.js +2 -0
  846. package/dist/window/parametrics.js +2 -2
  847. package/dist/window/renderer.d.ts.map +1 -1
  848. package/dist/window/renderer.js +5 -7
  849. package/dist/window/tool.d.ts.map +1 -1
  850. package/dist/window/tool.js +227 -13
  851. package/dist/zone/floorplan-affordances.d.ts +12 -12
  852. package/dist/zone/quantities-panel.d.ts.map +1 -1
  853. package/dist/zone/quantities-panel.js +4 -3
  854. package/package.json +11 -9
  855. package/dist/dormer/panel-window-section.d.ts +0 -14
  856. package/dist/dormer/panel-window-section.d.ts.map +0 -1
  857. package/dist/dormer/panel-window-section.js +0 -59
  858. package/dist/dormer/window-assembly.d.ts +0 -22
  859. package/dist/dormer/window-assembly.d.ts.map +0 -1
  860. package/dist/dormer/window-assembly.js +0 -111
  861. package/dist/dormer/window-frame.d.ts +0 -24
  862. package/dist/dormer/window-frame.d.ts.map +0 -1
  863. package/dist/dormer/window-frame.js +0 -100
@@ -1,11 +1,13 @@
1
1
  import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { emitter, isCurvedWall, sceneRegistry, spatialGridManager, useLiveTransforms, useScene, WindowNode, } from '@pascal-app/core';
3
- import { calculateItemRotation, clearPlacementSurface, consumePlacementDragRelease, EDITOR_LAYER, getSideFromNormal, isGridSnapActive, isMagneticSnapActive, isValidWallSideFace, publishPlacementSurface, snapToHalf, stripPlacementMetadataFlags, triggerSFX, useAlignmentGuides, useEditor, useFacingPose, } from '@pascal-app/editor';
4
- import { useViewer } from '@pascal-app/viewer';
2
+ import { dormerWallFacePointToDormer, emitter, holdHiddenWallPointerEvents, isCurvedWall, sceneRegistry, spatialGridManager, useLiveNodeOverrides, useLiveTransforms, useScene, WindowNode, } from '@pascal-app/core';
3
+ import { calculateItemRotation, clearPlacementSurface, consumePlacementDragRelease, EDITOR_LAYER, getSideFromNormal, isGridSnapActive, isMagneticSnapActive, isValidWallSideFace, publishPlacementSurface, snapToHalf, stripPlacementMetadataFlags, triggerSFX, useAlignmentGuides, useEditor, useFacingPose, useRegistryToolContext, } from '@pascal-app/editor';
5
4
  import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
6
5
  import { BoxGeometry, EdgesGeometry, Vector3 } from 'three';
7
6
  import { LineBasicNodeMaterial } from 'three/webgpu';
7
+ import { dormerEventFromHostedWindow, getDormerWindowWorldNormal, getDormerWindowWorldYaw, resolveDormerWindowTarget, } from '../shared/dormer-wall-opening-placement';
8
8
  import { clearOpeningGuides3D, publishOpeningGuidesForWallEvent, resolveSillSnap, } from '../shared/opening-guides-runtime';
9
+ import { beginOpeningMoveHistorySession } from '../shared/opening-move-history';
10
+ import { isWallMeshHidden, shouldIgnoreWallEventForOpeningMove, } from '../shared/opening-move-wall-gate';
9
11
  import { getRoofWallOpeningCursorPose, resolveRoofWallOpeningTarget, } from '../shared/roof-wall-opening-placement';
10
12
  import { resolveOpeningPlacement } from '../shared/wall-attach-target';
11
13
  import { collectWallOpeningAlignmentCandidates, resolveWallSlideAlignment, } from '../shared/wall-opening-alignment';
@@ -22,15 +24,18 @@ const edgeMaterial = new LineBasicNodeMaterial({
22
24
  * Move/duplicate tool for WindowNodes — wall-only, same guardrails as WindowTool.
23
25
  *
24
26
  * Move mode (metadata.isNew falsy):
25
- * Adopts the existing window, pauses temporal. On commit: restores original state
26
- * (clean undo baseline) then resumes + updateNode (undo reverts to original position).
27
- * On cancel: restores original state.
27
+ * Adopts the existing window and holds a refcounted history pause for the
28
+ * gesture. On commit: restores original state (clean undo baseline) then runs
29
+ * updateNode as the gesture's single tracked write (undo reverts to the
30
+ * original position). On cancel: restores original state, never tracked.
28
31
  *
29
32
  * Duplicate mode (metadata.isNew = true):
30
- * The node is a freshly created transient copy. On commit: deletes transient + resumes
31
- * + createNode (undo removes the new window entirely). On cancel: deletes the node.
33
+ * The node is a freshly created transient copy. On commit: deletes the
34
+ * transient paused + createNode as the single tracked write (undo removes the
35
+ * new window entirely). On cancel: deletes the node.
32
36
  */
33
37
  const MoveWindowTool = ({ node: movingWindowNode }) => {
38
+ const { activeLevelId, isCameraDragging, selectNode } = useRegistryToolContext();
34
39
  const cursorGroupRef = useRef(null);
35
40
  // The window preview ghost. Shown for the WHOLE move so the user always sees
36
41
  // a translucent window tinted by placement state — red off-wall or colliding,
@@ -54,7 +59,19 @@ const MoveWindowTool = ({ node: movingWindowNode }) => {
54
59
  useEditor.getState().setMovingNode(null);
55
60
  }, []);
56
61
  useEffect(() => {
57
- useScene.temporal.getState().pause();
62
+ // One undo entry per gesture: hold the REFCOUNTED history pause for the
63
+ // move's lifetime (a raw `temporal.pause()` is invisible to
64
+ // `getSceneHistoryPauseDepth()`, so a cooperating system's balanced
65
+ // pause/resume pair could zero the refcount mid-drag and resume tracking
66
+ // — every mid-drag write then became its own undo entry). The commit
67
+ // paths run their single tracked write through `history.commitStep`.
68
+ const history = beginOpeningMoveHistorySession();
69
+ // This tool's whole cursor model is the wall surface (`wall:enter` /
70
+ // `wall:move` / `wall:click`). Walls hidden by the wall-mode pass (X-ray
71
+ // 'down' mode) are pointer-transparent for selection; hold their pointer
72
+ // events for the move's lifetime so the window keeps sliding along its
73
+ // wall instead of detaching into the floor free-follow.
74
+ const releaseHiddenWallHold = holdHiddenWallPointerEvents();
58
75
  const meta = typeof movingWindowNode.metadata === 'object' && movingWindowNode.metadata !== null
59
76
  ? movingWindowNode.metadata
60
77
  : {};
@@ -66,6 +83,8 @@ const MoveWindowTool = ({ node: movingWindowNode }) => {
66
83
  side: movingWindowNode.side,
67
84
  parentId: movingWindowNode.parentId,
68
85
  wallId: movingWindowNode.wallId,
86
+ dormerId: movingWindowNode.dormerId,
87
+ dormerFace: movingWindowNode.dormerFace,
69
88
  // Windows can be hosted on a roof-segment wall face. Moving onto a
70
89
  // wall re-anchors as wall-hosted (roofSegmentId cleared); reverts
71
90
  // must restore the roof host.
@@ -144,6 +163,8 @@ const MoveWindowTool = ({ node: movingWindowNode }) => {
144
163
  let grabWallId = movingWindowNode.parentId;
145
164
  let lastTarget = null;
146
165
  let lastRoofEvent = null;
166
+ let lastDormerEvent = null;
167
+ let lastDormerTarget = null;
147
168
  const markHostDirty = (hostId) => {
148
169
  if (hostId)
149
170
  useScene.getState().dirtyNodes.add(hostId);
@@ -160,7 +181,7 @@ const MoveWindowTool = ({ node: movingWindowNode }) => {
160
181
  markHostDirty(hostId);
161
182
  }
162
183
  };
163
- const getLevelId = () => useViewer.getState().selection.levelId;
184
+ const getLevelId = () => activeLevelId;
164
185
  const getLevelYOffset = () => {
165
186
  const id = getLevelId();
166
187
  return id ? (sceneRegistry.nodes.get(id)?.position.y ?? 0) : 0;
@@ -197,6 +218,20 @@ const MoveWindowTool = ({ node: movingWindowNode }) => {
197
218
  group.rotation.y = cursorRotationY;
198
219
  edgeMaterial.color.setHex(valid ? 0x22_c5_5e : 0xef_44_44);
199
220
  };
221
+ // While MOVING an existing window, a HIDDEN wall may drive the drag only
222
+ // if it is the window's own wall (grab wall / current mid-drag host) — an
223
+ // interposed hidden wall between the camera and the window's wall must
224
+ // not capture the drag and silently re-parent the window on commit
225
+ // (night-6 QA: an X-ray drag rode an invisible wall at z=-2.5 instead of
226
+ // the window's own wall at z=0). Ignored events are NOT
227
+ // stopPropagation'd, so the ray falls through to the own wall behind.
228
+ // Fresh placements (`isNew`) keep the all-walls behavior.
229
+ const wallEventIgnored = (event) => !isNew &&
230
+ shouldIgnoreWallEventForOpeningMove({
231
+ eventWallId: event.node.id,
232
+ eventWallHidden: isWallMeshHidden(event.node.id),
233
+ ownWallIds: [original.wallId, currentHostId],
234
+ });
200
235
  const resolveMoveTarget = (event) => {
201
236
  if (!isValidWallSideFace(event.normal))
202
237
  return;
@@ -257,7 +292,7 @@ const MoveWindowTool = ({ node: movingWindowNode }) => {
257
292
  applySnap: isMagneticSnapActive(),
258
293
  });
259
294
  const { clampedX, clampedY } = clampToWall(event.node, localX, targetLocalY, movingWindowNode.width, movingWindowNode.height, useScene.getState().nodes);
260
- const valid = !hasWallChildOverlap(event.node.id, clampedX, clampedY, movingWindowNode.width, movingWindowNode.height, movingWindowNode.id);
295
+ const valid = !hasWallChildOverlap(event.node.id, useScene.getState().nodes, clampedX, clampedY, movingWindowNode.width, movingWindowNode.height, movingWindowNode.id);
261
296
  return {
262
297
  wallNode: event.node,
263
298
  wallId: event.node.id,
@@ -278,8 +313,13 @@ const MoveWindowTool = ({ node: movingWindowNode }) => {
278
313
  tickGridStep(target.event.nativeEvent?.timeStamp ?? -1, target.clampedX);
279
314
  // Keep the REAL node hidden and show a tinted ghost in the wall opening —
280
315
  // green when placeable, red when it collides — matching the free-follow
281
- // ghost so validity reads at a glance (see MoveDoorTool). The node position
282
- // is still written so the wall cuts the hole at the right spot.
316
+ // ghost so validity reads at a glance (see MoveDoorTool). Reparenting
317
+ // MUST be a scene write: the wall's CSG merge and the renderer's nesting
318
+ // walk the wall's `children` array, which a live override never joins —
319
+ // an override-only reparent left the window uncut and rendered against
320
+ // its stale parent (no on-wall preview at all). A stale override from a
321
+ // free-follow / dormer hop would shadow those scene fields, so drop it.
322
+ useLiveNodeOverrides.getState().clear(movingWindowNode.id);
283
323
  if (currentHostId !== target.wallId) {
284
324
  useScene.getState().updateNode(movingWindowNode.id, {
285
325
  position: [target.clampedX, target.clampedY, 0],
@@ -289,6 +329,8 @@ const MoveWindowTool = ({ node: movingWindowNode }) => {
289
329
  wallId: target.wallId,
290
330
  roofSegmentId: undefined,
291
331
  roofFace: undefined,
332
+ dormerId: undefined,
333
+ dormerFace: undefined,
292
334
  visible: false,
293
335
  });
294
336
  markHostDirty(currentHostId);
@@ -351,6 +393,11 @@ const MoveWindowTool = ({ node: movingWindowNode }) => {
351
393
  });
352
394
  };
353
395
  const onWallEnter = (event) => {
396
+ // Interposed hidden wall: ignore WITHOUT tearing down the current
397
+ // preview or stopping propagation — the own wall behind it (a later,
398
+ // farther intersection on this same ray) emits its own event.
399
+ if (wallEventIgnored(event))
400
+ return;
354
401
  const target = resolveMoveTarget(event);
355
402
  if (!target) {
356
403
  onWallLeave();
@@ -366,6 +413,9 @@ const MoveWindowTool = ({ node: movingWindowNode }) => {
366
413
  event.stopPropagation();
367
414
  };
368
415
  const onWallMove = (event) => {
416
+ // See onWallEnter — interposed hidden walls never own the move.
417
+ if (wallEventIgnored(event))
418
+ return;
369
419
  if (!isValidWallSideFace(event.normal)) {
370
420
  onWallLeave();
371
421
  return;
@@ -401,10 +451,10 @@ const MoveWindowTool = ({ node: movingWindowNode }) => {
401
451
  committed = true;
402
452
  let placedId;
403
453
  if (isNew) {
404
- // Duplicate mode: delete transient + resume + createNode
405
- // Undo will remove the newly created node entirely
454
+ // Duplicate mode: delete the transient draft while history is still
455
+ // paused, then create the real node as the gesture's ONE tracked
456
+ // write — undo removes the new window entirely.
406
457
  useScene.getState().deleteNode(movingWindowNode.id);
407
- useScene.temporal.getState().resume();
408
458
  const cloned = structuredClone(movingWindowNode);
409
459
  delete cloned.id;
410
460
  cloned.metadata = stripPlacementMetadataFlags(cloned.metadata);
@@ -420,33 +470,39 @@ const MoveWindowTool = ({ node: movingWindowNode }) => {
420
470
  // Hidden during free-follow; the committed window must be visible.
421
471
  visible: true,
422
472
  });
423
- useScene.getState().createNode(node, target.wallId);
473
+ history.commitStep(() => {
474
+ useScene.getState().createNode(node, target.wallId);
475
+ });
424
476
  placedId = node.id;
425
477
  }
426
478
  else {
427
- // Move mode: restore original (clean baseline) + resume + updateNode
428
- // Undo will revert to the original position
479
+ // Move mode: restore the exact pre-drag state while history is still
480
+ // paused (the clean undo baseline), then apply the drop as the
481
+ // gesture's ONE tracked write — undo reverts to the original state.
429
482
  useScene.getState().updateNode(movingWindowNode.id, {
430
483
  position: original.position,
431
484
  rotation: original.rotation,
432
485
  side: original.side,
433
486
  parentId: original.parentId,
434
487
  wallId: original.wallId,
488
+ dormerId: original.dormerId,
489
+ dormerFace: original.dormerFace,
435
490
  roofSegmentId: original.roofSegmentId,
436
491
  roofFace: original.roofFace,
437
492
  metadata: original.metadata,
438
493
  visible: original.visible,
439
494
  });
440
- useScene.temporal.getState().resume();
441
- useScene.getState().updateNode(movingWindowNode.id, {
442
- position: [target.clampedX, target.clampedY, 0],
443
- rotation: [0, target.itemRotation, 0],
444
- side: target.side,
445
- parentId: target.wallId,
446
- wallId: target.wallId,
447
- roofSegmentId: undefined,
448
- metadata: {},
449
- visible: true,
495
+ history.commitStep(() => {
496
+ useScene.getState().updateNode(movingWindowNode.id, {
497
+ position: [target.clampedX, target.clampedY, 0],
498
+ rotation: [0, target.itemRotation, 0],
499
+ side: target.side,
500
+ parentId: target.wallId,
501
+ wallId: target.wallId,
502
+ roofSegmentId: undefined,
503
+ metadata: {},
504
+ visible: true,
505
+ });
450
506
  });
451
507
  if (original.parentId && original.parentId !== target.wallId) {
452
508
  markHostDirty(original.parentId);
@@ -455,15 +511,18 @@ const MoveWindowTool = ({ node: movingWindowNode }) => {
455
511
  }
456
512
  markHostDirty(target.wallId);
457
513
  useLiveTransforms.getState().clear(movingWindowNode.id);
458
- useScene.temporal.getState().pause();
459
514
  triggerSFX('sfx:structure-build');
460
515
  hideCursor();
461
- useViewer.getState().setSelection({ selectedIds: [placedId] });
516
+ selectNode(placedId);
462
517
  exitMoveMode();
463
518
  };
464
519
  const onWallClick = (event) => {
465
520
  if (committed)
466
521
  return;
522
+ // A click on an interposed hidden wall must not commit / re-parent;
523
+ // let it fall through to the own wall behind (see onWallEnter).
524
+ if (wallEventIgnored(event))
525
+ return;
467
526
  if (!isValidWallSideFace(event.normal))
468
527
  return;
469
528
  if (isCurvedWall(event.node))
@@ -500,10 +559,7 @@ const MoveWindowTool = ({ node: movingWindowNode }) => {
500
559
  setGhostPose(null);
501
560
  useFacingPose.getState().clear();
502
561
  clearPlacementSurface();
503
- const live = useScene.getState().nodes[movingWindowNode.id];
504
- if (live && live.visible === false) {
505
- useScene.getState().updateNode(movingWindowNode.id, { visible: true });
506
- }
562
+ useLiveNodeOverrides.getState().set(movingWindowNode.id, { visible: true });
507
563
  };
508
564
  // Free-follow: over open floor there's no wall to host the window, so hide
509
565
  // the real (pale, near-invisible-on-grid) node and float a red translucent
@@ -512,6 +568,8 @@ const MoveWindowTool = ({ node: movingWindowNode }) => {
512
568
  freeFollowing = true;
513
569
  lastTarget = null;
514
570
  lastRoofEvent = null;
571
+ lastDormerEvent = null;
572
+ lastDormerTarget = null;
515
573
  // No snap SFX here: the free-follow fires off-wall (an invalid red ghost,
516
574
  // not a placeable position) AND interleaves with the on-wall slide on the
517
575
  // same pointer move (R3F `wall:move` and DOM `grid:move` carry different
@@ -519,11 +577,15 @@ const MoveWindowTool = ({ node: movingWindowNode }) => {
519
577
  // source of the constant click while sliding a window along a wall — the
520
578
  // on-wall `applyPreview` already ticks once per along-wall cell.
521
579
  hideCursor();
580
+ useLiveNodeOverrides.getState().clear(movingWindowNode.id);
522
581
  useLiveTransforms.getState().clear(movingWindowNode.id);
523
582
  const levelId = getLevelId();
524
583
  const sillCenterY = getSillCenterY();
525
584
  // Keep the R-flip visible while free-following (back = rotated π).
526
585
  const yaw = sideOverride === 'back' ? Math.PI : 0;
586
+ // Scene writes, not overrides: leaving the wall must actually remove the
587
+ // window from the wall's `children` or the CSG cut trails the ghost
588
+ // around the old wall (see the wall-branch note in `applyPreview`).
527
589
  if (currentHostId !== levelId) {
528
590
  if (currentHostId && currentHostId !== levelId)
529
591
  markHostDirty(currentHostId);
@@ -535,6 +597,8 @@ const MoveWindowTool = ({ node: movingWindowNode }) => {
535
597
  wallId: undefined,
536
598
  roofSegmentId: undefined,
537
599
  roofFace: undefined,
600
+ dormerId: undefined,
601
+ dormerFace: undefined,
538
602
  visible: false,
539
603
  });
540
604
  currentHostId = levelId;
@@ -563,7 +627,7 @@ const MoveWindowTool = ({ node: movingWindowNode }) => {
563
627
  const onGridMove = (event) => {
564
628
  if (committed)
565
629
  return;
566
- if (useViewer.getState().cameraDragging)
630
+ if (isCameraDragging())
567
631
  return;
568
632
  // A wall/roof handler owns the pointer right now — the cursor ray is on a
569
633
  // wall/roof that snaps, so skip the floor follow (see `wallOwnsPointer`).
@@ -573,6 +637,186 @@ const MoveWindowTool = ({ node: movingWindowNode }) => {
573
637
  lastFloorPoint = [x, z];
574
638
  freeFollowAt(x, z);
575
639
  };
640
+ // ── Dormer wall faces ──────────────────────────────────────────
641
+ const resolveDormerMoveTarget = (event) => resolveDormerWindowTarget({
642
+ event,
643
+ width: movingWindowNode.width,
644
+ height: movingWindowNode.height,
645
+ ignoreId: movingWindowNode.id,
646
+ nodes: useScene.getState().nodes,
647
+ snap: snapToHalf,
648
+ });
649
+ const dormerWindowWorldPosition = (event, target) => {
650
+ const point = new Vector3(...dormerWallFacePointToDormer(event.node, target.face, target.position));
651
+ event.object.localToWorld(point);
652
+ return [point.x, point.y, point.z];
653
+ };
654
+ const applyDormerPreview = (event, target) => {
655
+ markWallOwnedPointer();
656
+ freeFollowing = false;
657
+ lastTarget = null;
658
+ lastRoofEvent = null;
659
+ lastDormerEvent = event;
660
+ lastDormerTarget = target;
661
+ dragAnchor = null;
662
+ grabWallId = null;
663
+ const side = sideOverride ?? 'front';
664
+ const rotation = [0, side === 'back' ? Math.PI : 0, 0];
665
+ if (currentHostId !== target.dormer.id) {
666
+ markHostDirty(currentHostId);
667
+ currentHostId = target.dormer.id;
668
+ }
669
+ useLiveNodeOverrides.getState().set(movingWindowNode.id, {
670
+ position: target.position,
671
+ rotation,
672
+ side,
673
+ parentId: target.dormer.id,
674
+ dormerId: target.dormer.id,
675
+ dormerFace: target.face,
676
+ wallId: undefined,
677
+ roofSegmentId: undefined,
678
+ roofFace: undefined,
679
+ visible: false,
680
+ });
681
+ const worldPosition = dormerWindowWorldPosition(event, target);
682
+ publishPlacementSurface(new Vector3(...worldPosition), getDormerWindowWorldNormal(event, target));
683
+ setGhostPose({
684
+ position: worldPosition,
685
+ rotationY: getDormerWindowWorldYaw(event, target),
686
+ tint: target.valid || altHeld ? 'valid' : 'invalid',
687
+ floorY: worldPosition[1],
688
+ side,
689
+ });
690
+ useFacingPose.getState().clear();
691
+ clearOpeningGuides3D();
692
+ };
693
+ const commitToDormer = (event, target) => {
694
+ if (committed)
695
+ return;
696
+ committed = true;
697
+ useLiveNodeOverrides.getState().clear(movingWindowNode.id);
698
+ const side = sideOverride ?? 'front';
699
+ const rotation = [0, side === 'back' ? Math.PI : 0, 0];
700
+ let placedId;
701
+ if (isNew) {
702
+ useScene.getState().deleteNode(movingWindowNode.id);
703
+ const cloned = structuredClone(movingWindowNode);
704
+ delete cloned.id;
705
+ cloned.metadata = stripPlacementMetadataFlags(cloned.metadata);
706
+ const committedNode = WindowNode.parse({
707
+ ...cloned,
708
+ position: target.position,
709
+ rotation,
710
+ side,
711
+ parentId: target.dormer.id,
712
+ dormerId: target.dormer.id,
713
+ dormerFace: target.face,
714
+ wallId: undefined,
715
+ roofSegmentId: undefined,
716
+ roofFace: undefined,
717
+ visible: true,
718
+ });
719
+ history.commitStep(() => {
720
+ useScene.getState().createNode(committedNode, target.dormer.id);
721
+ });
722
+ placedId = committedNode.id;
723
+ }
724
+ else {
725
+ useScene.getState().updateNode(movingWindowNode.id, {
726
+ position: original.position,
727
+ rotation: original.rotation,
728
+ side: original.side,
729
+ parentId: original.parentId,
730
+ wallId: original.wallId,
731
+ dormerId: original.dormerId,
732
+ dormerFace: original.dormerFace,
733
+ roofSegmentId: original.roofSegmentId,
734
+ roofFace: original.roofFace,
735
+ metadata: original.metadata,
736
+ visible: original.visible,
737
+ });
738
+ history.commitStep(() => {
739
+ useScene.getState().updateNode(movingWindowNode.id, {
740
+ position: target.position,
741
+ rotation,
742
+ side,
743
+ parentId: target.dormer.id,
744
+ dormerId: target.dormer.id,
745
+ dormerFace: target.face,
746
+ wallId: undefined,
747
+ roofSegmentId: undefined,
748
+ roofFace: undefined,
749
+ metadata: {},
750
+ visible: true,
751
+ });
752
+ });
753
+ if (original.parentId && original.parentId !== target.dormer.id) {
754
+ markHostDirty(original.parentId);
755
+ }
756
+ placedId = movingWindowNode.id;
757
+ }
758
+ markHostDirty(target.dormer.id);
759
+ useLiveTransforms.getState().clear(movingWindowNode.id);
760
+ triggerSFX('sfx:structure-build');
761
+ hideCursor();
762
+ selectNode(placedId);
763
+ exitMoveMode();
764
+ event.stopPropagation();
765
+ };
766
+ const onDormerHover = (event) => {
767
+ if (committed)
768
+ return;
769
+ const target = resolveDormerMoveTarget(event);
770
+ if (!target) {
771
+ onDormerLeave();
772
+ return;
773
+ }
774
+ applyDormerPreview(event, target);
775
+ event.stopPropagation();
776
+ };
777
+ const onDormerClick = (event) => {
778
+ if (committed)
779
+ return;
780
+ const target = lastDormerTarget && lastDormerEvent?.node.id === event.node.id
781
+ ? lastDormerTarget
782
+ : resolveDormerMoveTarget(event);
783
+ if (!target)
784
+ return;
785
+ if (!target.valid && event.nativeEvent?.altKey !== true)
786
+ return;
787
+ commitToDormer(event, target);
788
+ };
789
+ const onDormerLeave = () => {
790
+ hideCursor();
791
+ useLiveNodeOverrides.getState().clear(movingWindowNode.id);
792
+ useLiveTransforms.getState().clear(movingWindowNode.id);
793
+ lastDormerEvent = null;
794
+ lastDormerTarget = null;
795
+ };
796
+ const dormerEventFromWindow = (event) => {
797
+ const dormerId = event.node.dormerId ?? event.node.parentId;
798
+ const dormer = dormerId ? useScene.getState().nodes[dormerId] : undefined;
799
+ const object = dormer ? sceneRegistry.nodes.get(dormer.id) : undefined;
800
+ if (!(dormer?.type === 'dormer' && object))
801
+ return null;
802
+ return dormerEventFromHostedWindow(event, dormer, object);
803
+ };
804
+ const onDormerWindowHover = (event) => {
805
+ const dormerEvent = dormerEventFromWindow(event);
806
+ if (dormerEvent)
807
+ onDormerHover(dormerEvent);
808
+ };
809
+ const onDormerWindowClick = (event) => {
810
+ const dormerEvent = dormerEventFromWindow(event);
811
+ if (dormerEvent)
812
+ onDormerClick(dormerEvent);
813
+ };
814
+ const onDormerWindowLeave = (event) => {
815
+ if (event.node.dormerId ||
816
+ useScene.getState().nodes[event.node.parentId]?.type === 'dormer') {
817
+ onDormerLeave();
818
+ }
819
+ };
576
820
  // ── Roof-segment wall faces ─────────────────────────────────────
577
821
  // Mirrors the wall flow for the segments' vertical wall faces (base
578
822
  // walls under the roof + coplanar gable ends — a window can sit in
@@ -611,13 +855,16 @@ const MoveWindowTool = ({ node: movingWindowNode }) => {
611
855
  grabWallId = null;
612
856
  lastTarget = null;
613
857
  lastRoofEvent = event;
858
+ useLiveNodeOverrides.getState().clear(movingWindowNode.id);
614
859
  useLiveTransforms.getState().clear(movingWindowNode.id);
615
860
  // Opening guides are wall-specific; clear them when over a roof face.
616
861
  clearOpeningGuides3D();
617
862
  // On a roof face the real mesh is the preview — drop the ghost + reveal.
618
863
  revealRealNode();
619
864
  if (currentHostId !== target.segment.id) {
620
- useScene.getState().updateNode(movingWindowNode.id, {
865
+ markHostDirty(currentHostId);
866
+ currentHostId = target.segment.id;
867
+ useLiveNodeOverrides.getState().set(movingWindowNode.id, {
621
868
  position: target.position,
622
869
  rotation: [0, 0, 0],
623
870
  side: 'front',
@@ -627,11 +874,9 @@ const MoveWindowTool = ({ node: movingWindowNode }) => {
627
874
  roofFace: target.face.id,
628
875
  visible: true,
629
876
  });
630
- markHostDirty(currentHostId);
631
- currentHostId = target.segment.id;
632
877
  }
633
878
  else {
634
- useScene.getState().updateNode(movingWindowNode.id, {
879
+ useLiveNodeOverrides.getState().set(movingWindowNode.id, {
635
880
  position: target.position,
636
881
  rotation: [0, 0, 0],
637
882
  roofFace: target.face.id,
@@ -653,8 +898,9 @@ const MoveWindowTool = ({ node: movingWindowNode }) => {
653
898
  const segmentId = target.segment.id;
654
899
  let placedId;
655
900
  if (isNew) {
901
+ // See commitToWall — delete the draft paused, create as the ONE
902
+ // tracked write.
656
903
  useScene.getState().deleteNode(movingWindowNode.id);
657
- useScene.temporal.getState().resume();
658
904
  const cloned = structuredClone(movingWindowNode);
659
905
  delete cloned.id;
660
906
  cloned.metadata = stripPlacementMetadataFlags(cloned.metadata);
@@ -669,32 +915,39 @@ const MoveWindowTool = ({ node: movingWindowNode }) => {
669
915
  parentId: segmentId,
670
916
  visible: true,
671
917
  });
672
- useScene.getState().createNode(node, segmentId);
918
+ history.commitStep(() => {
919
+ useScene.getState().createNode(node, segmentId);
920
+ });
673
921
  placedId = node.id;
674
922
  }
675
923
  else {
924
+ // See commitToWall — restore the pre-drag baseline paused, drop as
925
+ // the ONE tracked write.
676
926
  useScene.getState().updateNode(movingWindowNode.id, {
677
927
  position: original.position,
678
928
  rotation: original.rotation,
679
929
  side: original.side,
680
930
  parentId: original.parentId,
681
931
  wallId: original.wallId,
932
+ dormerId: original.dormerId,
933
+ dormerFace: original.dormerFace,
682
934
  roofSegmentId: original.roofSegmentId,
683
935
  roofFace: original.roofFace,
684
936
  metadata: original.metadata,
685
937
  visible: original.visible,
686
938
  });
687
- useScene.temporal.getState().resume();
688
- useScene.getState().updateNode(movingWindowNode.id, {
689
- position: target.position,
690
- rotation: [0, 0, 0],
691
- side: 'front',
692
- parentId: segmentId,
693
- wallId: undefined,
694
- roofSegmentId: segmentId,
695
- roofFace: target.face.id,
696
- metadata: {},
697
- visible: true,
939
+ history.commitStep(() => {
940
+ useScene.getState().updateNode(movingWindowNode.id, {
941
+ position: target.position,
942
+ rotation: [0, 0, 0],
943
+ side: 'front',
944
+ parentId: segmentId,
945
+ wallId: undefined,
946
+ roofSegmentId: segmentId,
947
+ roofFace: target.face.id,
948
+ metadata: {},
949
+ visible: true,
950
+ });
698
951
  });
699
952
  if (original.parentId && original.parentId !== segmentId) {
700
953
  markHostDirty(original.parentId);
@@ -703,10 +956,9 @@ const MoveWindowTool = ({ node: movingWindowNode }) => {
703
956
  }
704
957
  markHostDirty(segmentId);
705
958
  useLiveTransforms.getState().clear(movingWindowNode.id);
706
- useScene.temporal.getState().pause();
707
959
  triggerSFX('sfx:structure-build');
708
960
  hideCursor();
709
- useViewer.getState().setSelection({ selectedIds: [placedId] });
961
+ selectNode(placedId);
710
962
  exitMoveMode();
711
963
  event.stopPropagation();
712
964
  };
@@ -714,12 +966,14 @@ const MoveWindowTool = ({ node: movingWindowNode }) => {
714
966
  // Mirror onWallLeave: don't revert to origin here — onGridMove takes
715
967
  // over on the same pointermove (snap to a nearby wall or free-follow).
716
968
  hideCursor();
969
+ useLiveNodeOverrides.getState().clear(movingWindowNode.id);
717
970
  useLiveTransforms.getState().clear(movingWindowNode.id);
718
971
  dragAnchor = null;
719
972
  lastTarget = null;
720
973
  lastRoofEvent = null;
721
974
  };
722
975
  const onCancel = () => {
976
+ useLiveNodeOverrides.getState().clear(movingWindowNode.id);
723
977
  useLiveTransforms.getState().clear(movingWindowNode.id);
724
978
  if (isNew) {
725
979
  useScene.getState().deleteNode(movingWindowNode.id);
@@ -733,6 +987,8 @@ const MoveWindowTool = ({ node: movingWindowNode }) => {
733
987
  side: original.side,
734
988
  parentId: original.parentId,
735
989
  wallId: original.wallId,
990
+ dormerId: original.dormerId,
991
+ dormerFace: original.dormerFace,
736
992
  roofSegmentId: original.roofSegmentId,
737
993
  roofFace: original.roofFace,
738
994
  metadata: original.metadata,
@@ -741,7 +997,10 @@ const MoveWindowTool = ({ node: movingWindowNode }) => {
741
997
  if (original.parentId)
742
998
  markHostDirty(original.parentId);
743
999
  }
744
- useScene.temporal.getState().resume();
1000
+ // The revert writes above ran under the gesture's history pause (never
1001
+ // tracked); ending the session here keeps a cancelled move out of undo
1002
+ // entirely. `end` is idempotent — the effect cleanup's end() is a no-op.
1003
+ history.end();
745
1004
  hideCursor();
746
1005
  exitMoveMode();
747
1006
  };
@@ -758,6 +1017,8 @@ const MoveWindowTool = ({ node: movingWindowNode }) => {
758
1017
  }
759
1018
  if (lastRoofEvent)
760
1019
  onRoofClick(lastRoofEvent);
1020
+ if (lastDormerEvent && lastDormerTarget)
1021
+ commitToDormer(lastDormerEvent, lastDormerTarget);
761
1022
  };
762
1023
  // R flips the window's facing side mid-placement (front ↔ back), like the
763
1024
  // committed-selected R flip — usable before commit, whether snapped to a
@@ -788,6 +1049,11 @@ const MoveWindowTool = ({ node: movingWindowNode }) => {
788
1049
  applyPreview(next);
789
1050
  }
790
1051
  }
1052
+ else if (lastDormerEvent) {
1053
+ const next = resolveDormerMoveTarget(lastDormerEvent);
1054
+ if (next)
1055
+ applyDormerPreview(lastDormerEvent, next);
1056
+ }
791
1057
  else if (lastFloorPoint) {
792
1058
  // Free-following: re-run at the same spot so the floating ghost rebuilds
793
1059
  // with the flipped side.
@@ -822,6 +1088,14 @@ const MoveWindowTool = ({ node: movingWindowNode }) => {
822
1088
  emitter.on('roof:move', onRoofHover);
823
1089
  emitter.on('roof:click', onRoofClick);
824
1090
  emitter.on('roof:leave', onRoofLeave);
1091
+ emitter.on('dormer:enter', onDormerHover);
1092
+ emitter.on('dormer:move', onDormerHover);
1093
+ emitter.on('dormer:click', onDormerClick);
1094
+ emitter.on('dormer:leave', onDormerLeave);
1095
+ emitter.on('window:enter', onDormerWindowHover);
1096
+ emitter.on('window:move', onDormerWindowHover);
1097
+ emitter.on('window:click', onDormerWindowClick);
1098
+ emitter.on('window:leave', onDormerWindowLeave);
825
1099
  emitter.on('grid:move', onGridMove);
826
1100
  emitter.on('tool:cancel', onCancel);
827
1101
  window.addEventListener('pointerup', onPlacementDragPointerUp);
@@ -865,6 +1139,8 @@ const MoveWindowTool = ({ node: movingWindowNode }) => {
865
1139
  side: original.side,
866
1140
  parentId: original.parentId,
867
1141
  wallId: original.wallId,
1142
+ dormerId: original.dormerId,
1143
+ dormerFace: original.dormerFace,
868
1144
  roofSegmentId: original.roofSegmentId,
869
1145
  roofFace: original.roofFace,
870
1146
  metadata: original.metadata,
@@ -880,12 +1156,14 @@ const MoveWindowTool = ({ node: movingWindowNode }) => {
880
1156
  // becomes an invisible orphan (place-preset deletes a true cancel).
881
1157
  useScene.getState().updateNode(movingWindowNode.id, { visible: true });
882
1158
  }
1159
+ useLiveNodeOverrides.getState().clear(movingWindowNode.id);
883
1160
  useLiveTransforms.getState().clear(movingWindowNode.id);
884
1161
  useAlignmentGuides.getState().clear();
885
1162
  clearOpeningGuides3D();
886
1163
  useFacingPose.getState().clear();
887
1164
  clearPlacementSurface();
888
- useScene.temporal.getState().resume();
1165
+ releaseHiddenWallHold();
1166
+ history.end();
889
1167
  emitter.off('wall:enter', onWallEnter);
890
1168
  emitter.off('wall:move', onWallMove);
891
1169
  emitter.off('wall:click', onWallClick);
@@ -894,6 +1172,14 @@ const MoveWindowTool = ({ node: movingWindowNode }) => {
894
1172
  emitter.off('roof:move', onRoofHover);
895
1173
  emitter.off('roof:click', onRoofClick);
896
1174
  emitter.off('roof:leave', onRoofLeave);
1175
+ emitter.off('dormer:enter', onDormerHover);
1176
+ emitter.off('dormer:move', onDormerHover);
1177
+ emitter.off('dormer:click', onDormerClick);
1178
+ emitter.off('dormer:leave', onDormerLeave);
1179
+ emitter.off('window:enter', onDormerWindowHover);
1180
+ emitter.off('window:move', onDormerWindowHover);
1181
+ emitter.off('window:click', onDormerWindowClick);
1182
+ emitter.off('window:leave', onDormerWindowLeave);
897
1183
  emitter.off('grid:move', onGridMove);
898
1184
  emitter.off('tool:cancel', onCancel);
899
1185
  window.removeEventListener('pointerup', onPlacementDragPointerUp);
@@ -901,7 +1187,7 @@ const MoveWindowTool = ({ node: movingWindowNode }) => {
901
1187
  window.removeEventListener('keydown', onAltToggle);
902
1188
  window.removeEventListener('keyup', onAltToggle);
903
1189
  };
904
- }, [movingWindowNode, exitMoveMode]);
1190
+ }, [activeLevelId, exitMoveMode, isCameraDragging, movingWindowNode, selectNode]);
905
1191
  const edgesGeo = useMemo(() => {
906
1192
  const boxGeo = new BoxGeometry(movingWindowNode.width, movingWindowNode.height, movingWindowNode.frameDepth ?? 0.07);
907
1193
  const geo = new EdgesGeometry(boxGeo);