@pascal-app/nodes 1.0.6 → 1.0.7

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 (566) hide show
  1. package/README.md +1 -0
  2. package/dist/beam/actions/move-endpoint.d.ts +24 -0
  3. package/dist/beam/actions/move-endpoint.d.ts.map +1 -0
  4. package/dist/beam/actions/move-endpoint.js +54 -0
  5. package/dist/beam/definition.d.ts +14 -0
  6. package/dist/beam/definition.d.ts.map +1 -0
  7. package/dist/beam/definition.js +173 -0
  8. package/dist/beam/draft-settings.d.ts +17 -0
  9. package/dist/beam/draft-settings.d.ts.map +1 -0
  10. package/dist/beam/draft-settings.js +81 -0
  11. package/dist/beam/drafting.d.ts +35 -0
  12. package/dist/beam/drafting.d.ts.map +1 -0
  13. package/dist/beam/drafting.js +103 -0
  14. package/dist/beam/floorplan-affordances.d.ts +8 -0
  15. package/dist/beam/floorplan-affordances.d.ts.map +1 -0
  16. package/dist/beam/floorplan-affordances.js +40 -0
  17. package/dist/beam/floorplan-move.d.ts +11 -0
  18. package/dist/beam/floorplan-move.d.ts.map +1 -0
  19. package/dist/beam/floorplan-move.js +54 -0
  20. package/dist/beam/floorplan.d.ts +11 -0
  21. package/dist/beam/floorplan.d.ts.map +1 -0
  22. package/dist/beam/floorplan.js +91 -0
  23. package/dist/beam/geometry.d.ts +19 -0
  24. package/dist/beam/geometry.d.ts.map +1 -0
  25. package/dist/beam/geometry.js +63 -0
  26. package/dist/beam/index.d.ts +3 -0
  27. package/dist/beam/index.d.ts.map +1 -0
  28. package/dist/beam/index.js +2 -0
  29. package/dist/beam/move-endpoint-tool.d.ts +21 -0
  30. package/dist/beam/move-endpoint-tool.d.ts.map +1 -0
  31. package/dist/beam/move-endpoint-tool.js +49 -0
  32. package/dist/beam/move-tool.d.ts +12 -0
  33. package/dist/beam/move-tool.d.ts.map +1 -0
  34. package/dist/beam/move-tool.js +114 -0
  35. package/dist/beam/panel-model.d.ts +28 -0
  36. package/dist/beam/panel-model.d.ts.map +1 -0
  37. package/dist/beam/panel-model.js +123 -0
  38. package/dist/beam/panel.d.ts +13 -0
  39. package/dist/beam/panel.d.ts.map +1 -0
  40. package/dist/beam/panel.js +107 -0
  41. package/dist/beam/parametrics.d.ts +3 -0
  42. package/dist/beam/parametrics.d.ts.map +1 -0
  43. package/dist/beam/parametrics.js +4 -0
  44. package/dist/beam/renderer.d.ts +13 -0
  45. package/dist/beam/renderer.d.ts.map +1 -0
  46. package/dist/beam/renderer.js +36 -0
  47. package/dist/beam/schema.d.ts +2 -0
  48. package/dist/beam/schema.d.ts.map +1 -0
  49. package/dist/beam/schema.js +1 -0
  50. package/dist/beam/tool.d.ts +13 -0
  51. package/dist/beam/tool.d.ts.map +1 -0
  52. package/dist/beam/tool.js +152 -0
  53. package/dist/box-vent/panel.d.ts.map +1 -1
  54. package/dist/box-vent/panel.js +8 -7
  55. package/dist/cabinet/batchable.d.ts +10 -0
  56. package/dist/cabinet/batchable.d.ts.map +1 -0
  57. package/dist/cabinet/batchable.js +12 -0
  58. package/dist/cabinet/compartment-card.d.ts.map +1 -1
  59. package/dist/cabinet/compartment-card.js +142 -46
  60. package/dist/cabinet/countertop-layout.d.ts +5 -0
  61. package/dist/cabinet/countertop-layout.d.ts.map +1 -1
  62. package/dist/cabinet/definition.d.ts.map +1 -1
  63. package/dist/cabinet/definition.js +3 -0
  64. package/dist/cabinet/dimension-input.d.ts +6 -0
  65. package/dist/cabinet/dimension-input.d.ts.map +1 -0
  66. package/dist/cabinet/dimension-input.js +8 -0
  67. package/dist/cabinet/essential-controls.d.ts.map +1 -1
  68. package/dist/cabinet/essential-controls.js +82 -17
  69. package/dist/cabinet/index.d.ts +1 -1
  70. package/dist/cabinet/index.d.ts.map +1 -1
  71. package/dist/cabinet/index.js +1 -1
  72. package/dist/cabinet/kitchen-catalog.d.ts +17 -4
  73. package/dist/cabinet/kitchen-catalog.d.ts.map +1 -1
  74. package/dist/cabinet/kitchen-catalog.js +45 -7
  75. package/dist/cabinet/kitchen-collection.d.ts.map +1 -1
  76. package/dist/cabinet/kitchen-collection.js +21 -5
  77. package/dist/cabinet/kitchen-module-actions.d.ts.map +1 -1
  78. package/dist/cabinet/kitchen-module-actions.js +107 -14
  79. package/dist/cabinet/neighbor-placement.d.ts +10 -0
  80. package/dist/cabinet/neighbor-placement.d.ts.map +1 -1
  81. package/dist/cabinet/panel.d.ts.map +1 -1
  82. package/dist/cabinet/panel.js +127 -50
  83. package/dist/cabinet/run-finishing.d.ts +5 -0
  84. package/dist/cabinet/run-finishing.d.ts.map +1 -1
  85. package/dist/cabinet/run-ops.d.ts +5 -0
  86. package/dist/cabinet/run-ops.d.ts.map +1 -1
  87. package/dist/cabinet/run-panel.d.ts.map +1 -1
  88. package/dist/cabinet/run-panel.js +203 -52
  89. package/dist/cabinet/tool.d.ts.map +1 -1
  90. package/dist/cabinet/tool.js +8 -5
  91. package/dist/ceiling/build-up-section.d.ts +7 -0
  92. package/dist/ceiling/build-up-section.d.ts.map +1 -0
  93. package/dist/ceiling/build-up-section.js +57 -0
  94. package/dist/ceiling/definition.d.ts.map +1 -1
  95. package/dist/ceiling/definition.js +3 -1
  96. package/dist/ceiling/floorplan-affordances.d.ts +112 -0
  97. package/dist/ceiling/floorplan-affordances.d.ts.map +1 -1
  98. package/dist/ceiling/materials.d.ts +5 -0
  99. package/dist/ceiling/materials.d.ts.map +1 -1
  100. package/dist/ceiling/materials.js +17 -0
  101. package/dist/ceiling/panel-model.d.ts +13 -0
  102. package/dist/ceiling/panel-model.d.ts.map +1 -0
  103. package/dist/ceiling/panel-model.js +49 -0
  104. package/dist/ceiling/panel.d.ts.map +1 -1
  105. package/dist/ceiling/panel.js +82 -18
  106. package/dist/ceiling/renderer.d.ts.map +1 -1
  107. package/dist/ceiling/renderer.js +10 -4
  108. package/dist/ceiling/tool.d.ts.map +1 -1
  109. package/dist/ceiling/tool.js +24 -4
  110. package/dist/chimney/panel.d.ts.map +1 -1
  111. package/dist/chimney/panel.js +113 -41
  112. package/dist/column/definition.d.ts.map +1 -1
  113. package/dist/column/definition.js +3 -0
  114. package/dist/column/floorplan.d.ts.map +1 -1
  115. package/dist/column/floorplan.js +17 -0
  116. package/dist/column/hosted-resize.d.ts +28 -1
  117. package/dist/column/hosted-resize.d.ts.map +1 -1
  118. package/dist/column/panel.d.ts.map +1 -1
  119. package/dist/column/panel.js +125 -37
  120. package/dist/column/post-options.d.ts +10 -0
  121. package/dist/column/post-options.d.ts.map +1 -0
  122. package/dist/column/post-options.js +71 -0
  123. package/dist/column/post-placement.d.ts +78 -0
  124. package/dist/column/post-placement.d.ts.map +1 -0
  125. package/dist/column/post-placement.js +157 -0
  126. package/dist/column/post-section.d.ts +17 -0
  127. package/dist/column/post-section.d.ts.map +1 -0
  128. package/dist/column/post-section.js +95 -0
  129. package/dist/column/post-tool.d.ts +11 -0
  130. package/dist/column/post-tool.d.ts.map +1 -0
  131. package/dist/column/post-tool.js +94 -0
  132. package/dist/column/tool.d.ts +3 -10
  133. package/dist/column/tool.d.ts.map +1 -1
  134. package/dist/column/tool.js +13 -1
  135. package/dist/cupola/panel.d.ts.map +1 -1
  136. package/dist/cupola/panel.js +14 -7
  137. package/dist/door/actions.d.ts +7 -0
  138. package/dist/door/actions.d.ts.map +1 -0
  139. package/dist/door/actions.js +32 -0
  140. package/dist/door/contextual-dimensions.d.ts.map +1 -1
  141. package/dist/door/contextual-dimensions.js +11 -1
  142. package/dist/door/definition.d.ts.map +1 -1
  143. package/dist/door/definition.js +34 -7
  144. package/dist/door/floorplan-affordances.d.ts.map +1 -1
  145. package/dist/door/floorplan-affordances.js +5 -2
  146. package/dist/door/floorplan-move.d.ts.map +1 -1
  147. package/dist/door/floorplan-move.js +28 -6
  148. package/dist/door/floorplan.d.ts +2 -0
  149. package/dist/door/floorplan.d.ts.map +1 -1
  150. package/dist/door/floorplan.js +89 -16
  151. package/dist/door/move-tool.d.ts.map +1 -1
  152. package/dist/door/move-tool.js +60 -16
  153. package/dist/door/paint.d.ts +2 -7
  154. package/dist/door/paint.d.ts.map +1 -1
  155. package/dist/door/paint.js +26 -2
  156. package/dist/door/panel.d.ts.map +1 -1
  157. package/dist/door/panel.js +242 -90
  158. package/dist/door/parametrics.js +1 -1
  159. package/dist/door/placement.d.ts.map +1 -1
  160. package/dist/door/placement.js +9 -2
  161. package/dist/door/swing.d.ts +22 -0
  162. package/dist/door/swing.d.ts.map +1 -0
  163. package/dist/door/swing.js +36 -0
  164. package/dist/door/tool.d.ts.map +1 -1
  165. package/dist/door/tool.js +76 -29
  166. package/dist/dormer/panel-actions-section.d.ts.map +1 -1
  167. package/dist/dormer/panel-actions-section.js +3 -1
  168. package/dist/dormer/panel-position-section.d.ts.map +1 -1
  169. package/dist/dormer/panel-position-section.js +4 -3
  170. package/dist/dormer/panel-windows-section.d.ts.map +1 -1
  171. package/dist/dormer/panel-windows-section.js +38 -1
  172. package/dist/dormer/panel.d.ts.map +1 -1
  173. package/dist/dormer/panel.js +24 -18
  174. package/dist/downspout/inspector-editors.d.ts.map +1 -1
  175. package/dist/downspout/inspector-editors.js +3 -2
  176. package/dist/duct-fitting/inspector-editors.d.ts.map +1 -1
  177. package/dist/duct-fitting/inspector-editors.js +6 -1
  178. package/dist/duct-fitting/tool.d.ts.map +1 -1
  179. package/dist/duct-fitting/tool.js +11 -2
  180. package/dist/duct-terminal/tool.d.ts.map +1 -1
  181. package/dist/duct-terminal/tool.js +11 -2
  182. package/dist/elevator/panel.d.ts.map +1 -1
  183. package/dist/elevator/panel.js +41 -18
  184. package/dist/eyebrow-vent/panel.d.ts.map +1 -1
  185. package/dist/eyebrow-vent/panel.js +16 -6
  186. package/dist/fence/drafting.d.ts +2 -3
  187. package/dist/fence/drafting.d.ts.map +1 -1
  188. package/dist/fence/drafting.js +2 -3
  189. package/dist/fence/inspector-editors.d.ts.map +1 -1
  190. package/dist/fence/inspector-editors.js +64 -21
  191. package/dist/fence/move-endpoint-tool.d.ts.map +1 -1
  192. package/dist/fence/move-endpoint-tool.js +11 -2
  193. package/dist/fence/system.d.ts.map +1 -1
  194. package/dist/fence/system.js +13 -0
  195. package/dist/fence-feature/actions.d.ts.map +1 -1
  196. package/dist/fence-feature/actions.js +5 -2
  197. package/dist/fence-feature/inspector.d.ts.map +1 -1
  198. package/dist/fence-feature/inspector.js +150 -34
  199. package/dist/fence-feature/move-session.d.ts +1 -1
  200. package/dist/floor-opening/floorplan.d.ts +29 -6
  201. package/dist/floor-opening/floorplan.d.ts.map +1 -1
  202. package/dist/floor-opening/floorplan.js +172 -14
  203. package/dist/gutter/downspouts-panel.d.ts.map +1 -1
  204. package/dist/gutter/downspouts-panel.js +14 -2
  205. package/dist/hvac-equipment/tool.d.ts.map +1 -1
  206. package/dist/hvac-equipment/tool.js +3 -2
  207. package/dist/i18n/definition-messages.d.ts +5 -0
  208. package/dist/i18n/definition-messages.d.ts.map +1 -0
  209. package/dist/i18n/definition-messages.js +771 -0
  210. package/dist/index.d.ts +4 -1
  211. package/dist/index.d.ts.map +1 -1
  212. package/dist/index.js +6 -1
  213. package/dist/item/authored-params.d.ts.map +1 -1
  214. package/dist/item/authored-params.js +19 -4
  215. package/dist/item/floorplan.d.ts +1 -1
  216. package/dist/item/floorplan.d.ts.map +1 -1
  217. package/dist/item/panel.d.ts.map +1 -1
  218. package/dist/item/panel.js +9 -7
  219. package/dist/liquid-line/tool.d.ts.map +1 -1
  220. package/dist/liquid-line/tool.js +10 -3
  221. package/dist/measurement/tool.d.ts +1 -1
  222. package/dist/measurement/tool.d.ts.map +1 -1
  223. package/dist/measurement/tool.js +8 -8
  224. package/dist/pipe-fitting/tool.d.ts.map +1 -1
  225. package/dist/pipe-fitting/tool.js +3 -2
  226. package/dist/pipe-trap/tool.d.ts.map +1 -1
  227. package/dist/pipe-trap/tool.js +7 -2
  228. package/dist/procedural-item/renderer.d.ts.map +1 -1
  229. package/dist/procedural-item/renderer.js +8 -1
  230. package/dist/ridge-vent/panel.d.ts.map +1 -1
  231. package/dist/ridge-vent/panel.js +22 -9
  232. package/dist/roof/barrel-panel.d.ts.map +1 -1
  233. package/dist/roof/barrel-panel.js +7 -3
  234. package/dist/roof/definition.d.ts.map +1 -1
  235. package/dist/roof/definition.js +33 -3
  236. package/dist/roof/floorplan-overrides.d.ts +22 -0
  237. package/dist/roof/floorplan-overrides.d.ts.map +1 -0
  238. package/dist/roof/floorplan-overrides.js +46 -0
  239. package/dist/roof/floorplan-tool.d.ts +9 -0
  240. package/dist/roof/floorplan-tool.d.ts.map +1 -0
  241. package/dist/roof/floorplan-tool.js +168 -0
  242. package/dist/roof/floorplan.d.ts.map +1 -1
  243. package/dist/roof/floorplan.js +131 -41
  244. package/dist/roof/glazing-controls.d.ts +2 -1
  245. package/dist/roof/glazing-controls.d.ts.map +1 -1
  246. package/dist/roof/glazing-controls.js +51 -13
  247. package/dist/roof/glazing-panel-editor.d.ts.map +1 -1
  248. package/dist/roof/glazing-panel-editor.js +40 -13
  249. package/dist/roof/glazing-panel.d.ts.map +1 -1
  250. package/dist/roof/glazing-panel.js +73 -9
  251. package/dist/roof/paint.d.ts +19 -0
  252. package/dist/roof/paint.d.ts.map +1 -0
  253. package/dist/roof/paint.js +158 -0
  254. package/dist/roof/panel.d.ts.map +1 -1
  255. package/dist/roof/panel.js +90 -22
  256. package/dist/roof/renderer.d.ts.map +1 -1
  257. package/dist/roof/renderer.js +13 -2
  258. package/dist/roof/roof-footprint-source.d.ts +17 -0
  259. package/dist/roof/roof-footprint-source.d.ts.map +1 -1
  260. package/dist/roof/roof-footprint-source.js +14 -0
  261. package/dist/roof/roof-footprint.d.ts +36 -2
  262. package/dist/roof/roof-footprint.d.ts.map +1 -1
  263. package/dist/roof/roof-footprint.js +124 -2
  264. package/dist/roof/roof-materials.d.ts.map +1 -1
  265. package/dist/roof/roof-materials.js +10 -1
  266. package/dist/roof/roof-placement-mode.d.ts +0 -2
  267. package/dist/roof/roof-placement-mode.d.ts.map +1 -1
  268. package/dist/roof/roof-placement-mode.js +8 -6
  269. package/dist/roof/roof-plan-creases.d.ts +50 -0
  270. package/dist/roof/roof-plan-creases.d.ts.map +1 -0
  271. package/dist/roof/roof-plan-creases.js +194 -0
  272. package/dist/roof/roof-ridge-mode.d.ts +20 -0
  273. package/dist/roof/roof-ridge-mode.d.ts.map +1 -0
  274. package/dist/roof/roof-ridge-mode.js +16 -0
  275. package/dist/roof/tool.d.ts +17 -4
  276. package/dist/roof/tool.d.ts.map +1 -1
  277. package/dist/roof/tool.js +211 -113
  278. package/dist/roof/wall-catch.d.ts +106 -0
  279. package/dist/roof/wall-catch.d.ts.map +1 -0
  280. package/dist/roof/wall-catch.js +267 -0
  281. package/dist/roof-segment/build-up-section.d.ts +9 -0
  282. package/dist/roof-segment/build-up-section.d.ts.map +1 -0
  283. package/dist/roof-segment/build-up-section.js +191 -0
  284. package/dist/roof-segment/definition.d.ts.map +1 -1
  285. package/dist/roof-segment/definition.js +50 -5
  286. package/dist/roof-segment/floorplan-affordances.d.ts.map +1 -1
  287. package/dist/roof-segment/floorplan-affordances.js +68 -19
  288. package/dist/roof-segment/floorplan.d.ts.map +1 -1
  289. package/dist/roof-segment/floorplan.js +16 -12
  290. package/dist/roof-segment/paint.d.ts +3 -1
  291. package/dist/roof-segment/paint.d.ts.map +1 -1
  292. package/dist/roof-segment/paint.js +43 -2
  293. package/dist/roof-segment/panel-model.d.ts +23 -0
  294. package/dist/roof-segment/panel-model.d.ts.map +1 -0
  295. package/dist/roof-segment/panel-model.js +64 -0
  296. package/dist/roof-segment/panel.d.ts.map +1 -1
  297. package/dist/roof-segment/panel.js +96 -14
  298. package/dist/roof-segment/parametrics.d.ts.map +1 -1
  299. package/dist/roof-segment/parametrics.js +4 -0
  300. package/dist/roof-segment/renderer.d.ts.map +1 -1
  301. package/dist/roof-segment/renderer.js +26 -5
  302. package/dist/separator/definition.d.ts.map +1 -1
  303. package/dist/separator/definition.js +10 -12
  304. package/dist/separator/floorplan-affordances.d.ts +9 -0
  305. package/dist/separator/floorplan-affordances.d.ts.map +1 -0
  306. package/dist/separator/floorplan-affordances.js +23 -0
  307. package/dist/separator/floorplan.d.ts +9 -0
  308. package/dist/separator/floorplan.d.ts.map +1 -0
  309. package/dist/separator/floorplan.js +54 -0
  310. package/dist/separator/renderer.d.ts +4 -0
  311. package/dist/separator/renderer.d.ts.map +1 -1
  312. package/dist/separator/renderer.js +21 -6
  313. package/dist/separator/selection.d.ts +10 -0
  314. package/dist/separator/selection.d.ts.map +1 -0
  315. package/dist/separator/selection.js +35 -0
  316. package/dist/shared/build-up-controls.d.ts +88 -0
  317. package/dist/shared/build-up-controls.d.ts.map +1 -0
  318. package/dist/shared/build-up-controls.js +139 -0
  319. package/dist/shared/curtain-opening-limits.d.ts.map +1 -1
  320. package/dist/shared/curtain-opening-limits.js +44 -14
  321. package/dist/shared/item-interaction-actions.d.ts.map +1 -1
  322. package/dist/shared/item-interaction-actions.js +11 -2
  323. package/dist/shared/layer-thickness.d.ts +2 -0
  324. package/dist/shared/layer-thickness.d.ts.map +1 -0
  325. package/dist/shared/layer-thickness.js +3 -0
  326. package/dist/shared/move-roof-tool.d.ts.map +1 -1
  327. package/dist/shared/move-roof-tool.js +100 -5
  328. package/dist/shared/node-batch/batchable.d.ts +2 -0
  329. package/dist/shared/node-batch/batchable.d.ts.map +1 -1
  330. package/dist/shared/node-batch/batchable.js +4 -0
  331. package/dist/shared/node-batch/candidates.d.ts +21 -5
  332. package/dist/shared/node-batch/candidates.d.ts.map +1 -1
  333. package/dist/shared/node-batch/candidates.js +85 -50
  334. package/dist/shared/node-batch/system.d.ts.map +1 -1
  335. package/dist/shared/node-batch/system.js +24 -15
  336. package/dist/shared/opening-casing-move.d.ts +16 -0
  337. package/dist/shared/opening-casing-move.d.ts.map +1 -0
  338. package/dist/shared/opening-casing-move.js +33 -0
  339. package/dist/shared/opening-casing-section.d.ts +15 -0
  340. package/dist/shared/opening-casing-section.d.ts.map +1 -0
  341. package/dist/shared/opening-casing-section.js +38 -0
  342. package/dist/shared/opening-casing.d.ts +26 -0
  343. package/dist/shared/opening-casing.d.ts.map +1 -0
  344. package/dist/shared/opening-casing.js +80 -0
  345. package/dist/shared/opening-depth-position.d.ts +13 -0
  346. package/dist/shared/opening-depth-position.d.ts.map +1 -0
  347. package/dist/shared/opening-depth-position.js +34 -0
  348. package/dist/shared/opening-documentation.d.ts.map +1 -1
  349. package/dist/shared/opening-documentation.js +17 -8
  350. package/dist/shared/opening-guides-runtime.d.ts +2 -1
  351. package/dist/shared/opening-guides-runtime.d.ts.map +1 -1
  352. package/dist/shared/opening-guides-runtime.js +11 -7
  353. package/dist/shared/opening-labels.d.ts +11 -0
  354. package/dist/shared/opening-labels.d.ts.map +1 -0
  355. package/dist/shared/opening-labels.js +46 -0
  356. package/dist/shared/opening-placement-dimensions.d.ts.map +1 -1
  357. package/dist/shared/opening-placement-dimensions.js +11 -9
  358. package/dist/shared/opening-plane-offset.d.ts +4 -3
  359. package/dist/shared/opening-plane-offset.d.ts.map +1 -1
  360. package/dist/shared/opening-plane-offset.js +7 -4
  361. package/dist/shared/opening-swap.d.ts +8 -0
  362. package/dist/shared/opening-swap.d.ts.map +1 -0
  363. package/dist/shared/opening-swap.js +18 -0
  364. package/dist/shared/polygon-vertex-affordance.d.ts +19 -0
  365. package/dist/shared/polygon-vertex-affordance.d.ts.map +1 -1
  366. package/dist/shared/polygon-vertex-affordance.js +65 -6
  367. package/dist/shared/roof-opening-host.d.ts +2 -1
  368. package/dist/shared/roof-opening-host.d.ts.map +1 -1
  369. package/dist/shared/roof-opening-host.js +14 -5
  370. package/dist/shared/roof-wall-opening-cut.d.ts.map +1 -1
  371. package/dist/shared/roof-wall-opening-cut.js +14 -6
  372. package/dist/shared/roof-wall-opening-placement.d.ts +2 -1
  373. package/dist/shared/roof-wall-opening-placement.d.ts.map +1 -1
  374. package/dist/shared/roof-wall-opening-placement.js +6 -4
  375. package/dist/shared/run-hanger-inspector.d.ts.map +1 -1
  376. package/dist/shared/run-hanger-inspector.js +39 -5
  377. package/dist/shared/system-check-panel.d.ts.map +1 -1
  378. package/dist/shared/system-check-panel.js +94 -15
  379. package/dist/shared/wall-attach-target.d.ts.map +1 -1
  380. package/dist/shared/wall-attach-target.js +6 -3
  381. package/dist/shelf/definition.d.ts.map +1 -1
  382. package/dist/shelf/definition.js +2 -0
  383. package/dist/site/ground-hole.d.ts +3 -3
  384. package/dist/site/ground-hole.js +3 -3
  385. package/dist/site/ground-veil.d.ts +5 -12
  386. package/dist/site/ground-veil.d.ts.map +1 -1
  387. package/dist/site/ground-veil.js +9 -33
  388. package/dist/site/panel.d.ts.map +1 -1
  389. package/dist/site/panel.js +52 -12
  390. package/dist/site/renderer.d.ts.map +1 -1
  391. package/dist/site/renderer.js +52 -23
  392. package/dist/skylight/panel.d.ts.map +1 -1
  393. package/dist/skylight/panel.js +49 -19
  394. package/dist/slab/deck-geometry.d.ts +28 -0
  395. package/dist/slab/deck-geometry.d.ts.map +1 -0
  396. package/dist/slab/deck-geometry.js +320 -0
  397. package/dist/slab/definition.d.ts +2 -1
  398. package/dist/slab/definition.d.ts.map +1 -1
  399. package/dist/slab/definition.js +6 -1
  400. package/dist/slab/dependency-tracker.d.ts.map +1 -1
  401. package/dist/slab/dependency-tracker.js +3 -0
  402. package/dist/slab/floorplan-affordances.d.ts +500 -0
  403. package/dist/slab/floorplan-affordances.d.ts.map +1 -1
  404. package/dist/slab/geometry.d.ts.map +1 -1
  405. package/dist/slab/geometry.js +46 -9
  406. package/dist/slab/panel.d.ts.map +1 -1
  407. package/dist/slab/panel.js +97 -21
  408. package/dist/slab/renderer.d.ts +11 -0
  409. package/dist/slab/renderer.d.ts.map +1 -0
  410. package/dist/slab/renderer.js +19 -0
  411. package/dist/slab/system.d.ts.map +1 -1
  412. package/dist/slab/system.js +12 -1
  413. package/dist/solar-panel/panel.d.ts.map +1 -1
  414. package/dist/solar-panel/panel.js +49 -14
  415. package/dist/stair/construction-controls.d.ts +3 -1
  416. package/dist/stair/construction-controls.d.ts.map +1 -1
  417. package/dist/stair/construction-controls.js +75 -12
  418. package/dist/stair/paint.d.ts +6 -0
  419. package/dist/stair/paint.d.ts.map +1 -1
  420. package/dist/stair/panel.d.ts.map +1 -1
  421. package/dist/stair/panel.js +243 -51
  422. package/dist/stair/parametrics.d.ts.map +1 -1
  423. package/dist/stair/parametrics.js +7 -0
  424. package/dist/stair/placement-defaults.d.ts +18 -0
  425. package/dist/stair/placement-defaults.d.ts.map +1 -0
  426. package/dist/stair/placement-defaults.js +27 -0
  427. package/dist/stair/railing-controls.d.ts.map +1 -1
  428. package/dist/stair/railing-controls.js +78 -18
  429. package/dist/stair/renderer.d.ts.map +1 -1
  430. package/dist/stair/renderer.js +16 -10
  431. package/dist/stair/structure-controls.d.ts +18 -0
  432. package/dist/stair/structure-controls.d.ts.map +1 -0
  433. package/dist/stair/structure-controls.js +275 -0
  434. package/dist/stair/tool.d.ts.map +1 -1
  435. package/dist/stair/tool.js +13 -9
  436. package/dist/stair/use-stair-render-data.d.ts +41 -0
  437. package/dist/stair/use-stair-render-data.d.ts.map +1 -1
  438. package/dist/stair-segment/panel.d.ts.map +1 -1
  439. package/dist/stair-segment/panel.js +65 -18
  440. package/dist/turbine-vent/panel.d.ts.map +1 -1
  441. package/dist/turbine-vent/panel.js +14 -5
  442. package/dist/unit/unit-panel.d.ts.map +1 -1
  443. package/dist/unit/unit-panel.js +28 -12
  444. package/dist/wall/actions.d.ts +1 -1
  445. package/dist/wall/actions.d.ts.map +1 -1
  446. package/dist/wall/actions.js +17 -13
  447. package/dist/wall/construction-dimensions.d.ts +6 -0
  448. package/dist/wall/construction-dimensions.d.ts.map +1 -1
  449. package/dist/wall/construction-dimensions.js +8 -0
  450. package/dist/wall/contextual-dimensions.d.ts +6 -0
  451. package/dist/wall/contextual-dimensions.d.ts.map +1 -1
  452. package/dist/wall/contextual-dimensions.js +104 -17
  453. package/dist/wall/curtain-opening-frame.d.ts.map +1 -1
  454. package/dist/wall/curtain-opening-frame.js +6 -4
  455. package/dist/wall/curtain-wall-layout.d.ts +1 -1
  456. package/dist/wall/curtain-wall-layout.d.ts.map +1 -1
  457. package/dist/wall/curtain-wall-layout.js +6 -4
  458. package/dist/wall/curtain-wall-materials.d.ts.map +1 -1
  459. package/dist/wall/curtain-wall-materials.js +8 -3
  460. package/dist/wall/curtain-wall-panel.d.ts.map +1 -1
  461. package/dist/wall/curtain-wall-panel.js +241 -37
  462. package/dist/wall/curve-tool.d.ts.map +1 -1
  463. package/dist/wall/curve-tool.js +2 -3
  464. package/dist/wall/definition.d.ts.map +1 -1
  465. package/dist/wall/definition.js +20 -5
  466. package/dist/wall/floorplan-affordances.d.ts.map +1 -1
  467. package/dist/wall/floorplan-affordances.js +9 -6
  468. package/dist/wall/floorplan-move.d.ts.map +1 -1
  469. package/dist/wall/floorplan-move.js +66 -16
  470. package/dist/wall/floorplan.d.ts +4 -5
  471. package/dist/wall/floorplan.d.ts.map +1 -1
  472. package/dist/wall/floorplan.js +62 -46
  473. package/dist/wall/move-endpoint-tool.d.ts.map +1 -1
  474. package/dist/wall/move-endpoint-tool.js +1 -0
  475. package/dist/wall/move-tool.d.ts.map +1 -1
  476. package/dist/wall/move-tool.js +77 -12
  477. package/dist/wall/paint.d.ts +2 -2
  478. package/dist/wall/paint.d.ts.map +1 -1
  479. package/dist/wall/paint.js +11 -4
  480. package/dist/wall/panel-model.d.ts +17 -2
  481. package/dist/wall/panel-model.d.ts.map +1 -1
  482. package/dist/wall/panel-model.js +158 -18
  483. package/dist/wall/panel.d.ts +8 -0
  484. package/dist/wall/panel.d.ts.map +1 -1
  485. package/dist/wall/panel.js +228 -156
  486. package/dist/wall/parametrics.d.ts +1 -1
  487. package/dist/wall/parametrics.d.ts.map +1 -1
  488. package/dist/wall/parametrics.js +14 -1
  489. package/dist/wall/railing-wall-adapter.d.ts +7 -0
  490. package/dist/wall/railing-wall-adapter.d.ts.map +1 -0
  491. package/dist/wall/railing-wall-adapter.js +38 -0
  492. package/dist/wall/railing-wall-floorplan.d.ts +8 -0
  493. package/dist/wall/railing-wall-floorplan.d.ts.map +1 -0
  494. package/dist/wall/railing-wall-floorplan.js +27 -0
  495. package/dist/wall/railing-wall-geometry.d.ts +12 -0
  496. package/dist/wall/railing-wall-geometry.d.ts.map +1 -0
  497. package/dist/wall/railing-wall-geometry.js +51 -0
  498. package/dist/wall/railing-wall-guard.d.ts +81 -0
  499. package/dist/wall/railing-wall-guard.d.ts.map +1 -0
  500. package/dist/wall/railing-wall-guard.js +435 -0
  501. package/dist/wall/railing-wall-materials.d.ts +11 -0
  502. package/dist/wall/railing-wall-materials.d.ts.map +1 -0
  503. package/dist/wall/railing-wall-materials.js +31 -0
  504. package/dist/wall/railing-wall-panel-model.d.ts +30 -0
  505. package/dist/wall/railing-wall-panel-model.d.ts.map +1 -0
  506. package/dist/wall/railing-wall-panel-model.js +117 -0
  507. package/dist/wall/railing-wall-panel.d.ts +17 -0
  508. package/dist/wall/railing-wall-panel.d.ts.map +1 -0
  509. package/dist/wall/railing-wall-panel.js +42 -0
  510. package/dist/wall/rectangle-command.d.ts +79 -1
  511. package/dist/wall/rectangle-command.d.ts.map +1 -1
  512. package/dist/wall/rectangle-tool.d.ts.map +1 -1
  513. package/dist/wall/rectangle-tool.js +2 -0
  514. package/dist/wall/renderer.d.ts.map +1 -1
  515. package/dist/wall/renderer.js +3 -1
  516. package/dist/wall/skirting-floor-gaps.d.ts +8 -0
  517. package/dist/wall/skirting-floor-gaps.d.ts.map +1 -0
  518. package/dist/wall/skirting-floor-gaps.js +36 -0
  519. package/dist/wall/system.d.ts +0 -14
  520. package/dist/wall/system.d.ts.map +1 -1
  521. package/dist/wall/system.js +6 -1
  522. package/dist/wall/tool.d.ts +16 -0
  523. package/dist/wall/tool.d.ts.map +1 -1
  524. package/dist/wall/tool.js +160 -47
  525. package/dist/wall/treatments.d.ts +3 -0
  526. package/dist/wall/treatments.d.ts.map +1 -1
  527. package/dist/wall/treatments.js +30 -7
  528. package/dist/window/actions.d.ts +7 -0
  529. package/dist/window/actions.d.ts.map +1 -0
  530. package/dist/window/actions.js +29 -0
  531. package/dist/window/definition.d.ts.map +1 -1
  532. package/dist/window/definition.js +11 -2
  533. package/dist/window/floorplan-move.d.ts.map +1 -1
  534. package/dist/window/floorplan-move.js +5 -0
  535. package/dist/window/floorplan.d.ts +2 -0
  536. package/dist/window/floorplan.d.ts.map +1 -1
  537. package/dist/window/floorplan.js +58 -1
  538. package/dist/window/mechanism.d.ts.map +1 -1
  539. package/dist/window/mechanism.js +21 -1
  540. package/dist/window/move-tool.d.ts.map +1 -1
  541. package/dist/window/move-tool.js +10 -3
  542. package/dist/window/paint.d.ts +2 -7
  543. package/dist/window/paint.d.ts.map +1 -1
  544. package/dist/window/paint.js +31 -3
  545. package/dist/window/panel.d.ts.map +1 -1
  546. package/dist/window/panel.js +311 -69
  547. package/dist/window/placement.d.ts.map +1 -1
  548. package/dist/window/placement.js +5 -1
  549. package/dist/window/swing.d.ts +13 -0
  550. package/dist/window/swing.d.ts.map +1 -0
  551. package/dist/window/swing.js +16 -0
  552. package/dist/window/tool.d.ts.map +1 -1
  553. package/dist/window/tool.js +19 -14
  554. package/dist/zone/floorplan-affordances.d.ts +136 -0
  555. package/dist/zone/floorplan-affordances.d.ts.map +1 -1
  556. package/dist/zone/quantities-panel.d.ts.map +1 -1
  557. package/dist/zone/quantities-panel.js +34 -9
  558. package/dist/zone/renderer.d.ts.map +1 -1
  559. package/dist/zone/renderer.js +9 -5
  560. package/package.json +14 -14
  561. package/dist/site/generic-foundation-geometry.d.ts +0 -16
  562. package/dist/site/generic-foundation-geometry.d.ts.map +0 -1
  563. package/dist/site/generic-foundation-geometry.js +0 -75
  564. package/dist/site/generic-foundation.d.ts +0 -4
  565. package/dist/site/generic-foundation.d.ts.map +0 -1
  566. package/dist/site/generic-foundation.js +0 -91
@@ -30,10 +30,6 @@ export function batchableKinds() {
30
30
  export function batchableConfig(node) {
31
31
  return node ? batchableKinds().get(node.type) : undefined;
32
32
  }
33
- /** A wall-scoped node (door, window) moves with its host wall. */
34
- export function isWallHosted(node) {
35
- return batchableConfig(node)?.scope === 'wall';
36
- }
37
33
  const rootInverse = new Matrix4();
38
34
  /** Source meshes currently draw-hidden per node, so reveal needs no candidate. */
39
35
  const hiddenMeshesByNode = new Map();
@@ -43,7 +39,9 @@ const hiddenMeshesByNode = new Map();
43
39
  * variant, a cutout group) — and at any HOSTED child node's registered group:
44
40
  * an item can host other items (a shelf's books), whose groups mount inside
45
41
  * the host's. Packing those would freeze the child at the host's join pose
46
- * with no release of its own (it is not a store member).
42
+ * with no release of its own (it is not a store member). A ceiling's cap draws
43
+ * itself: it shows and hides with a viewer flag that rebuilds nothing, so a
44
+ * batched copy would stay drawn after it hides.
47
45
  */
48
46
  function collectMeshes(object, out, hostedRoots) {
49
47
  if (object.visible === false || hostedRoots.has(object))
@@ -52,33 +50,80 @@ function collectMeshes(object, out, hostedRoots) {
52
50
  if (mesh.isMesh &&
53
51
  mesh.name !== 'cutout' &&
54
52
  mesh.name !== 'ceiling-grid' &&
53
+ mesh.name !== 'ceiling-cap' &&
55
54
  mesh.layers.isEnabled(SCENE_LAYER)) {
56
55
  out.push(mesh);
57
56
  }
58
57
  for (const child of object.children)
59
58
  collectMeshes(child, out, hostedRoots);
60
59
  }
60
+ /**
61
+ * The node's hosts between it and its level, nearest first, or null when the
62
+ * chain does not reach a level or a host is hidden — a hidden host hides its
63
+ * children through group visibility, while batch instances hang off the level
64
+ * root and would keep drawing them — or a host draws itself because it moves
65
+ * (an animating item, a door mid-swing): what it carries moves with it. A host's edits, gestures and tint release
66
+ * the nodes it carries ({@link hostsBusy}), so a batched copy never stays
67
+ * behind when the host moves.
68
+ */
69
+ export function hostChain(node, nodes) {
70
+ const hosts = [];
71
+ for (let id = node.parentId; id;) {
72
+ const host = nodes[id];
73
+ if (!host)
74
+ return null;
75
+ if (host.type === 'level')
76
+ return { levelId: host.id, hosts };
77
+ if (host.visible === false)
78
+ return null;
79
+ const batchable = batchableConfig(host);
80
+ if (batchable?.excluded?.(host))
81
+ return null;
82
+ if (batchable?.settled) {
83
+ const group = sceneRegistry.nodes.get(host.id);
84
+ if (!group || !batchable.settled(group.userData))
85
+ return null;
86
+ }
87
+ hosts.push(host);
88
+ id = host.parentId;
89
+ }
90
+ return null;
91
+ }
61
92
  /**
62
93
  * The level this node's batches live under, or null when the node is not in
63
- * batchable scope. Level-scoped kinds qualify directly under a level; doors
64
- * and windows through a wall that is itself parented to a level. Other
65
- * hosting shapes (roof faces, blocks, wall-hosted items) move when their host
66
- * changes without any signal the batch would see — they draw themselves.
94
+ * batchable scope. Level-scoped kinds qualify anywhere under a level; doors
95
+ * and windows through a wall that is itself parented to a level.
67
96
  */
68
97
  function resolveLevelId(node, batchable, nodes) {
69
- const parent = node.parentId ? nodes[node.parentId] : undefined;
70
- if (!parent)
98
+ const chain = hostChain(node, nodes);
99
+ if (!chain)
71
100
  return null;
72
- if (batchable.scope === 'level') {
73
- return parent.type === 'level' ? parent.id : null;
101
+ if (batchable.scope === 'level')
102
+ return chain.levelId;
103
+ return chain.hosts.length === 1 && chain.hosts[0].type === 'wall' ? chain.levelId : null;
104
+ }
105
+ /** Whether any host of `nodeId` (not the node itself) satisfies `busy`. */
106
+ export function hostsBusy(nodeId, nodes, busy) {
107
+ for (let id = nodes[nodeId]?.parentId; id; id = nodes[id]?.parentId) {
108
+ const host = nodes[id];
109
+ if (!host || host.type === 'level')
110
+ return false;
111
+ if (busy(id))
112
+ return true;
113
+ }
114
+ return false;
115
+ }
116
+ /** Adds every batchable node carried by `nodeId` (its descendants, at any depth) to `out`. */
117
+ export function addBatchableDescendants(nodeId, nodes, out) {
118
+ const children = nodes[nodeId]?.children;
119
+ if (!Array.isArray(children))
120
+ return;
121
+ for (const childId of children) {
122
+ const id = String(childId);
123
+ if (batchableConfig(nodes[id]))
124
+ out.add(id);
125
+ addBatchableDescendants(id, nodes, out);
74
126
  }
75
- // Wall-hosted: host wall → its level. A hidden wall hides its openings
76
- // through group visibility — batch instances hang off the level root and
77
- // would keep drawing them.
78
- if (parent.type !== 'wall' || parent.visible === false)
79
- return null;
80
- const level = parent.parentId ? nodes[parent.parentId] : undefined;
81
- return level?.type === 'level' ? level.id : null;
82
127
  }
83
128
  export function collectBatchCandidate(nodeId) {
84
129
  const nodes = useScene.getState().nodes;
@@ -102,7 +147,9 @@ export function collectBatchCandidate(nodeId) {
102
147
  const overrides = useLiveNodeOverrides.getState();
103
148
  if (overrides.get(nodeId) || useLiveTransforms.getState().get(nodeId))
104
149
  return null;
105
- if (batchable.scope === 'wall' && node.parentId && overrides.get(node.parentId)) {
150
+ const liveTransforms = useLiveTransforms.getState();
151
+ if (hostsBusy(nodeId, nodes, (hostId) => overrides.get(hostId) !== undefined ||
152
+ liveTransforms.get(hostId) !== undefined)) {
106
153
  return null;
107
154
  }
108
155
  const levelRoot = sceneRegistry.nodes.get(levelId);
@@ -188,46 +235,34 @@ export function revealBatchedNode(nodeId) {
188
235
  hiddenMeshesByNode.delete(nodeId);
189
236
  }
190
237
  /**
191
- * Nodes the viewer is lighting up — plus hosted openings whose host wall is
192
- * lit or mid-gesture: a dragged wall carries its doors with it through live
193
- * overrides, and a batched copy would stay behind until commit.
238
+ * Nodes the viewer is lighting up — plus nodes whose host is lit or
239
+ * mid-gesture: a dragged wall carries its doors, a moved cabinet run its
240
+ * modules, through live overrides and transforms, and a batched copy would
241
+ * stay behind until commit.
194
242
  */
195
243
  export function collectTintedNodes(nodeIds) {
196
244
  const viewer = useViewer.getState();
197
- const tinted = new Set();
245
+ const lit = new Set();
198
246
  for (const id of viewer.selection.selectedIds)
199
- if (nodeIds.has(id))
200
- tinted.add(id);
247
+ lit.add(id);
201
248
  for (const id of viewer.previewSelectedIds)
202
- if (nodeIds.has(id))
203
- tinted.add(id);
249
+ lit.add(id);
204
250
  for (const id of viewer.externalSelectedIds)
251
+ lit.add(id);
252
+ if (viewer.hoveredId)
253
+ lit.add(viewer.hoveredId);
254
+ const tinted = new Set();
255
+ for (const id of lit)
205
256
  if (nodeIds.has(id))
206
257
  tinted.add(id);
207
- const hovered = viewer.hoveredId;
208
- if (hovered && nodeIds.has(hovered))
209
- tinted.add(hovered);
210
258
  const nodes = useScene.getState().nodes;
211
259
  const overrides = useLiveNodeOverrides.getState();
212
- const wallLit = new Set();
213
- for (const id of viewer.selection.selectedIds)
214
- wallLit.add(id);
215
- for (const id of viewer.previewSelectedIds)
216
- wallLit.add(id);
217
- for (const id of viewer.externalSelectedIds)
218
- wallLit.add(id);
219
- if (hovered)
220
- wallLit.add(hovered);
260
+ const liveTransforms = useLiveTransforms.getState();
261
+ const busy = (hostId) => lit.has(hostId) ||
262
+ overrides.get(hostId) !== undefined ||
263
+ liveTransforms.get(hostId) !== undefined;
221
264
  for (const id of nodeIds) {
222
- if (tinted.has(id))
223
- continue;
224
- const node = nodes[id];
225
- if (!node || !isWallHosted(node))
226
- continue;
227
- const wallId = node.parentId;
228
- if (!wallId)
229
- continue;
230
- if (wallLit.has(wallId) || overrides.get(wallId))
265
+ if (!tinted.has(id) && hostsBusy(id, nodes, busy))
231
266
  tinted.add(id);
232
267
  }
233
268
  return tinted;
@@ -1 +1 @@
1
- {"version":3,"file":"system.d.ts","sourceRoot":"","sources":["../../../src/shared/node-batch/system.tsx"],"names":[],"mappings":"AA6HA,wBAAgB,mBAAmB,SAmBlC;AAkCD,wBAAgB,0BAA0B,CAAC,UAAU,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CA4B7E;AAED,wBAAgB,mBAAmB,SAgBlC;AAED,wBAAgB,aAAa,CAC3B,UAAU,EAAE,MAAM,IAAI,EACtB,OAAO,EAAE;IAAE,OAAO,EAAE,UAAU,CAAC,OAAO,UAAU,CAAC,GAAG,IAAI,CAAA;CAAE,QAmB3D;AAkQD,eAAO,MAAM,eAAe,0CAG3B,CAAA"}
1
+ {"version":3,"file":"system.d.ts","sourceRoot":"","sources":["../../../src/shared/node-batch/system.tsx"],"names":[],"mappings":"AAgIA,wBAAgB,mBAAmB,SAmBlC;AAkCD,wBAAgB,0BAA0B,CAAC,UAAU,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAmC7E;AAED,wBAAgB,mBAAmB,SAalC;AAED,wBAAgB,aAAa,CAC3B,UAAU,EAAE,MAAM,IAAI,EACtB,OAAO,EAAE;IAAE,OAAO,EAAE,UAAU,CAAC,OAAO,UAAU,CAAC,GAAG,IAAI,CAAA;CAAE,QAmB3D;AAwQD,eAAO,MAAM,eAAe,0CAG3B,CAAA"}
@@ -5,7 +5,7 @@ import { getPendingWallRebuildCount, isIsolationActive, isNodeRevealing, publish
5
5
  import { useFrame, useThree } from '@react-three/fiber';
6
6
  import { useEffect, useRef } from 'react';
7
7
  import { isSlotPaintPreviewActive, subscribeSlotPaintPreviews } from '../slot-paint.js';
8
- import { batchableConfig, collectBatchCandidate, collectTintedNodes, getBatchableNodeIds, hideBatchedNode, isWallHosted, revealAllBatchedHolds, revealBatchedNode, } from './candidates.js';
8
+ import { addBatchableDescendants, batchableConfig, collectBatchCandidate, collectTintedNodes, getBatchableNodeIds, hideBatchedNode, hostsBusy, revealAllBatchedHolds, revealBatchedNode, } from './candidates.js';
9
9
  import { subscribeBatchReleases } from './release.js';
10
10
  import { NodeBatchStore } from './store.js';
11
11
  import { MIN_BATCH_ENTRIES, NODE_BATCH_SETTLE_MS } from './types.js';
@@ -21,11 +21,13 @@ const store = new NodeBatchStore((levelId) => sceneRegistry.nodes.get(levelId));
21
21
  /**
22
22
  * Marks captured before the consuming systems (priority 2+) clear them — the
23
23
  * walls' `drainRebuiltWalls` ledger, done from the outside: a priority-1 pass
24
- * snapshots which nodes this frame touched. A dirty WALL cascades to its
25
- * hosted doors/windows: the wall edit moves them in level space without
26
- * marking them.
24
+ * snapshots which nodes this frame touched. A dirty host cascades to the
25
+ * batchable nodes it carries: a wall edit moves its doors and windows, a
26
+ * cabinet run edit its modules, in level space without marking them.
27
27
  */
28
28
  const changedNodes = new Set();
29
+ /** Scene containers: their children are organised under them, not carried by them. */
30
+ const CONTAINER_TYPES = new Set(['level', 'building', 'site']);
29
31
  const surfaceLevelReadyAt = new Map();
30
32
  const staleNodes = new Set();
31
33
  /**
@@ -131,11 +133,19 @@ function releaseAll() {
131
133
  revealAllBatchedHolds();
132
134
  }
133
135
  export function subscribeBatchInteractions(invalidate) {
136
+ // A gesture or release on a host moves what it carries too.
134
137
  const changed = (nodeId) => {
135
- if (!batchableConfig(useScene.getState().nodes[nodeId]))
138
+ const nodes = useScene.getState().nodes;
139
+ const ids = new Set();
140
+ if (batchableConfig(nodes[nodeId]))
141
+ ids.add(nodeId);
142
+ addBatchableDescendants(nodeId, nodes, ids);
143
+ if (ids.size === 0)
136
144
  return;
137
- releaseNode(nodeId);
138
- changedNodes.add(nodeId);
145
+ for (const id of ids) {
146
+ releaseNode(id);
147
+ changedNodes.add(id);
148
+ }
139
149
  invalidate();
140
150
  };
141
151
  const unsubscribeTransforms = useLiveTransforms.subscribe((state, previous) => {
@@ -174,14 +184,11 @@ export function captureChangedNodes() {
174
184
  continue;
175
185
  if (batchableConfig(node))
176
186
  changedNodes.add(id);
177
- else if (node.type === 'wall' && Array.isArray(node.children)) {
178
- // The wall edit moved its openings in level space; their own marks may
179
- // never come.
180
- for (const childId of node.children) {
181
- if (isWallHosted(nodes[childId]))
182
- changedNodes.add(childId);
183
- }
184
- }
187
+ // The host edit moved what it carries in level space; their own marks may never come. A
188
+ // level, building or site carries nothing that way: its child list is bookkeeping (it changes
189
+ // whenever furniture is re-parented), and cascading from it released the whole floor.
190
+ if (!CONTAINER_TYPES.has(node.type))
191
+ addBatchableDescendants(id, nodes, changedNodes);
185
192
  }
186
193
  }
187
194
  export function runBatchFrame(invalidate, wakeRef) {
@@ -393,6 +400,8 @@ function processBatchFrame(invalidate, wakeRef) {
393
400
  dirty.has(nodeId) ||
394
401
  // Still growing in from a construction reveal: its transform moves every frame.
395
402
  isNodeRevealing(nodeId) ||
403
+ // A host still being rebuilt or revealed moves this node with it.
404
+ hostsBusy(nodeId, sceneNodes, (hostId) => dirty.has(hostId) || isNodeRevealing(hostId)) ||
396
405
  overrides.get(nodeId) !== undefined ||
397
406
  useLiveTransforms.getState().get(nodeId) !== undefined ||
398
407
  isSlotPaintPreviewActive(nodeId)) {
@@ -0,0 +1,16 @@
1
+ import { type AnyNode, type DoorNode, type WindowNode } from '@pascal-app/core';
2
+ type MovedOpening = Pick<DoorNode | WindowNode, 'parentId' | 'roofSegmentId' | 'rotation' | 'casingFaceA' | 'casingFaceB'>;
3
+ type CasingFaces = Pick<DoorNode | WindowNode, 'casingFaceA' | 'casingFaceB'>;
4
+ /**
5
+ * The casing faces a door or window keeps when a move takes it from its host to `hostId`, the
6
+ * wall or roof face it lands on turned to `rotation`. Casing is kept per host face, and two hosts
7
+ * need not name their faces alike: a wall drawn the other way round has its `a` where the first
8
+ * has its `b`. So each face's casing goes to the matching face of the new host: outside to
9
+ * outside where both hosts know their outside (an outside wall, as its rooms give it, or a roof
10
+ * face), else the face the unit's front looks at to the face it looks at there. A slide along its
11
+ * own host, or a host with no cased faces on either end (a dormer, open floor), keeps them as they
12
+ * are.
13
+ */
14
+ export declare function movedOpeningCasingFaces(opening: MovedOpening, hostId: string, rotation: DoorNode['rotation'], nodes: Readonly<Record<string, AnyNode>>): CasingFaces;
15
+ export {};
16
+ //# sourceMappingURL=opening-casing-move.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"opening-casing-move.d.ts","sourceRoot":"","sources":["../../src/shared/opening-casing-move.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,OAAO,EACZ,KAAK,QAAQ,EAGb,KAAK,UAAU,EAChB,MAAM,kBAAkB,CAAA;AAEzB,KAAK,YAAY,GAAG,IAAI,CACtB,QAAQ,GAAG,UAAU,EACrB,UAAU,GAAG,eAAe,GAAG,UAAU,GAAG,aAAa,GAAG,aAAa,CAC1E,CAAA;AACD,KAAK,WAAW,GAAG,IAAI,CAAC,QAAQ,GAAG,UAAU,EAAE,aAAa,GAAG,aAAa,CAAC,CAAA;AAS7E;;;;;;;;;GASG;AACH,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,YAAY,EACrB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,QAAQ,CAAC,UAAU,CAAC,EAC9B,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GACvC,WAAW,CAab"}
@@ -0,0 +1,33 @@
1
+ import { openingHostFacing, resolveWallExteriorSide, } from '@pascal-app/core';
2
+ /** The face of a host that looks outdoors: +1 for `a`, -1 for `b`, null when it cannot tell. */
3
+ function hostOutside(host) {
4
+ if (host.type === 'wall')
5
+ return resolveWallExteriorSide(host);
6
+ // A roof face's `a` is its outside, as its casing has it.
7
+ return host.type === 'roof-segment' ? 1 : null;
8
+ }
9
+ /**
10
+ * The casing faces a door or window keeps when a move takes it from its host to `hostId`, the
11
+ * wall or roof face it lands on turned to `rotation`. Casing is kept per host face, and two hosts
12
+ * need not name their faces alike: a wall drawn the other way round has its `a` where the first
13
+ * has its `b`. So each face's casing goes to the matching face of the new host: outside to
14
+ * outside where both hosts know their outside (an outside wall, as its rooms give it, or a roof
15
+ * face), else the face the unit's front looks at to the face it looks at there. A slide along its
16
+ * own host, or a host with no cased faces on either end (a dormer, open floor), keeps them as they
17
+ * are.
18
+ */
19
+ export function movedOpeningCasingFaces(opening, hostId, rotation, nodes) {
20
+ const kept = { casingFaceA: opening.casingFaceA, casingFaceB: opening.casingFaceB };
21
+ const fromId = opening.roofSegmentId ?? opening.parentId;
22
+ const [from, to] = [nodes[fromId ?? ''], nodes[hostId]];
23
+ if (fromId === hostId || !from || !to)
24
+ return kept;
25
+ const cased = (host) => host.type === 'wall' || host.type === 'roof-segment';
26
+ if (!(cased(from) && cased(to)))
27
+ return kept;
28
+ const [fromOutside, toOutside] = [hostOutside(from), hostOutside(to)];
29
+ const swapped = fromOutside !== null && toOutside !== null
30
+ ? fromOutside !== toOutside
31
+ : openingHostFacing(opening) !== openingHostFacing({ rotation });
32
+ return swapped ? { casingFaceA: kept.casingFaceB, casingFaceB: kept.casingFaceA } : kept;
33
+ }
@@ -0,0 +1,15 @@
1
+ import { type DoorNode, type WindowNode } from '@pascal-app/core';
2
+ type CasingPatch = Partial<Pick<DoorNode, 'casingFaceA' | 'casingFaceB' | 'casingWidth'>>;
3
+ /**
4
+ * The door and window panels' Casing section: casing on or off for each face
5
+ * of the host wall (Exterior and Interior on an outside wall), and the boards'
6
+ * face width, in inches on an imperial plan (feet would show 2 in as 0.17).
7
+ * Nothing where the opening takes no casing (a curtain wall, a dormer face, a
8
+ * unit built from a script).
9
+ */
10
+ export declare function OpeningCasingSection({ node, onUpdate, }: {
11
+ node: DoorNode | WindowNode;
12
+ onUpdate: (patch: CasingPatch) => void;
13
+ }): import("react").JSX.Element | null;
14
+ export {};
15
+ //# sourceMappingURL=opening-casing-section.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"opening-casing-section.d.ts","sourceRoot":"","sources":["../../src/shared/opening-casing-section.tsx"],"names":[],"mappings":"AAEA,OAAO,EACL,KAAK,QAAQ,EAKb,KAAK,UAAU,EAChB,MAAM,kBAAkB,CAAA;AAUzB,KAAK,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,aAAa,GAAG,aAAa,GAAG,aAAa,CAAC,CAAC,CAAA;AAEzF;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,EACnC,IAAI,EACJ,QAAQ,GACT,EAAE;IACD,IAAI,EAAE,QAAQ,GAAG,UAAU,CAAA;IAC3B,QAAQ,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAA;CACvC,sCAkDA"}
@@ -0,0 +1,38 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { openingCasingWidth, resolveOpeningCasingHost, usePascalI18n, useScene, } from '@pascal-app/core';
4
+ import { PanelSection, SliderControl, ToggleControl } from '@pascal-app/editor';
5
+ import { useViewer } from '@pascal-app/viewer';
6
+ import { useMemo } from 'react';
7
+ import { openingCasingFaceLabels } from './opening-casing.js';
8
+ const INCH = 0.0254;
9
+ const MIN_CASING_WIDTH = 0.5 * INCH;
10
+ const MAX_CASING_WIDTH = 8 * INCH;
11
+ /**
12
+ * The door and window panels' Casing section: casing on or off for each face
13
+ * of the host wall (Exterior and Interior on an outside wall), and the boards'
14
+ * face width, in inches on an imperial plan (feet would show 2 in as 0.17).
15
+ * Nothing where the opening takes no casing (a curtain wall, a dormer face, a
16
+ * unit built from a script).
17
+ */
18
+ export function OpeningCasingSection({ node, onUpdate, }) {
19
+ const i18n = usePascalI18n();
20
+ // Its own component, so the whole scene it reads for the face names
21
+ // re-renders this section alone, not the panel around it.
22
+ const nodes = useScene((state) => state.nodes);
23
+ const cased = useMemo(() => resolveOpeningCasingHost(node, nodes) !== null, [node, nodes]);
24
+ const { parentId, roofSegmentId } = node;
25
+ const labels = useMemo(() => openingCasingFaceLabels(nodes, { parentId, roofSegmentId }), [nodes, parentId, roofSegmentId]);
26
+ const imperial = useViewer((state) => state.unit) === 'imperial';
27
+ if (!cased)
28
+ return null;
29
+ const faceA = node.casingFaceA === true;
30
+ const faceB = node.casingFaceB === true;
31
+ const toShown = (meters) => (imperial ? meters / INCH : meters);
32
+ return (_jsxs(PanelSection, { title: i18n._({ id: 'node.shared.openingCasingSection.casing', message: 'Casing' }), children: [_jsx(ToggleControl, { checked: faceA, label: labels.a, onChange: (checked) => onUpdate({ casingFaceA: checked }) }), _jsx(ToggleControl, { checked: faceB, label: labels.b, onChange: (checked) => onUpdate({ casingFaceB: checked }) }), (faceA || faceB) && (_jsx(SliderControl, { label: i18n._({ id: 'node.shared.openingCasingSection.width', message: 'Width' }), max: toShown(MAX_CASING_WIDTH), min: toShown(MIN_CASING_WIDTH), onChange: (value) => {
33
+ const meters = imperial ? value * INCH : value;
34
+ onUpdate({
35
+ casingWidth: Math.min(Math.max(meters, MIN_CASING_WIDTH), MAX_CASING_WIDTH),
36
+ });
37
+ }, precision: imperial ? 2 : 3, step: imperial ? 0.25 : 0.005, unit: imperial ? 'in' : 'm', value: toShown(openingCasingWidth(node)) }))] }));
38
+ }
@@ -0,0 +1,26 @@
1
+ import { type AnyNode, type DoorNode, type FloorplanGeometry, type OpeningCasingHost, type WallFace, type WallNode, type WindowNode } from '@pascal-app/core';
2
+ type CasingPlanStyle = {
3
+ fill: string;
4
+ stroke: string;
5
+ strokeWidth: number;
6
+ /** Screen-pixel strokes in the editor; plan-metre ink on a drafted sheet. */
7
+ vectorEffect?: 'non-scaling-stroke';
8
+ };
9
+ /**
10
+ * The casing a door's or window's plan shows: the legs beside the cutout on
11
+ * each face of the wall it is cased on, each a short rectangle standing proud
12
+ * of the finished face, as plans draw trim. Null when there is none to draw (a
13
+ * curtain wall, a railing, a script-built unit, both faces turned off).
14
+ * `cornerEnd` is the wall end a corner window runs to, where it has no leg.
15
+ */
16
+ export declare function buildOpeningCasingPlan(opening: DoorNode | WindowNode, wall: WallNode, style: CasingPlanStyle, cornerEnd?: OpeningCasingHost['cornerEnd']): FloorplanGeometry | null;
17
+ /**
18
+ * What the door and window panels call the faces an opening can be cased on. A
19
+ * wall with rooms on one side only (an outside wall, as the wall panel's paint
20
+ * regions tell it) names them Exterior and Interior, as does a roof face, whose
21
+ * `a` is its outside; any other wall keeps the wall panel's Side A and Side B.
22
+ */
23
+ export declare function openingCasingFaceLabels(nodes: Readonly<Record<string, AnyNode>>, opening: Pick<DoorNode | WindowNode, 'parentId' | 'roofSegmentId'>): Record<WallFace, string>;
24
+ export declare function openingCasingPaintLabel(role: string): string | null;
25
+ export {};
26
+ //# sourceMappingURL=opening-casing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"opening-casing.d.ts","sourceRoot":"","sources":["../../src/shared/opening-casing.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,OAAO,EACZ,KAAK,QAAQ,EAEb,KAAK,iBAAiB,EAGtB,KAAK,iBAAiB,EAGtB,KAAK,QAAQ,EACb,KAAK,QAAQ,EACb,KAAK,UAAU,EAChB,MAAM,kBAAkB,CAAA;AAEzB,KAAK,eAAe,GAAG;IACrB,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;IACd,WAAW,EAAE,MAAM,CAAA;IACnB,6EAA6E;IAC7E,YAAY,CAAC,EAAE,oBAAoB,CAAA;CACpC,CAAA;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,QAAQ,GAAG,UAAU,EAC9B,IAAI,EAAE,QAAQ,EACd,KAAK,EAAE,eAAe,EACtB,SAAS,CAAC,EAAE,iBAAiB,CAAC,WAAW,CAAC,GACzC,iBAAiB,GAAG,IAAI,CAuC1B;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EACxC,OAAO,EAAE,IAAI,CAAC,QAAQ,GAAG,UAAU,EAAE,UAAU,GAAG,eAAe,CAAC,GACjE,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,CAiB1B;AAED,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAMnE"}
@@ -0,0 +1,80 @@
1
+ import { defaultI18n, getWallBodyCenterOffset, openingCasingBoards, roomSideFaces, } from '@pascal-app/core';
2
+ /**
3
+ * The casing a door's or window's plan shows: the legs beside the cutout on
4
+ * each face of the wall it is cased on, each a short rectangle standing proud
5
+ * of the finished face, as plans draw trim. Null when there is none to draw (a
6
+ * curtain wall, a railing, a script-built unit, both faces turned off).
7
+ * `cornerEnd` is the wall end a corner window runs to, where it has no leg.
8
+ */
9
+ export function buildOpeningCasingPlan(opening, wall, style, cornerEnd) {
10
+ if (opening.source || wall.wallType === 'curtain' || wall.wallType === 'railing')
11
+ return null;
12
+ const [x1, z1] = wall.start;
13
+ const dx = wall.end[0] - x1;
14
+ const dz = wall.end[1] - z1;
15
+ const length = Math.hypot(dx, dz);
16
+ if (length < 1e-9)
17
+ return null;
18
+ const dir = [dx / length, dz / length];
19
+ const perp = [-dir[1], dir[0]];
20
+ const plan = (along, across) => [
21
+ x1 + dir[0] * along + perp[0] * across,
22
+ z1 + dir[1] * along + perp[1] * across,
23
+ ];
24
+ // Boards are measured from the opening's centre plane, which a justified wall
25
+ // sets off its reference line and a plane offset sets off the wall's body.
26
+ const centreAcross = getWallBodyCenterOffset(wall) + (opening.position[2] ?? 0);
27
+ const host = {
28
+ thickness: wall.thickness ?? 0.1,
29
+ ...(cornerEnd ? { cornerEnd } : {}),
30
+ };
31
+ const children = openingCasingBoards(opening, host)
32
+ .filter((board) => board.part === 'leg')
33
+ .map(({ center, size }) => {
34
+ const along = opening.position[0] + center[0];
35
+ const across = centreAcross + center[2];
36
+ const [halfAlong, halfAcross] = [size[0] / 2, size[2] / 2];
37
+ return {
38
+ kind: 'polygon',
39
+ points: [
40
+ plan(along - halfAlong, across + halfAcross),
41
+ plan(along + halfAlong, across + halfAcross),
42
+ plan(along + halfAlong, across - halfAcross),
43
+ plan(along - halfAlong, across - halfAcross),
44
+ ],
45
+ ...style,
46
+ strokeLinejoin: 'miter',
47
+ };
48
+ });
49
+ return children.length ? { kind: 'group', children } : null;
50
+ }
51
+ /**
52
+ * What the door and window panels call the faces an opening can be cased on. A
53
+ * wall with rooms on one side only (an outside wall, as the wall panel's paint
54
+ * regions tell it) names them Exterior and Interior, as does a roof face, whose
55
+ * `a` is its outside; any other wall keeps the wall panel's Side A and Side B.
56
+ */
57
+ export function openingCasingFaceLabels(nodes, opening) {
58
+ if (opening.roofSegmentId)
59
+ return { a: 'Exterior', b: 'Interior' };
60
+ const wallId = opening.parentId;
61
+ if (wallId && nodes[wallId]?.type === 'wall') {
62
+ try {
63
+ const { inside, outside } = roomSideFaces(nodes, wallId);
64
+ if (inside && outside) {
65
+ return { [outside]: 'Exterior', [inside]: 'Interior' };
66
+ }
67
+ }
68
+ catch {
69
+ // Not a wall (any more): fall through to the neutral labels.
70
+ }
71
+ }
72
+ return { a: 'Side A', b: 'Side B' };
73
+ }
74
+ export function openingCasingPaintLabel(role) {
75
+ if (role === 'casing-a')
76
+ return defaultI18n._({ id: 'node.shared.openingCasing.faceA', message: 'Casing A' });
77
+ if (role === 'casing-b')
78
+ return defaultI18n._({ id: 'node.shared.openingCasing.faceB', message: 'Casing B' });
79
+ return null;
80
+ }
@@ -0,0 +1,13 @@
1
+ import { type DoorNode, type WindowNode } from '@pascal-app/core';
2
+ /**
3
+ * The Frame section's Depth position: where the frame stands across its wall,
4
+ * the opening's `position[2]` (0 = the wall's centre plane), within half the
5
+ * wall's thickness either way. In inches on an imperial plan, like the casing
6
+ * width (feet would show 2 in as 0.17). Nothing where the opening stands in no
7
+ * wall: a roof face, a curtain wall or railing, a unit built from a script.
8
+ */
9
+ export declare function OpeningDepthPositionControl({ node, onUpdate, }: {
10
+ node: DoorNode | WindowNode;
11
+ onUpdate: (patch: Pick<DoorNode, 'position'>) => void;
12
+ }): import("react").JSX.Element | null;
13
+ //# sourceMappingURL=opening-depth-position.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"opening-depth-position.d.ts","sourceRoot":"","sources":["../../src/shared/opening-depth-position.tsx"],"names":[],"mappings":"AAEA,OAAO,EACL,KAAK,QAAQ,EAIb,KAAK,UAAU,EAChB,MAAM,kBAAkB,CAAA;AAMzB;;;;;;GAMG;AACH,wBAAgB,2BAA2B,CAAC,EAC1C,IAAI,EACJ,QAAQ,GACT,EAAE;IACD,IAAI,EAAE,QAAQ,GAAG,UAAU,CAAA;IAC3B,QAAQ,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,QAAQ,EAAE,UAAU,CAAC,KAAK,IAAI,CAAA;CACtD,sCAkCA"}
@@ -0,0 +1,34 @@
1
+ 'use client';
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { resolveOpeningCasingHost, usePascalI18n, useScene, } from '@pascal-app/core';
4
+ import { SliderControl } from '@pascal-app/editor';
5
+ import { useViewer } from '@pascal-app/viewer';
6
+ const INCH = 0.0254;
7
+ /**
8
+ * The Frame section's Depth position: where the frame stands across its wall,
9
+ * the opening's `position[2]` (0 = the wall's centre plane), within half the
10
+ * wall's thickness either way. In inches on an imperial plan, like the casing
11
+ * width (feet would show 2 in as 0.17). Nothing where the opening stands in no
12
+ * wall: a roof face, a curtain wall or railing, a unit built from a script.
13
+ */
14
+ export function OpeningDepthPositionControl({ node, onUpdate, }) {
15
+ const i18n = usePascalI18n();
16
+ // A number, so only a change to the host wall's thickness re-renders the panel.
17
+ const thickness = useScene((state) => node.roofSegmentId ? null : (resolveOpeningCasingHost(node, state.nodes)?.thickness ?? null));
18
+ const imperial = useViewer((state) => state.unit) === 'imperial';
19
+ if (thickness === null)
20
+ return null;
21
+ const offset = node.position[2] ?? 0;
22
+ // An opening already set further out (a photo-profiled slider) keeps its value in range.
23
+ const half = Math.max(thickness / 2, Math.abs(offset));
24
+ const toShown = (meters) => (imperial ? meters / INCH : meters);
25
+ return (_jsx(SliderControl, { label: i18n._({
26
+ id: 'node.shared.openingDepthPosition.depthPosition',
27
+ message: 'Depth position',
28
+ }), max: toShown(half), min: toShown(-half), onChange: (value) => {
29
+ const meters = imperial ? value * INCH : value;
30
+ onUpdate({
31
+ position: [node.position[0], node.position[1], Math.min(Math.max(meters, -half), half)],
32
+ });
33
+ }, precision: imperial ? 2 : 3, step: imperial ? 0.25 : 0.005, unit: imperial ? 'in' : 'm', value: toShown(offset) }));
34
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"opening-documentation.d.ts","sourceRoot":"","sources":["../../src/shared/opening-documentation.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"opening-documentation.d.ts","sourceRoot":"","sources":["../../src/shared/opening-documentation.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { getOpeningFloorDatum, getWallLocalFaceZ, wallSupportForNodes } from '@pascal-app/core';
1
+ import { doorHandleStyle, getDoorOpeningSize, getOpeningFloorDatum, getWallLocalFaceZ, resolveHostedOpeningFrameDepth, wallSupportForNodes, } from '@pascal-app/core';
2
2
  import { resolveMarkDetail, withFloorplanGeometryMetadata, } from '@pascal-app/editor';
3
3
  import { formatConstructionLength, } from './construction-length.js';
4
4
  function openingLevelData(openings, nodes, kind) {
@@ -38,10 +38,10 @@ export function buildDoorFloorplanSchedule(args) {
38
38
  cells: {
39
39
  mark: marks.markById.get(door.id) ?? '—',
40
40
  type: door.openingKind === 'opening' ? 'Opening' : titleCase(door.doorType),
41
- size: formatSize(door.width, door.height, args.unit, args.profile ?? 'document'),
41
+ size: formatSize(getDoorOpeningSize(door).width, getDoorOpeningSize(door).height, args.unit, args.profile ?? 'document'),
42
42
  roughOpening: formatRoughOpening(door, args.unit, args.profile ?? 'document'),
43
43
  operation: doorOperation(door),
44
- frame: `${formatConstructionLength(door.frameThickness, args.unit, args.profile ?? 'document')} / ${formatConstructionLength(door.frameDepth, args.unit, args.profile ?? 'document')}`,
44
+ frame: `${formatConstructionLength(door.frameThickness, args.unit, args.profile ?? 'document')} / ${formatConstructionLength(resolveHostedOpeningFrameDepth(door, args.nodes), args.unit, args.profile ?? 'document')}`,
45
45
  hardware: doorHardware(door),
46
46
  },
47
47
  })),
@@ -405,7 +405,7 @@ function formatRoughOpening(opening, unit, profile) {
405
405
  function openingDocumentationDimensions(opening, reference) {
406
406
  switch (reference) {
407
407
  case 'nominal':
408
- return { width: opening.width, height: opening.height };
408
+ return getDoorOpeningSize(opening);
409
409
  case 'rough-opening':
410
410
  return {
411
411
  width: opening.roughOpeningWidth ?? null,
@@ -449,12 +449,21 @@ function doorHardware(door) {
449
449
  if (door.openingKind === 'opening')
450
450
  return 'None';
451
451
  const hardware = [];
452
+ if (door.handle) {
453
+ const swing = ['hinged', 'double', 'french'].includes(door.doorType);
454
+ const labels = {
455
+ lever: 'Lever',
456
+ 'lever-curved': 'Curved lever',
457
+ knob: 'Knob',
458
+ bar: 'Bar pull',
459
+ plate: 'Plate lever',
460
+ };
461
+ hardware.push(swing ? labels[doorHandleStyle(door)] : 'Pull');
462
+ }
452
463
  if (door.doorCloser)
453
- hardware.push('Closer');
464
+ hardware.push(hardware.length ? 'closer' : 'Closer');
454
465
  if (door.panicBar)
455
- hardware.push('Panic bar');
456
- if (door.threshold)
457
- hardware.push('Threshold');
466
+ hardware.push(hardware.length ? 'panic bar' : 'Panic bar');
458
467
  return hardware.length > 0 ? hardware.join(', ') : 'Standard';
459
468
  }
460
469
  function windowOperation(window) {
@@ -1,3 +1,4 @@
1
+ import { type DoorNode } from '@pascal-app/core';
1
2
  import { type AnyNode, type OpeningSpan, type WallNode } from '@pascal-app/core';
2
3
  /** Maps a wall-local point (s along the wall, y above the wall base) to the move
3
4
  * tool's render frame — the caller passes its own `wallLocalToWorld` closure so
@@ -65,6 +66,6 @@ export declare function publishOpeningResizeGuides(node: {
65
66
  position: readonly [number, number, number];
66
67
  width: number;
67
68
  height: number;
68
- }, includeVertical: boolean): void;
69
+ } & Partial<Pick<DoorNode, 'rotation' | 'doorType' | 'sidelightLeft' | 'sidelightRight' | 'transomHeight'>>, includeVertical: boolean): void;
69
70
  export {};
70
71
  //# sourceMappingURL=opening-guides-runtime.d.ts.map