@pascal-app/nodes 1.0.7 → 1.1.1

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 (965) hide show
  1. package/README.md +43 -8
  2. package/dist/agent-operations/index.d.ts +5 -0
  3. package/dist/agent-operations/index.d.ts.map +1 -1
  4. package/dist/agent-operations/index.js +10 -0
  5. package/dist/agent-tools/index.d.ts +195 -0
  6. package/dist/agent-tools/index.d.ts.map +1 -1
  7. package/dist/agent-tools/index.js +82 -2
  8. package/dist/beam/definition.d.ts +64 -13
  9. package/dist/beam/definition.d.ts.map +1 -1
  10. package/dist/beam/definition.edit.d.ts +4 -0
  11. package/dist/beam/definition.edit.d.ts.map +1 -0
  12. package/dist/beam/definition.edit.js +131 -0
  13. package/dist/beam/definition.js +4 -173
  14. package/dist/beam/definition.render.d.ts +6 -0
  15. package/dist/beam/definition.render.d.ts.map +1 -0
  16. package/dist/beam/definition.render.js +34 -0
  17. package/dist/beam/floorplan.d.ts.map +1 -1
  18. package/dist/beam/floorplan.js +1 -2
  19. package/dist/beam/panel.d.ts.map +1 -1
  20. package/dist/beam/panel.js +2 -2
  21. package/dist/beam/tool.d.ts.map +1 -1
  22. package/dist/beam/tool.js +2 -2
  23. package/dist/block/definition.d.ts +67 -7
  24. package/dist/block/definition.d.ts.map +1 -1
  25. package/dist/block/definition.edit.d.ts +4 -0
  26. package/dist/block/definition.edit.d.ts.map +1 -0
  27. package/dist/block/definition.edit.js +26 -0
  28. package/dist/block/definition.js +5 -144
  29. package/dist/block/definition.render.d.ts +11 -0
  30. package/dist/block/definition.render.d.ts.map +1 -0
  31. package/dist/block/definition.render.js +122 -0
  32. package/dist/block/floorplan.d.ts.map +1 -1
  33. package/dist/block/floorplan.js +1 -2
  34. package/dist/box-vent/definition.d.ts +103 -29
  35. package/dist/box-vent/definition.d.ts.map +1 -1
  36. package/dist/box-vent/definition.edit.d.ts +4 -0
  37. package/dist/box-vent/definition.edit.d.ts.map +1 -0
  38. package/dist/box-vent/definition.edit.js +149 -0
  39. package/dist/box-vent/definition.js +4 -212
  40. package/dist/box-vent/definition.render.d.ts +6 -0
  41. package/dist/box-vent/definition.render.d.ts.map +1 -0
  42. package/dist/box-vent/definition.render.js +42 -0
  43. package/dist/box-vent/move-tool.d.ts.map +1 -1
  44. package/dist/box-vent/move-tool.js +6 -5
  45. package/dist/building/definition.d.ts +49 -11
  46. package/dist/building/definition.d.ts.map +1 -1
  47. package/dist/building/definition.edit.d.ts +4 -0
  48. package/dist/building/definition.edit.d.ts.map +1 -0
  49. package/dist/building/definition.edit.js +10 -0
  50. package/dist/building/definition.js +4 -54
  51. package/dist/building/definition.render.d.ts +6 -0
  52. package/dist/building/definition.render.d.ts.map +1 -0
  53. package/dist/building/definition.render.js +38 -0
  54. package/dist/builtin-definitions.d.ts +9784 -0
  55. package/dist/builtin-definitions.d.ts.map +1 -0
  56. package/dist/builtin-definitions.js +113 -0
  57. package/dist/builtin-edit-contributions.d.ts +9608 -0
  58. package/dist/builtin-edit-contributions.d.ts.map +1 -0
  59. package/dist/builtin-edit-contributions.js +112 -0
  60. package/dist/builtin-plugin-metadata.d.ts +5 -0
  61. package/dist/builtin-plugin-metadata.d.ts.map +1 -0
  62. package/dist/builtin-plugin-metadata.js +1 -0
  63. package/dist/cabinet/definition.d.ts +497 -25
  64. package/dist/cabinet/definition.d.ts.map +1 -1
  65. package/dist/cabinet/definition.edit.d.ts +5 -0
  66. package/dist/cabinet/definition.edit.d.ts.map +1 -0
  67. package/dist/cabinet/definition.edit.js +1372 -0
  68. package/dist/cabinet/definition.js +6 -2115
  69. package/dist/cabinet/definition.render.d.ts +66 -0
  70. package/dist/cabinet/definition.render.d.ts.map +1 -0
  71. package/dist/cabinet/definition.render.js +754 -0
  72. package/dist/cabinet/floorplan.js +1 -1
  73. package/dist/cabinet/kitchen-module-actions.d.ts.map +1 -1
  74. package/dist/cabinet/kitchen-module-actions.js +2 -2
  75. package/dist/cabinet/placement-dimensions.d.ts +36 -2
  76. package/dist/cabinet/placement-dimensions.d.ts.map +1 -1
  77. package/dist/cabinet/placement-dimensions.js +68 -2
  78. package/dist/cabinet/system.js +1 -1
  79. package/dist/cabinet/tool.d.ts.map +1 -1
  80. package/dist/cabinet/tool.js +268 -15
  81. package/dist/cabinet/wall-snap.d.ts +5 -1
  82. package/dist/cabinet/wall-snap.d.ts.map +1 -1
  83. package/dist/cabinet/wall-snap.js +2 -2
  84. package/dist/ceiling/definition.d.ts +152 -19
  85. package/dist/ceiling/definition.d.ts.map +1 -1
  86. package/dist/ceiling/definition.edit.d.ts +4 -0
  87. package/dist/ceiling/definition.edit.d.ts.map +1 -0
  88. package/dist/ceiling/definition.edit.js +123 -0
  89. package/dist/ceiling/definition.js +4 -207
  90. package/dist/ceiling/definition.render.d.ts +6 -0
  91. package/dist/ceiling/definition.render.d.ts.map +1 -0
  92. package/dist/ceiling/definition.render.js +73 -0
  93. package/dist/ceiling/panel.js +2 -2
  94. package/dist/chimney/definition.d.ts +186 -17
  95. package/dist/chimney/definition.d.ts.map +1 -1
  96. package/dist/chimney/definition.edit.d.ts +4 -0
  97. package/dist/chimney/definition.edit.d.ts.map +1 -0
  98. package/dist/chimney/definition.edit.js +217 -0
  99. package/dist/chimney/definition.js +4 -390
  100. package/dist/chimney/definition.render.d.ts +6 -0
  101. package/dist/chimney/definition.render.d.ts.map +1 -0
  102. package/dist/chimney/definition.render.js +61 -0
  103. package/dist/chimney/move-tool.d.ts.map +1 -1
  104. package/dist/chimney/move-tool.js +6 -4
  105. package/dist/chimney/panel.js +1 -1
  106. package/dist/column/__bench__/geometry.d.ts +2 -0
  107. package/dist/column/__bench__/geometry.d.ts.map +1 -0
  108. package/dist/column/__bench__/geometry.js +36 -0
  109. package/dist/column/bounds.d.ts +7 -0
  110. package/dist/column/bounds.d.ts.map +1 -0
  111. package/dist/column/bounds.js +127 -0
  112. package/dist/column/definition.d.ts +372 -20
  113. package/dist/column/definition.d.ts.map +1 -1
  114. package/dist/column/definition.edit.d.ts +4 -0
  115. package/dist/column/definition.edit.d.ts.map +1 -0
  116. package/dist/column/definition.edit.js +320 -0
  117. package/dist/column/definition.js +4 -439
  118. package/dist/column/definition.render.d.ts +6 -0
  119. package/dist/column/definition.render.d.ts.map +1 -0
  120. package/dist/column/definition.render.js +84 -0
  121. package/dist/column/edit-policy.d.ts +5 -0
  122. package/dist/column/edit-policy.d.ts.map +1 -0
  123. package/dist/column/edit-policy.js +43 -0
  124. package/dist/column/floorplan-affordances.d.ts.map +1 -1
  125. package/dist/column/floorplan-affordances.js +2 -0
  126. package/dist/column/floorplan-move.d.ts.map +1 -1
  127. package/dist/column/floorplan-move.js +5 -1
  128. package/dist/column/floorplan.d.ts.map +1 -1
  129. package/dist/column/floorplan.js +34 -93
  130. package/dist/column/geometry.d.ts +13 -0
  131. package/dist/column/geometry.d.ts.map +1 -0
  132. package/dist/column/geometry.js +294 -0
  133. package/dist/column/hosted-resize.d.ts +3 -2
  134. package/dist/column/hosted-resize.d.ts.map +1 -1
  135. package/dist/column/hosted-resize.js +7 -1
  136. package/dist/column/inspector-highlight.d.ts +29 -0
  137. package/dist/column/inspector-highlight.d.ts.map +1 -0
  138. package/dist/column/inspector-highlight.js +166 -0
  139. package/dist/column/paint.d.ts.map +1 -1
  140. package/dist/column/paint.js +12 -2
  141. package/dist/column/panel.d.ts.map +1 -1
  142. package/dist/column/panel.js +451 -363
  143. package/dist/column/parametrics.js +1 -1
  144. package/dist/column/post-section.d.ts.map +1 -1
  145. package/dist/column/post-section.js +2 -2
  146. package/dist/column/preset-gallery.d.ts +8 -0
  147. package/dist/column/preset-gallery.d.ts.map +1 -0
  148. package/dist/column/preset-gallery.js +98 -0
  149. package/dist/column/presets.d.ts +16 -0
  150. package/dist/column/presets.d.ts.map +1 -0
  151. package/dist/column/presets.js +96 -0
  152. package/dist/column/property-preview.d.ts +8 -0
  153. package/dist/column/property-preview.d.ts.map +1 -0
  154. package/dist/column/property-preview.js +50 -0
  155. package/dist/column/renderer.d.ts +13 -1
  156. package/dist/column/renderer.d.ts.map +1 -1
  157. package/dist/column/renderer.js +174 -198
  158. package/dist/column/shape.d.ts +4 -4
  159. package/dist/column/shape.d.ts.map +1 -1
  160. package/dist/column/shape.js +1 -1
  161. package/dist/column/surface.d.ts.map +1 -1
  162. package/dist/column/surface.js +15 -8
  163. package/dist/column/tool.d.ts.map +1 -1
  164. package/dist/column/tool.js +21 -10
  165. package/dist/construction-dimension/definition.d.ts +129 -3
  166. package/dist/construction-dimension/definition.d.ts.map +1 -1
  167. package/dist/construction-dimension/definition.edit.d.ts +4 -0
  168. package/dist/construction-dimension/definition.edit.d.ts.map +1 -0
  169. package/dist/construction-dimension/definition.edit.js +30 -0
  170. package/dist/construction-dimension/definition.js +4 -83
  171. package/dist/construction-dimension/definition.render.d.ts +6 -0
  172. package/dist/construction-dimension/definition.render.d.ts.map +1 -0
  173. package/dist/construction-dimension/definition.render.js +55 -0
  174. package/dist/construction-dimension/floorplan-tool.d.ts.map +1 -1
  175. package/dist/construction-dimension/floorplan-tool.js +2 -2
  176. package/dist/construction-dimension/floorplan.d.ts.map +1 -1
  177. package/dist/construction-dimension/floorplan.js +1 -2
  178. package/dist/cupola/definition.d.ts +95 -10
  179. package/dist/cupola/definition.d.ts.map +1 -1
  180. package/dist/cupola/definition.edit.d.ts +4 -0
  181. package/dist/cupola/definition.edit.d.ts.map +1 -0
  182. package/dist/cupola/definition.edit.js +101 -0
  183. package/dist/cupola/definition.js +4 -148
  184. package/dist/cupola/definition.render.d.ts +6 -0
  185. package/dist/cupola/definition.render.d.ts.map +1 -0
  186. package/dist/cupola/definition.render.js +45 -0
  187. package/dist/cupola/move-tool.d.ts.map +1 -1
  188. package/dist/cupola/move-tool.js +6 -5
  189. package/dist/definition-contributions.d.ts +14 -0
  190. package/dist/definition-contributions.d.ts.map +1 -0
  191. package/dist/definition-contributions.js +8 -0
  192. package/dist/door/definition.d.ts +350 -22
  193. package/dist/door/definition.d.ts.map +1 -1
  194. package/dist/door/definition.edit.d.ts +4 -0
  195. package/dist/door/definition.edit.d.ts.map +1 -0
  196. package/dist/door/definition.edit.js +241 -0
  197. package/dist/door/definition.js +4 -341
  198. package/dist/door/definition.render.d.ts +6 -0
  199. package/dist/door/definition.render.d.ts.map +1 -0
  200. package/dist/door/definition.render.js +94 -0
  201. package/dist/door/floorplan-move.d.ts.map +1 -1
  202. package/dist/door/floorplan-move.js +11 -8
  203. package/dist/door/floorplan.d.ts.map +1 -1
  204. package/dist/door/floorplan.js +1 -2
  205. package/dist/door/mechanism.d.ts.map +1 -1
  206. package/dist/door/mechanism.js +1 -2
  207. package/dist/door/move-tool.d.ts.map +1 -1
  208. package/dist/door/move-tool.js +25 -23
  209. package/dist/door/tool.d.ts.map +1 -1
  210. package/dist/door/tool.js +2 -1
  211. package/dist/dormer/definition.d.ts +240 -11
  212. package/dist/dormer/definition.d.ts.map +1 -1
  213. package/dist/dormer/definition.edit.d.ts +4 -0
  214. package/dist/dormer/definition.edit.d.ts.map +1 -0
  215. package/dist/dormer/definition.edit.js +212 -0
  216. package/dist/dormer/definition.js +4 -319
  217. package/dist/dormer/definition.render.d.ts +6 -0
  218. package/dist/dormer/definition.render.d.ts.map +1 -0
  219. package/dist/dormer/definition.render.js +54 -0
  220. package/dist/dormer/panel-position-section.js +1 -1
  221. package/dist/downspout/definition.d.ts +108 -16
  222. package/dist/downspout/definition.d.ts.map +1 -1
  223. package/dist/downspout/definition.edit.d.ts +4 -0
  224. package/dist/downspout/definition.edit.d.ts.map +1 -0
  225. package/dist/downspout/definition.edit.js +134 -0
  226. package/dist/downspout/definition.js +4 -188
  227. package/dist/downspout/definition.render.d.ts +6 -0
  228. package/dist/downspout/definition.render.d.ts.map +1 -0
  229. package/dist/downspout/definition.render.js +46 -0
  230. package/dist/duct-fitting/definition.d.ts +99 -11
  231. package/dist/duct-fitting/definition.d.ts.map +1 -1
  232. package/dist/duct-fitting/definition.edit.d.ts +4 -0
  233. package/dist/duct-fitting/definition.edit.d.ts.map +1 -0
  234. package/dist/duct-fitting/definition.edit.js +47 -0
  235. package/dist/duct-fitting/definition.js +4 -135
  236. package/dist/duct-fitting/definition.render.d.ts +6 -0
  237. package/dist/duct-fitting/definition.render.d.ts.map +1 -0
  238. package/dist/duct-fitting/definition.render.js +84 -0
  239. package/dist/duct-fitting/floorplan.js +1 -1
  240. package/dist/duct-fitting/geometry.js +2 -1
  241. package/dist/duct-fitting/move-tool.d.ts.map +1 -1
  242. package/dist/duct-fitting/move-tool.js +19 -13
  243. package/dist/duct-fitting/selection.d.ts.map +1 -1
  244. package/dist/duct-fitting/selection.js +92 -80
  245. package/dist/duct-segment/continuation-handle.d.ts +8 -0
  246. package/dist/duct-segment/continuation-handle.d.ts.map +1 -0
  247. package/dist/duct-segment/continuation-handle.js +36 -0
  248. package/dist/duct-segment/continuation.d.ts +3 -7
  249. package/dist/duct-segment/continuation.d.ts.map +1 -1
  250. package/dist/duct-segment/continuation.js +54 -37
  251. package/dist/duct-segment/definition.d.ts +91 -3
  252. package/dist/duct-segment/definition.d.ts.map +1 -1
  253. package/dist/duct-segment/definition.edit.d.ts +4 -0
  254. package/dist/duct-segment/definition.edit.d.ts.map +1 -0
  255. package/dist/duct-segment/definition.edit.js +98 -0
  256. package/dist/duct-segment/definition.js +4 -181
  257. package/dist/duct-segment/definition.render.d.ts +6 -0
  258. package/dist/duct-segment/definition.render.d.ts.map +1 -0
  259. package/dist/duct-segment/definition.render.js +91 -0
  260. package/dist/duct-segment/edit-inspector.d.ts +5 -0
  261. package/dist/duct-segment/edit-inspector.d.ts.map +1 -0
  262. package/dist/duct-segment/edit-inspector.js +163 -0
  263. package/dist/duct-segment/edit-operation.d.ts +17 -0
  264. package/dist/duct-segment/edit-operation.d.ts.map +1 -0
  265. package/dist/duct-segment/edit-operation.js +283 -0
  266. package/dist/duct-segment/floorplan.js +2 -2
  267. package/dist/duct-segment/geometry.d.ts +0 -40
  268. package/dist/duct-segment/geometry.d.ts.map +1 -1
  269. package/dist/duct-segment/geometry.js +2 -77
  270. package/dist/duct-segment/move-tool.d.ts.map +1 -1
  271. package/dist/duct-segment/move-tool.js +34 -35
  272. package/dist/duct-segment/parametrics.d.ts.map +1 -1
  273. package/dist/duct-segment/parametrics.js +2 -35
  274. package/dist/duct-segment/profile.d.ts +42 -0
  275. package/dist/duct-segment/profile.d.ts.map +1 -0
  276. package/dist/duct-segment/profile.js +78 -0
  277. package/dist/duct-segment/selection.d.ts.map +1 -1
  278. package/dist/duct-segment/selection.js +114 -54
  279. package/dist/duct-segment/tool.d.ts.map +1 -1
  280. package/dist/duct-segment/tool.js +105 -28
  281. package/dist/duct-terminal/definition.d.ts +68 -12
  282. package/dist/duct-terminal/definition.d.ts.map +1 -1
  283. package/dist/duct-terminal/definition.edit.d.ts +4 -0
  284. package/dist/duct-terminal/definition.edit.d.ts.map +1 -0
  285. package/dist/duct-terminal/definition.edit.js +12 -0
  286. package/dist/duct-terminal/definition.js +4 -87
  287. package/dist/duct-terminal/definition.render.d.ts +6 -0
  288. package/dist/duct-terminal/definition.render.d.ts.map +1 -0
  289. package/dist/duct-terminal/definition.render.js +68 -0
  290. package/dist/duct-terminal/geometry.d.ts.map +1 -1
  291. package/dist/duct-terminal/geometry.js +2 -1
  292. package/dist/duct-terminal/parametrics.d.ts.map +1 -1
  293. package/dist/duct-terminal/parametrics.js +1 -0
  294. package/dist/duct-terminal/ports.js +1 -1
  295. package/dist/elevator/__bench__/runtime.d.ts +2 -0
  296. package/dist/elevator/__bench__/runtime.d.ts.map +1 -0
  297. package/dist/elevator/__bench__/runtime.js +38 -0
  298. package/dist/elevator/definition.d.ts +117 -10
  299. package/dist/elevator/definition.d.ts.map +1 -1
  300. package/dist/elevator/definition.edit.d.ts +4 -0
  301. package/dist/elevator/definition.edit.d.ts.map +1 -0
  302. package/dist/elevator/definition.edit.js +167 -0
  303. package/dist/elevator/definition.js +4 -258
  304. package/dist/elevator/definition.render.d.ts +11 -0
  305. package/dist/elevator/definition.render.d.ts.map +1 -0
  306. package/dist/elevator/definition.render.js +106 -0
  307. package/dist/elevator/floorplan-affordances.d.ts.map +1 -1
  308. package/dist/elevator/floorplan-affordances.js +11 -9
  309. package/dist/elevator/floorplan.d.ts +19 -0
  310. package/dist/elevator/floorplan.d.ts.map +1 -1
  311. package/dist/elevator/floorplan.js +3 -9
  312. package/dist/elevator/inspection.d.ts +17 -0
  313. package/dist/elevator/inspection.d.ts.map +1 -0
  314. package/dist/elevator/inspection.js +78 -0
  315. package/dist/elevator/panel.d.ts.map +1 -1
  316. package/dist/elevator/panel.js +152 -100
  317. package/dist/elevator/parametrics.d.ts +1 -1
  318. package/dist/elevator/parametrics.d.ts.map +1 -1
  319. package/dist/elevator/parametrics.js +7 -10
  320. package/dist/elevator/presets.d.ts +17 -0
  321. package/dist/elevator/presets.d.ts.map +1 -0
  322. package/dist/elevator/presets.js +52 -0
  323. package/dist/elevator/renderer.d.ts +2 -1
  324. package/dist/elevator/renderer.d.ts.map +1 -1
  325. package/dist/elevator/renderer.edit.d.ts +5 -0
  326. package/dist/elevator/renderer.edit.d.ts.map +1 -0
  327. package/dist/elevator/renderer.edit.js +8 -0
  328. package/dist/elevator/renderer.js +159 -60
  329. package/dist/elevator/tool.d.ts +2 -0
  330. package/dist/elevator/tool.d.ts.map +1 -0
  331. package/dist/elevator/tool.js +250 -0
  332. package/dist/eyebrow-vent/definition.d.ts +97 -11
  333. package/dist/eyebrow-vent/definition.d.ts.map +1 -1
  334. package/dist/eyebrow-vent/definition.edit.d.ts +4 -0
  335. package/dist/eyebrow-vent/definition.edit.d.ts.map +1 -0
  336. package/dist/eyebrow-vent/definition.edit.js +104 -0
  337. package/dist/eyebrow-vent/definition.js +4 -152
  338. package/dist/eyebrow-vent/definition.render.d.ts +6 -0
  339. package/dist/eyebrow-vent/definition.render.d.ts.map +1 -0
  340. package/dist/eyebrow-vent/definition.render.js +45 -0
  341. package/dist/eyebrow-vent/move-tool.d.ts.map +1 -1
  342. package/dist/eyebrow-vent/move-tool.js +6 -5
  343. package/dist/fence/definition.d.ts +186 -17
  344. package/dist/fence/definition.d.ts.map +1 -1
  345. package/dist/fence/definition.edit.d.ts +4 -0
  346. package/dist/fence/definition.edit.d.ts.map +1 -0
  347. package/dist/fence/definition.edit.js +276 -0
  348. package/dist/fence/definition.js +5 -413
  349. package/dist/fence/definition.render.d.ts +8 -0
  350. package/dist/fence/definition.render.d.ts.map +1 -0
  351. package/dist/fence/definition.render.js +126 -0
  352. package/dist/fence/move-endpoint-tool.d.ts.map +1 -1
  353. package/dist/fence/move-endpoint-tool.js +2 -2
  354. package/dist/fence/tool.js +2 -2
  355. package/dist/fence-feature/definition.d.ts +270 -3
  356. package/dist/fence-feature/definition.d.ts.map +1 -1
  357. package/dist/fence-feature/definition.edit.d.ts +5 -0
  358. package/dist/fence-feature/definition.edit.d.ts.map +1 -0
  359. package/dist/fence-feature/definition.edit.js +66 -0
  360. package/dist/fence-feature/definition.js +5 -116
  361. package/dist/fence-feature/definition.render.d.ts +9 -0
  362. package/dist/fence-feature/definition.render.d.ts.map +1 -0
  363. package/dist/fence-feature/definition.render.js +72 -0
  364. package/dist/floor-opening/definition.d.ts +58 -2
  365. package/dist/floor-opening/definition.d.ts.map +1 -1
  366. package/dist/floor-opening/definition.edit.d.ts +4 -0
  367. package/dist/floor-opening/definition.edit.d.ts.map +1 -0
  368. package/dist/floor-opening/definition.edit.js +9 -0
  369. package/dist/floor-opening/definition.js +4 -41
  370. package/dist/floor-opening/definition.render.d.ts +6 -0
  371. package/dist/floor-opening/definition.render.d.ts.map +1 -0
  372. package/dist/floor-opening/definition.render.js +35 -0
  373. package/dist/floor-opening/floorplan-affordances.d.ts +150 -0
  374. package/dist/floor-opening/floorplan-affordances.d.ts.map +1 -0
  375. package/dist/floor-opening/floorplan-affordances.js +67 -0
  376. package/dist/floor-opening/floorplan.d.ts +2 -151
  377. package/dist/floor-opening/floorplan.d.ts.map +1 -1
  378. package/dist/floor-opening/floorplan.js +0 -66
  379. package/dist/guide/definition.d.ts +65 -9
  380. package/dist/guide/definition.d.ts.map +1 -1
  381. package/dist/guide/definition.edit.d.ts +4 -0
  382. package/dist/guide/definition.edit.d.ts.map +1 -0
  383. package/dist/guide/definition.edit.js +4 -0
  384. package/dist/guide/definition.js +4 -53
  385. package/dist/guide/definition.render.d.ts +6 -0
  386. package/dist/guide/definition.render.d.ts.map +1 -0
  387. package/dist/guide/definition.render.js +45 -0
  388. package/dist/gutter/definition.d.ts +113 -18
  389. package/dist/gutter/definition.d.ts.map +1 -1
  390. package/dist/gutter/definition.edit.d.ts +4 -0
  391. package/dist/gutter/definition.edit.d.ts.map +1 -0
  392. package/dist/gutter/definition.edit.js +119 -0
  393. package/dist/gutter/definition.js +4 -176
  394. package/dist/gutter/definition.render.d.ts +6 -0
  395. package/dist/gutter/definition.render.d.ts.map +1 -0
  396. package/dist/gutter/definition.render.js +46 -0
  397. package/dist/gutter/move-tool.d.ts.map +1 -1
  398. package/dist/gutter/move-tool.js +5 -4
  399. package/dist/hvac-equipment/definition.d.ts +72 -12
  400. package/dist/hvac-equipment/definition.d.ts.map +1 -1
  401. package/dist/hvac-equipment/definition.edit.d.ts +4 -0
  402. package/dist/hvac-equipment/definition.edit.d.ts.map +1 -0
  403. package/dist/hvac-equipment/definition.edit.js +11 -0
  404. package/dist/hvac-equipment/definition.js +4 -92
  405. package/dist/hvac-equipment/definition.render.d.ts +6 -0
  406. package/dist/hvac-equipment/definition.render.d.ts.map +1 -0
  407. package/dist/hvac-equipment/definition.render.js +74 -0
  408. package/dist/hvac-equipment/floorplan.js +1 -1
  409. package/dist/hvac-equipment/geometry.d.ts.map +1 -1
  410. package/dist/hvac-equipment/geometry.js +2 -1
  411. package/dist/hvac-equipment/parametrics.d.ts.map +1 -1
  412. package/dist/hvac-equipment/parametrics.js +1 -0
  413. package/dist/hvac-equipment/ports.js +1 -1
  414. package/dist/i18n/definition-messages.js +1 -1
  415. package/dist/imported-mesh/definition.d.ts +54 -4
  416. package/dist/imported-mesh/definition.d.ts.map +1 -1
  417. package/dist/imported-mesh/definition.edit.d.ts +4 -0
  418. package/dist/imported-mesh/definition.edit.d.ts.map +1 -0
  419. package/dist/imported-mesh/definition.edit.js +3 -0
  420. package/dist/imported-mesh/definition.js +4 -40
  421. package/dist/imported-mesh/definition.render.d.ts +6 -0
  422. package/dist/imported-mesh/definition.render.d.ts.map +1 -0
  423. package/dist/imported-mesh/definition.render.js +38 -0
  424. package/dist/index.d.ts +3 -16
  425. package/dist/index.d.ts.map +1 -1
  426. package/dist/index.js +9 -136
  427. package/dist/item/definition.d.ts +280 -31
  428. package/dist/item/definition.d.ts.map +1 -1
  429. package/dist/item/definition.edit.d.ts +4 -0
  430. package/dist/item/definition.edit.d.ts.map +1 -0
  431. package/dist/item/definition.edit.js +203 -0
  432. package/dist/item/definition.js +4 -356
  433. package/dist/item/definition.render.d.ts +6 -0
  434. package/dist/item/definition.render.d.ts.map +1 -0
  435. package/dist/item/definition.render.js +132 -0
  436. package/dist/item/floorplan.d.ts.map +1 -1
  437. package/dist/item/floorplan.js +1 -2
  438. package/dist/item/plan-symbols.js +1 -1
  439. package/dist/item/renderer.d.ts.map +1 -1
  440. package/dist/item/renderer.js +2 -2
  441. package/dist/lean-to-extension/definition.d.ts +177 -3
  442. package/dist/lean-to-extension/definition.d.ts.map +1 -1
  443. package/dist/lean-to-extension/definition.edit.d.ts +4 -0
  444. package/dist/lean-to-extension/definition.edit.d.ts.map +1 -0
  445. package/dist/lean-to-extension/definition.edit.js +390 -0
  446. package/dist/lean-to-extension/definition.js +4 -433
  447. package/dist/lean-to-extension/definition.render.d.ts +6 -0
  448. package/dist/lean-to-extension/definition.render.d.ts.map +1 -0
  449. package/dist/lean-to-extension/definition.render.js +48 -0
  450. package/dist/level/definition.d.ts +49 -8
  451. package/dist/level/definition.d.ts.map +1 -1
  452. package/dist/level/definition.edit.d.ts +4 -0
  453. package/dist/level/definition.edit.d.ts.map +1 -0
  454. package/dist/level/definition.edit.js +4 -0
  455. package/dist/level/definition.js +4 -60
  456. package/dist/level/definition.render.d.ts +6 -0
  457. package/dist/level/definition.render.d.ts.map +1 -0
  458. package/dist/level/definition.render.js +53 -0
  459. package/dist/lineset/definition.d.ts +49 -14
  460. package/dist/lineset/definition.d.ts.map +1 -1
  461. package/dist/lineset/definition.edit.d.ts +4 -0
  462. package/dist/lineset/definition.edit.d.ts.map +1 -0
  463. package/dist/lineset/definition.edit.js +36 -0
  464. package/dist/lineset/definition.js +4 -119
  465. package/dist/lineset/definition.render.d.ts +6 -0
  466. package/dist/lineset/definition.render.d.ts.map +1 -0
  467. package/dist/lineset/definition.render.js +74 -0
  468. package/dist/lineset/floorplan.js +1 -1
  469. package/dist/lineset/geometry.js +1 -1
  470. package/dist/lineset/move-tool.d.ts.map +1 -1
  471. package/dist/lineset/move-tool.js +14 -7
  472. package/dist/liquid-line/definition.d.ts +47 -15
  473. package/dist/liquid-line/definition.d.ts.map +1 -1
  474. package/dist/liquid-line/definition.edit.d.ts +4 -0
  475. package/dist/liquid-line/definition.edit.d.ts.map +1 -0
  476. package/dist/liquid-line/definition.edit.js +29 -0
  477. package/dist/liquid-line/definition.js +4 -111
  478. package/dist/liquid-line/definition.render.d.ts +6 -0
  479. package/dist/liquid-line/definition.render.d.ts.map +1 -0
  480. package/dist/liquid-line/definition.render.js +72 -0
  481. package/dist/liquid-line/floorplan.js +1 -1
  482. package/dist/liquid-line/geometry.js +1 -1
  483. package/dist/measurement/definition.d.ts +126 -3
  484. package/dist/measurement/definition.d.ts.map +1 -1
  485. package/dist/measurement/definition.edit.d.ts +4 -0
  486. package/dist/measurement/definition.edit.d.ts.map +1 -0
  487. package/dist/measurement/definition.edit.js +24 -0
  488. package/dist/measurement/definition.js +4 -67
  489. package/dist/measurement/definition.render.d.ts +6 -0
  490. package/dist/measurement/definition.render.d.ts.map +1 -0
  491. package/dist/measurement/definition.render.js +45 -0
  492. package/dist/measurement/floorplan.d.ts.map +1 -1
  493. package/dist/measurement/floorplan.js +2 -2
  494. package/dist/measurement/renderer.d.ts.map +1 -1
  495. package/dist/measurement/renderer.js +2 -3
  496. package/dist/measurement/selection.d.ts.map +1 -1
  497. package/dist/measurement/selection.js +2 -2
  498. package/dist/measurement/tool.d.ts +2 -2
  499. package/dist/measurement/tool.d.ts.map +1 -1
  500. package/dist/measurement/tool.js +3 -3
  501. package/dist/pipe-fitting/definition.d.ts +73 -9
  502. package/dist/pipe-fitting/definition.d.ts.map +1 -1
  503. package/dist/pipe-fitting/definition.edit.d.ts +4 -0
  504. package/dist/pipe-fitting/definition.edit.d.ts.map +1 -0
  505. package/dist/pipe-fitting/definition.edit.js +45 -0
  506. package/dist/pipe-fitting/definition.js +4 -105
  507. package/dist/pipe-fitting/definition.render.d.ts +6 -0
  508. package/dist/pipe-fitting/definition.render.d.ts.map +1 -0
  509. package/dist/pipe-fitting/definition.render.js +56 -0
  510. package/dist/pipe-fitting/floorplan.js +1 -1
  511. package/dist/pipe-fitting/geometry.js +1 -1
  512. package/dist/pipe-fitting/move-tool.d.ts +1 -1
  513. package/dist/pipe-fitting/move-tool.d.ts.map +1 -1
  514. package/dist/pipe-fitting/move-tool.js +28 -22
  515. package/dist/pipe-fitting/parametrics.d.ts.map +1 -1
  516. package/dist/pipe-fitting/parametrics.js +1 -0
  517. package/dist/pipe-fitting/ports.js +1 -1
  518. package/dist/pipe-fitting/selection.d.ts.map +1 -1
  519. package/dist/pipe-fitting/selection.js +73 -29
  520. package/dist/pipe-segment/collar-connection.d.ts +12 -0
  521. package/dist/pipe-segment/collar-connection.d.ts.map +1 -0
  522. package/dist/pipe-segment/collar-connection.js +58 -0
  523. package/dist/pipe-segment/connect-operation.d.ts +9 -0
  524. package/dist/pipe-segment/connect-operation.d.ts.map +1 -0
  525. package/dist/pipe-segment/connect-operation.js +44 -0
  526. package/dist/pipe-segment/continuation-handle.d.ts +9 -0
  527. package/dist/pipe-segment/continuation-handle.d.ts.map +1 -0
  528. package/dist/pipe-segment/continuation-handle.js +35 -0
  529. package/dist/pipe-segment/continuation.d.ts +4 -7
  530. package/dist/pipe-segment/continuation.d.ts.map +1 -1
  531. package/dist/pipe-segment/continuation.js +62 -36
  532. package/dist/pipe-segment/definition.d.ts +78 -13
  533. package/dist/pipe-segment/definition.d.ts.map +1 -1
  534. package/dist/pipe-segment/definition.edit.d.ts +4 -0
  535. package/dist/pipe-segment/definition.edit.d.ts.map +1 -0
  536. package/dist/pipe-segment/definition.edit.js +46 -0
  537. package/dist/pipe-segment/definition.js +4 -132
  538. package/dist/pipe-segment/definition.render.d.ts +6 -0
  539. package/dist/pipe-segment/definition.render.d.ts.map +1 -0
  540. package/dist/pipe-segment/definition.render.js +80 -0
  541. package/dist/pipe-segment/floorplan.d.ts +1 -1
  542. package/dist/pipe-segment/floorplan.d.ts.map +1 -1
  543. package/dist/pipe-segment/floorplan.js +35 -2
  544. package/dist/pipe-segment/geometry.d.ts.map +1 -1
  545. package/dist/pipe-segment/geometry.js +2 -1
  546. package/dist/pipe-segment/grade-affordance.d.ts +8 -0
  547. package/dist/pipe-segment/grade-affordance.d.ts.map +1 -0
  548. package/dist/pipe-segment/grade-affordance.js +116 -0
  549. package/dist/pipe-segment/grade-inspector.d.ts +5 -0
  550. package/dist/pipe-segment/grade-inspector.d.ts.map +1 -0
  551. package/dist/pipe-segment/grade-inspector.js +91 -0
  552. package/dist/pipe-segment/grade-label.d.ts +7 -0
  553. package/dist/pipe-segment/grade-label.d.ts.map +1 -0
  554. package/dist/pipe-segment/grade-label.js +32 -0
  555. package/dist/pipe-segment/grade-operation.d.ts +22 -0
  556. package/dist/pipe-segment/grade-operation.d.ts.map +1 -0
  557. package/dist/pipe-segment/grade-operation.js +114 -0
  558. package/dist/pipe-segment/move-tool.d.ts.map +1 -1
  559. package/dist/pipe-segment/move-tool.js +38 -15
  560. package/dist/pipe-segment/offset-inspector.d.ts +5 -0
  561. package/dist/pipe-segment/offset-inspector.d.ts.map +1 -0
  562. package/dist/pipe-segment/offset-inspector.js +112 -0
  563. package/dist/pipe-segment/offset-operation.d.ts +9 -0
  564. package/dist/pipe-segment/offset-operation.d.ts.map +1 -0
  565. package/dist/pipe-segment/offset-operation.js +104 -0
  566. package/dist/pipe-segment/parametrics.d.ts.map +1 -1
  567. package/dist/pipe-segment/parametrics.js +1 -9
  568. package/dist/pipe-segment/resize-inspector.d.ts +5 -0
  569. package/dist/pipe-segment/resize-inspector.d.ts.map +1 -0
  570. package/dist/pipe-segment/resize-inspector.js +75 -0
  571. package/dist/pipe-segment/resize-operation.d.ts +8 -0
  572. package/dist/pipe-segment/resize-operation.d.ts.map +1 -0
  573. package/dist/pipe-segment/resize-operation.js +143 -0
  574. package/dist/pipe-segment/run-move.d.ts +65 -0
  575. package/dist/pipe-segment/run-move.d.ts.map +1 -0
  576. package/dist/pipe-segment/run-move.js +110 -0
  577. package/dist/pipe-segment/selection.d.ts.map +1 -1
  578. package/dist/pipe-segment/selection.js +124 -179
  579. package/dist/pipe-segment/slope.d.ts +3 -0
  580. package/dist/pipe-segment/slope.d.ts.map +1 -1
  581. package/dist/pipe-segment/slope.js +47 -0
  582. package/dist/pipe-segment/tool.d.ts.map +1 -1
  583. package/dist/pipe-segment/tool.js +125 -29
  584. package/dist/pipe-trap/definition.d.ts +54 -9
  585. package/dist/pipe-trap/definition.d.ts.map +1 -1
  586. package/dist/pipe-trap/definition.edit.d.ts +4 -0
  587. package/dist/pipe-trap/definition.edit.d.ts.map +1 -0
  588. package/dist/pipe-trap/definition.edit.js +11 -0
  589. package/dist/pipe-trap/definition.js +4 -59
  590. package/dist/pipe-trap/definition.render.d.ts +6 -0
  591. package/dist/pipe-trap/definition.render.d.ts.map +1 -0
  592. package/dist/pipe-trap/definition.render.js +45 -0
  593. package/dist/pipe-trap/geometry.d.ts.map +1 -1
  594. package/dist/pipe-trap/geometry.js +2 -1
  595. package/dist/pipe-trap/parametrics.d.ts.map +1 -1
  596. package/dist/pipe-trap/parametrics.js +1 -0
  597. package/dist/procedural-item/definition.d.ts +734 -3
  598. package/dist/procedural-item/definition.d.ts.map +1 -1
  599. package/dist/procedural-item/definition.edit.d.ts +4 -0
  600. package/dist/procedural-item/definition.edit.d.ts.map +1 -0
  601. package/dist/procedural-item/definition.edit.js +202 -0
  602. package/dist/procedural-item/definition.js +4 -325
  603. package/dist/procedural-item/definition.render.d.ts +6 -0
  604. package/dist/procedural-item/definition.render.d.ts.map +1 -0
  605. package/dist/procedural-item/definition.render.js +137 -0
  606. package/dist/procedural-item/renderer.d.ts.map +1 -1
  607. package/dist/procedural-item/renderer.edit.d.ts +5 -0
  608. package/dist/procedural-item/renderer.edit.d.ts.map +1 -0
  609. package/dist/procedural-item/renderer.edit.js +49 -0
  610. package/dist/procedural-item/renderer.js +4 -21
  611. package/dist/render.d.ts +4 -0
  612. package/dist/render.d.ts.map +1 -0
  613. package/dist/render.js +4 -0
  614. package/dist/ridge-vent/definition.d.ts +95 -15
  615. package/dist/ridge-vent/definition.d.ts.map +1 -1
  616. package/dist/ridge-vent/definition.edit.d.ts +4 -0
  617. package/dist/ridge-vent/definition.edit.d.ts.map +1 -0
  618. package/dist/ridge-vent/definition.edit.js +146 -0
  619. package/dist/ridge-vent/definition.js +4 -197
  620. package/dist/ridge-vent/definition.render.d.ts +6 -0
  621. package/dist/ridge-vent/definition.render.d.ts.map +1 -0
  622. package/dist/ridge-vent/definition.render.js +44 -0
  623. package/dist/ridge-vent/move-tool.d.ts.map +1 -1
  624. package/dist/ridge-vent/move-tool.js +5 -4
  625. package/dist/roof/barrel-panel.d.ts.map +1 -1
  626. package/dist/roof/barrel-panel.js +2 -2
  627. package/dist/roof/definition.d.ts +325 -8
  628. package/dist/roof/definition.d.ts.map +1 -1
  629. package/dist/roof/definition.edit.d.ts +4 -0
  630. package/dist/roof/definition.edit.d.ts.map +1 -0
  631. package/dist/roof/definition.edit.js +181 -0
  632. package/dist/roof/definition.js +4 -284
  633. package/dist/roof/definition.render.d.ts +7 -0
  634. package/dist/roof/definition.render.d.ts.map +1 -0
  635. package/dist/roof/definition.render.js +112 -0
  636. package/dist/roof/floorplan.d.ts.map +1 -1
  637. package/dist/roof/floorplan.js +1 -2
  638. package/dist/roof/geometry-notice.d.ts +5 -0
  639. package/dist/roof/geometry-notice.d.ts.map +1 -0
  640. package/dist/roof/geometry-notice.js +27 -0
  641. package/dist/roof/glazing-controls.d.ts.map +1 -1
  642. package/dist/roof/glazing-controls.js +2 -2
  643. package/dist/roof/panel.d.ts.map +1 -1
  644. package/dist/roof/panel.js +4 -3
  645. package/dist/roof/renderer.d.ts.map +1 -1
  646. package/dist/roof/renderer.js +10 -5
  647. package/dist/roof/tool.d.ts +3 -0
  648. package/dist/roof/tool.d.ts.map +1 -1
  649. package/dist/roof/tool.js +56 -170
  650. package/dist/roof/type-thumbnail-assets.d.ts +3 -0
  651. package/dist/roof/type-thumbnail-assets.d.ts.map +1 -0
  652. package/dist/roof/type-thumbnail-assets.js +12 -0
  653. package/dist/roof/type-thumbnail.d.ts +5 -0
  654. package/dist/roof/type-thumbnail.d.ts.map +1 -0
  655. package/dist/roof/type-thumbnail.js +5 -0
  656. package/dist/roof-segment/definition.d.ts +564 -9
  657. package/dist/roof-segment/definition.d.ts.map +1 -1
  658. package/dist/roof-segment/definition.edit.d.ts +4 -0
  659. package/dist/roof-segment/definition.edit.d.ts.map +1 -0
  660. package/dist/roof-segment/definition.edit.js +303 -0
  661. package/dist/roof-segment/definition.js +4 -364
  662. package/dist/roof-segment/definition.render.d.ts +6 -0
  663. package/dist/roof-segment/definition.render.d.ts.map +1 -0
  664. package/dist/roof-segment/definition.render.js +61 -0
  665. package/dist/roof-segment/floorplan-affordances.d.ts.map +1 -1
  666. package/dist/roof-segment/floorplan-affordances.js +2 -2
  667. package/dist/roof-segment/paint.d.ts +0 -1
  668. package/dist/roof-segment/paint.d.ts.map +1 -1
  669. package/dist/roof-segment/paint.js +0 -1
  670. package/dist/roof-segment/panel.d.ts.map +1 -1
  671. package/dist/roof-segment/panel.js +32 -34
  672. package/dist/roof-segment/parametrics.d.ts.map +1 -1
  673. package/dist/roof-segment/parametrics.js +13 -11
  674. package/dist/roof-segment/slots.d.ts +2 -0
  675. package/dist/roof-segment/slots.d.ts.map +1 -0
  676. package/dist/roof-segment/slots.js +1 -0
  677. package/dist/scan/definition.d.ts +57 -7
  678. package/dist/scan/definition.d.ts.map +1 -1
  679. package/dist/scan/definition.edit.d.ts +4 -0
  680. package/dist/scan/definition.edit.d.ts.map +1 -0
  681. package/dist/scan/definition.edit.js +4 -0
  682. package/dist/scan/definition.js +4 -52
  683. package/dist/scan/definition.render.d.ts +6 -0
  684. package/dist/scan/definition.render.d.ts.map +1 -0
  685. package/dist/scan/definition.render.js +46 -0
  686. package/dist/separator/definition.d.ts +47 -2
  687. package/dist/separator/definition.d.ts.map +1 -1
  688. package/dist/separator/definition.edit.d.ts +4 -0
  689. package/dist/separator/definition.edit.d.ts.map +1 -0
  690. package/dist/separator/definition.edit.js +11 -0
  691. package/dist/separator/definition.js +4 -37
  692. package/dist/separator/definition.render.d.ts +6 -0
  693. package/dist/separator/definition.render.d.ts.map +1 -0
  694. package/dist/separator/definition.render.js +29 -0
  695. package/dist/separator/floorplan.js +1 -1
  696. package/dist/separator/renderer.d.ts +2 -1
  697. package/dist/separator/renderer.d.ts.map +1 -1
  698. package/dist/separator/renderer.edit.d.ts +5 -0
  699. package/dist/separator/renderer.edit.d.ts.map +1 -0
  700. package/dist/separator/renderer.edit.js +8 -0
  701. package/dist/separator/renderer.js +3 -5
  702. package/dist/separator/selection.d.ts.map +1 -1
  703. package/dist/separator/selection.js +2 -2
  704. package/dist/shared/accessory-placement.js +1 -1
  705. package/dist/shared/auto-fitting.js +1 -1
  706. package/dist/shared/auto-offset-tag.d.ts +1 -1
  707. package/dist/shared/auto-offset-tag.d.ts.map +1 -1
  708. package/dist/shared/auto-offset-tag.js +3 -1
  709. package/dist/shared/automatic-run-end-cap.d.ts +5 -0
  710. package/dist/shared/automatic-run-end-cap.d.ts.map +1 -1
  711. package/dist/shared/automatic-run-end-cap.js +17 -9
  712. package/dist/shared/connection-feedback.d.ts +6 -3
  713. package/dist/shared/connection-feedback.d.ts.map +1 -1
  714. package/dist/shared/connection-feedback.js +29 -6
  715. package/dist/shared/curtain-opening-limits.d.ts.map +1 -1
  716. package/dist/shared/curtain-opening-limits.js +2 -3
  717. package/dist/shared/draft-axis-guides.d.ts.map +1 -1
  718. package/dist/shared/draft-axis-guides.js +2 -1
  719. package/dist/shared/duct-adapter.js +1 -1
  720. package/dist/shared/duct-collar-inspector.d.ts +5 -0
  721. package/dist/shared/duct-collar-inspector.d.ts.map +1 -0
  722. package/dist/shared/duct-collar-inspector.js +36 -0
  723. package/dist/shared/follower-frames.d.ts +15 -0
  724. package/dist/shared/follower-frames.d.ts.map +1 -0
  725. package/dist/shared/follower-frames.js +36 -0
  726. package/dist/shared/handle-drag-scope.d.ts +14 -0
  727. package/dist/shared/handle-drag-scope.d.ts.map +1 -0
  728. package/dist/shared/handle-drag-scope.js +36 -0
  729. package/dist/shared/hosted-resize.d.ts +3 -1
  730. package/dist/shared/hosted-resize.d.ts.map +1 -1
  731. package/dist/shared/hosted-resize.js +10 -8
  732. package/dist/shared/live-preview.d.ts +16 -0
  733. package/dist/shared/live-preview.d.ts.map +1 -0
  734. package/dist/shared/live-preview.js +36 -0
  735. package/dist/shared/opening-documentation.d.ts +1 -1
  736. package/dist/shared/opening-documentation.d.ts.map +1 -1
  737. package/dist/shared/opening-documentation.js +1 -2
  738. package/dist/shared/opening-guides-runtime.d.ts.map +1 -1
  739. package/dist/shared/opening-guides-runtime.js +2 -2
  740. package/dist/shared/opening-placement-dimensions.d.ts.map +1 -1
  741. package/dist/shared/opening-placement-dimensions.js +2 -3
  742. package/dist/shared/path-point-affordance.d.ts.map +1 -1
  743. package/dist/shared/path-point-affordance.js +19 -24
  744. package/dist/shared/path-segment-affordance.d.ts +2 -1
  745. package/dist/shared/path-segment-affordance.d.ts.map +1 -1
  746. package/dist/shared/path-segment-affordance.js +11 -8
  747. package/dist/shared/pipe-collar-inspector.d.ts +5 -0
  748. package/dist/shared/pipe-collar-inspector.d.ts.map +1 -0
  749. package/dist/shared/pipe-collar-inspector.js +27 -0
  750. package/dist/shared/refrigerant-line-selection.d.ts.map +1 -1
  751. package/dist/shared/refrigerant-line-selection.js +46 -29
  752. package/dist/shared/relative-roof-drag.d.ts.map +1 -1
  753. package/dist/shared/relative-roof-drag.js +5 -4
  754. package/dist/shared/roof-surface.d.ts.map +1 -1
  755. package/dist/shared/roof-surface.js +2 -0
  756. package/dist/shared/run-hangers.d.ts.map +1 -1
  757. package/dist/shared/run-hangers.js +2 -2
  758. package/dist/shared/run-move-connectivity.d.ts +15 -6
  759. package/dist/shared/run-move-connectivity.d.ts.map +1 -1
  760. package/dist/shared/run-move-connectivity.js +14 -5
  761. package/dist/shared/run-tool-options.d.ts +8 -0
  762. package/dist/shared/run-tool-options.d.ts.map +1 -0
  763. package/dist/shared/run-tool-options.js +166 -0
  764. package/dist/shared/system-checks.d.ts.map +1 -1
  765. package/dist/shared/system-checks.js +2 -1
  766. package/dist/shared/vertical-offset.js +1 -1
  767. package/dist/shared/wall-opening-ceiling.d.ts +6 -0
  768. package/dist/shared/wall-opening-ceiling.d.ts.map +1 -1
  769. package/dist/shared/wall-opening-ceiling.js +36 -7
  770. package/dist/shelf/definition.d.ts +108 -3
  771. package/dist/shelf/definition.d.ts.map +1 -1
  772. package/dist/shelf/definition.edit.d.ts +4 -0
  773. package/dist/shelf/definition.edit.d.ts.map +1 -0
  774. package/dist/shelf/definition.edit.js +153 -0
  775. package/dist/shelf/definition.js +4 -272
  776. package/dist/shelf/definition.render.d.ts +6 -0
  777. package/dist/shelf/definition.render.d.ts.map +1 -0
  778. package/dist/shelf/definition.render.js +124 -0
  779. package/dist/site/definition.d.ts +312 -9
  780. package/dist/site/definition.d.ts.map +1 -1
  781. package/dist/site/definition.edit.d.ts +4 -0
  782. package/dist/site/definition.edit.d.ts.map +1 -0
  783. package/dist/site/definition.edit.js +4 -0
  784. package/dist/site/definition.js +4 -55
  785. package/dist/site/definition.render.d.ts +6 -0
  786. package/dist/site/definition.render.d.ts.map +1 -0
  787. package/dist/site/definition.render.js +47 -0
  788. package/dist/skylight/definition.d.ts +158 -9
  789. package/dist/skylight/definition.d.ts.map +1 -1
  790. package/dist/skylight/definition.edit.d.ts +4 -0
  791. package/dist/skylight/definition.edit.d.ts.map +1 -0
  792. package/dist/skylight/definition.edit.js +216 -0
  793. package/dist/skylight/definition.js +4 -271
  794. package/dist/skylight/definition.render.d.ts +6 -0
  795. package/dist/skylight/definition.render.d.ts.map +1 -0
  796. package/dist/skylight/definition.render.js +52 -0
  797. package/dist/skylight/move-tool.d.ts.map +1 -1
  798. package/dist/skylight/move-tool.js +7 -5
  799. package/dist/skylight/panel.js +1 -1
  800. package/dist/slab/definition.d.ts +289 -20
  801. package/dist/slab/definition.d.ts.map +1 -1
  802. package/dist/slab/definition.edit.d.ts +4 -0
  803. package/dist/slab/definition.edit.d.ts.map +1 -0
  804. package/dist/slab/definition.edit.js +226 -0
  805. package/dist/slab/definition.js +4 -334
  806. package/dist/slab/definition.render.d.ts +6 -0
  807. package/dist/slab/definition.render.d.ts.map +1 -0
  808. package/dist/slab/definition.render.js +96 -0
  809. package/dist/slab/floorplan.d.ts.map +1 -1
  810. package/dist/slab/floorplan.js +1 -2
  811. package/dist/slab/panel.js +2 -2
  812. package/dist/solar-panel/definition.d.ts +145 -14
  813. package/dist/solar-panel/definition.d.ts.map +1 -1
  814. package/dist/solar-panel/definition.edit.d.ts +4 -0
  815. package/dist/solar-panel/definition.edit.d.ts.map +1 -0
  816. package/dist/solar-panel/definition.edit.js +211 -0
  817. package/dist/solar-panel/definition.js +4 -263
  818. package/dist/solar-panel/definition.render.d.ts +6 -0
  819. package/dist/solar-panel/definition.render.d.ts.map +1 -0
  820. package/dist/solar-panel/definition.render.js +44 -0
  821. package/dist/solar-panel/move-tool.d.ts.map +1 -1
  822. package/dist/solar-panel/move-tool.js +7 -5
  823. package/dist/spawn/definition.d.ts +48 -3
  824. package/dist/spawn/definition.d.ts.map +1 -1
  825. package/dist/spawn/definition.edit.d.ts +4 -0
  826. package/dist/spawn/definition.edit.d.ts.map +1 -0
  827. package/dist/spawn/definition.edit.js +55 -0
  828. package/dist/spawn/definition.js +4 -109
  829. package/dist/spawn/definition.render.d.ts +6 -0
  830. package/dist/spawn/definition.render.d.ts.map +1 -0
  831. package/dist/spawn/definition.render.js +50 -0
  832. package/dist/stair/definition.d.ts +334 -8
  833. package/dist/stair/definition.d.ts.map +1 -1
  834. package/dist/stair/definition.edit.d.ts +4 -0
  835. package/dist/stair/definition.edit.d.ts.map +1 -0
  836. package/dist/stair/definition.edit.js +364 -0
  837. package/dist/stair/definition.js +4 -443
  838. package/dist/stair/definition.render.d.ts +6 -0
  839. package/dist/stair/definition.render.d.ts.map +1 -0
  840. package/dist/stair/definition.render.js +75 -0
  841. package/dist/stair/documentation.d.ts.map +1 -1
  842. package/dist/stair/documentation.js +1 -2
  843. package/dist/stair/floorplan.d.ts.map +1 -1
  844. package/dist/stair/floorplan.js +1 -2
  845. package/dist/stair/panel.js +2 -2
  846. package/dist/stair/plan-entry.d.ts.map +1 -1
  847. package/dist/stair/plan-entry.js +1 -2
  848. package/dist/stair/structure-controls.d.ts.map +1 -1
  849. package/dist/stair/structure-controls.js +2 -2
  850. package/dist/stair-segment/definition.d.ts +130 -7
  851. package/dist/stair-segment/definition.d.ts.map +1 -1
  852. package/dist/stair-segment/definition.edit.d.ts +4 -0
  853. package/dist/stair-segment/definition.edit.d.ts.map +1 -0
  854. package/dist/stair-segment/definition.edit.js +135 -0
  855. package/dist/stair-segment/definition.js +4 -172
  856. package/dist/stair-segment/definition.render.d.ts +6 -0
  857. package/dist/stair-segment/definition.render.d.ts.map +1 -0
  858. package/dist/stair-segment/definition.render.js +38 -0
  859. package/dist/structural-grid/definition.d.ts +50 -3
  860. package/dist/structural-grid/definition.d.ts.map +1 -1
  861. package/dist/structural-grid/definition.edit.d.ts +4 -0
  862. package/dist/structural-grid/definition.edit.d.ts.map +1 -0
  863. package/dist/structural-grid/definition.edit.js +16 -0
  864. package/dist/structural-grid/definition.js +4 -51
  865. package/dist/structural-grid/definition.render.d.ts +6 -0
  866. package/dist/structural-grid/definition.render.d.ts.map +1 -0
  867. package/dist/structural-grid/definition.render.js +37 -0
  868. package/dist/structural-grid/floorplan.js +1 -1
  869. package/dist/turbine-vent/definition.d.ts +97 -23
  870. package/dist/turbine-vent/definition.d.ts.map +1 -1
  871. package/dist/turbine-vent/definition.edit.d.ts +4 -0
  872. package/dist/turbine-vent/definition.edit.d.ts.map +1 -0
  873. package/dist/turbine-vent/definition.edit.js +64 -0
  874. package/dist/turbine-vent/definition.js +4 -121
  875. package/dist/turbine-vent/definition.render.d.ts +6 -0
  876. package/dist/turbine-vent/definition.render.d.ts.map +1 -0
  877. package/dist/turbine-vent/definition.render.js +42 -0
  878. package/dist/turbine-vent/move-tool.d.ts.map +1 -1
  879. package/dist/turbine-vent/move-tool.js +6 -5
  880. package/dist/unit/definition.d.ts +53 -9
  881. package/dist/unit/definition.d.ts.map +1 -1
  882. package/dist/unit/definition.edit.d.ts +4 -0
  883. package/dist/unit/definition.edit.d.ts.map +1 -0
  884. package/dist/unit/definition.edit.js +4 -0
  885. package/dist/unit/definition.js +4 -38
  886. package/dist/unit/definition.render.d.ts +6 -0
  887. package/dist/unit/definition.render.d.ts.map +1 -0
  888. package/dist/unit/definition.render.js +30 -0
  889. package/dist/unit/unit-panel.d.ts.map +1 -1
  890. package/dist/unit/unit-panel.js +2 -2
  891. package/dist/wall/contextual-dimensions.d.ts.map +1 -1
  892. package/dist/wall/contextual-dimensions.js +1 -2
  893. package/dist/wall/curtain-wall-panel.d.ts.map +1 -1
  894. package/dist/wall/curtain-wall-panel.js +2 -2
  895. package/dist/wall/definition.d.ts +809 -3
  896. package/dist/wall/definition.d.ts.map +1 -1
  897. package/dist/wall/definition.edit.d.ts +4 -0
  898. package/dist/wall/definition.edit.d.ts.map +1 -0
  899. package/dist/wall/definition.edit.js +179 -0
  900. package/dist/wall/definition.js +4 -279
  901. package/dist/wall/definition.render.d.ts +6 -0
  902. package/dist/wall/definition.render.d.ts.map +1 -0
  903. package/dist/wall/definition.render.js +105 -0
  904. package/dist/wall/floorplan.d.ts.map +1 -1
  905. package/dist/wall/floorplan.js +2 -3
  906. package/dist/wall/measurement.d.ts.map +1 -1
  907. package/dist/wall/measurement.js +22 -5
  908. package/dist/wall/move-endpoint-tool.d.ts.map +1 -1
  909. package/dist/wall/move-endpoint-tool.js +3 -3
  910. package/dist/wall/move-shared.js +1 -1
  911. package/dist/wall/panel-model.d.ts.map +1 -1
  912. package/dist/wall/panel-model.js +4 -3
  913. package/dist/wall/panel.d.ts.map +1 -1
  914. package/dist/wall/panel.js +15 -6
  915. package/dist/wall/quick-measurement.js +1 -1
  916. package/dist/wall/rectangle-command.d.ts +1 -0
  917. package/dist/wall/rectangle-command.d.ts.map +1 -1
  918. package/dist/wall/rectangle-tool.js +2 -2
  919. package/dist/wall/split-floorplan-layer.d.ts.map +1 -1
  920. package/dist/wall/split-floorplan-layer.js +2 -2
  921. package/dist/wall/split-tool.d.ts.map +1 -1
  922. package/dist/wall/split-tool.js +2 -2
  923. package/dist/wall/tool.d.ts.map +1 -1
  924. package/dist/wall/tool.js +138 -36
  925. package/dist/wall/treatments.d.ts.map +1 -1
  926. package/dist/wall/treatments.js +36 -16
  927. package/dist/window/definition.d.ts +356 -15
  928. package/dist/window/definition.d.ts.map +1 -1
  929. package/dist/window/definition.edit.d.ts +4 -0
  930. package/dist/window/definition.edit.d.ts.map +1 -0
  931. package/dist/window/definition.edit.js +250 -0
  932. package/dist/window/definition.js +5 -338
  933. package/dist/window/definition.render.d.ts +8 -0
  934. package/dist/window/definition.render.d.ts.map +1 -0
  935. package/dist/window/definition.render.js +89 -0
  936. package/dist/window/floorplan-move.d.ts.map +1 -1
  937. package/dist/window/floorplan-move.js +7 -4
  938. package/dist/window/floorplan.d.ts.map +1 -1
  939. package/dist/window/floorplan.js +1 -2
  940. package/dist/window/mechanism.js +1 -1
  941. package/dist/window/move-tool.d.ts.map +1 -1
  942. package/dist/window/move-tool.js +7 -11
  943. package/dist/window/tool.d.ts.map +1 -1
  944. package/dist/window/tool.js +5 -2
  945. package/dist/zone/contextual-dimensions.d.ts.map +1 -1
  946. package/dist/zone/contextual-dimensions.js +1 -2
  947. package/dist/zone/definition.d.ts +264 -9
  948. package/dist/zone/definition.d.ts.map +1 -1
  949. package/dist/zone/definition.edit.d.ts +4 -0
  950. package/dist/zone/definition.edit.d.ts.map +1 -0
  951. package/dist/zone/definition.edit.js +36 -0
  952. package/dist/zone/definition.js +4 -97
  953. package/dist/zone/definition.render.d.ts +6 -0
  954. package/dist/zone/definition.render.d.ts.map +1 -0
  955. package/dist/zone/definition.render.js +57 -0
  956. package/dist/zone/floorplan.d.ts.map +1 -1
  957. package/dist/zone/floorplan.js +1 -2
  958. package/dist/zone/quantities-panel.d.ts.map +1 -1
  959. package/dist/zone/quantities-panel.js +2 -2
  960. package/dist/zone/room-clear-dimensions.d.ts.map +1 -1
  961. package/dist/zone/room-clear-dimensions.js +1 -2
  962. package/dist/zone/room-documentation.d.ts +1 -2
  963. package/dist/zone/room-documentation.d.ts.map +1 -1
  964. package/dist/zone/room-documentation.js +1 -1
  965. package/package.json +21 -10
@@ -1,7 +1,7 @@
1
1
  'use client';
2
2
  import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- import { analyzePortConnectivity, DuctSegmentNode, nodeRegistry, pauseSceneHistory, resolveConnectivityUpdates, resumeSceneHistory, sceneRegistry, useLiveNodeOverrides, useScene, } from '@pascal-app/core';
4
- import { clearPlacementSurface, DimensionPill, isAngleSnapActive, isGridSnapActive, swallowNextClick, triggerSFX, useEditor, } from '@pascal-app/editor';
3
+ import { analyzePortConnectivity, DuctSegmentNode, findLevelAncestorId, nodeRegistry, pauseSceneHistory, resolveConnectivityUpdates, resumeSceneHistory, sceneRegistry, useLiveNodeOverrides, useScene, } from '@pascal-app/core';
4
+ import { AXIS_MOVE_DRAG_LABEL, clearPlacementSurface, DimensionPill, isAngleSnapActive, isGridSnapActive, PATH_POINT_DRAG_LABEL, ROTATE_HANDLE_DRAG_LABEL, swallowNextClick, triggerSFX, useEditor, } from '@pascal-app/editor';
5
5
  import { collectScenePorts, findNearestPortXZ } from '@pascal-app/editor/distribution';
6
6
  import { useViewer } from '@pascal-app/viewer';
7
7
  import { Html } from '@react-three/drei';
@@ -11,14 +11,16 @@ import { Euler, Matrix4, Plane, Quaternion, Raycaster, Vector2, Vector3, } from
11
11
  import { newAutoOffsetGroupId, readAutoOffsetTag, translateAutoOffsetBase, withAutoOffsetTag, withoutAutoOffsetTag, } from '../shared/auto-offset-tag.js';
12
12
  import { planRunEndCapFollowUpdates } from '../shared/automatic-run-end-cap.js';
13
13
  import { detectFittingEndpoint, planFittingEndpointReaim, } from '../shared/fitting-endpoint-reaim.js';
14
+ import { useHandleDragScope } from '../shared/handle-drag-scope.js';
14
15
  import { DuctSegmentGhost, FittingGhost } from '../shared/mep-ghost.js';
15
16
  import { DUCT_PORT_SYSTEMS } from '../shared/port-systems.js';
16
17
  import { planRunTranslationOffsets } from '../shared/run-translation-offset.js';
17
18
  import { ContinuePlusHandle, HandleCube, MoveChevron, RotateArc } from '../shared/selection-handles.js';
18
19
  import { planVerticalOffsets } from '../shared/vertical-offset.js';
19
20
  import { refreshWallRunAttachment } from '../shared/wall-run-move.js';
20
- import { activateDuctContinuation, ductContinuationHandlePlan, } from './continuation.js';
21
- import { INCHES_TO_METERS } from './geometry.js';
21
+ import { activateDuctContinuation } from './continuation.js';
22
+ import { ductContinuationHandlePlan } from './continuation-handle.js';
23
+ import { INCHES_TO_METERS } from './profile.js';
22
24
  /** Port-snap radius for dragged run endpoints (meters, XZ). */
23
25
  const PORT_SNAP_RADIUS_M = 0.4;
24
26
  // In-world arrow handle layout (meters) — the arrows stand off the run body so
@@ -146,6 +148,7 @@ const DuctPointHandles = ({ duct, target }) => {
146
148
  });
147
149
  const unit = useViewer((s) => s.unit);
148
150
  const [draggingIndex, setDraggingIndex] = useState(null);
151
+ const claimHandleDrag = useHandleDragScope();
149
152
  const [rolling, setRolling] = useState(false);
150
153
  const [runMoving, setRunMoving] = useState(false);
151
154
  // Auto-routed offset preview shown while the run-center cube's ±Y arrows
@@ -307,9 +310,12 @@ const DuctPointHandles = ({ duct, target }) => {
307
310
  ]);
308
311
  }
309
312
  const path = drag.initialPath.map((p, i) => (i === drag.index ? next : p));
313
+ const followers = detached ? [] : connectivityUpdatesForPath(drag.connectivity, path);
314
+ if (!followers)
315
+ return null;
310
316
  const updates = [
311
317
  { id: duct.id, data: { path, wallAttachment: attachmentFor(path) } },
312
- ...(detached ? [] : connectivityUpdatesForPath(drag.connectivity, path)),
318
+ ...followers,
313
319
  ];
314
320
  return detached ? updates : withEndCapFollow(path, updates);
315
321
  };
@@ -322,12 +328,13 @@ const DuctPointHandles = ({ duct, target }) => {
322
328
  };
323
329
  // Follow-updates for fittings / ducts mated to this run's endpoints, given
324
330
  // the run's live path. Endpoints whose position didn't change resolve to a
325
- // zero delta, so only the dragged endpoint's partner actually moves.
331
+ // zero delta, so only the dragged endpoint's partner actually moves. Null
332
+ // when the mated joints cannot follow the path.
326
333
  const connectivityUpdatesForPath = (connectivity, path) => {
327
334
  if (!connectivity)
328
335
  return [];
329
336
  const preview = { ...duct, path };
330
- return resolveConnectivityUpdates(connectivity, preview).filter((u) => useScene.getState().nodes[u.id]);
337
+ return (resolveConnectivityUpdates(connectivity, preview)?.filter((u) => useScene.getState().nodes[u.id]) ?? null);
331
338
  };
332
339
  // A corner arrow drag: the point is locked to one axis (X / Z / Y). All the
333
340
  // rich behaviour — port-snap, elbow re-aim, connectivity follow, single-undo
@@ -342,10 +349,20 @@ const DuctPointHandles = ({ duct, target }) => {
342
349
  const livePreviewIds = new Set();
343
350
  const publishLivePreview = (updates) => {
344
351
  const scene = useScene.getState();
352
+ const overrides = useLiveNodeOverrides.getState();
345
353
  const entries = updates
346
354
  .filter((update) => scene.nodes[update.id])
347
355
  .map((update) => [update.id, update.data]);
348
- useLiveNodeOverrides.getState().setMany(entries);
356
+ const previewed = new Set(entries.map(([id]) => id));
357
+ for (const id of livePreviewIds) {
358
+ if (previewed.has(id))
359
+ continue;
360
+ overrides.clear(id);
361
+ if (scene.nodes[id])
362
+ scene.markDirty(id);
363
+ livePreviewIds.delete(id);
364
+ }
365
+ overrides.setMany(entries);
349
366
  for (const [id] of entries) {
350
367
  livePreviewIds.add(id);
351
368
  scene.markDirty(id);
@@ -363,6 +380,10 @@ const DuctPointHandles = ({ duct, target }) => {
363
380
  useViewer.getState().setInputDragging(true);
364
381
  document.body.style.cursor = kind.axis === 'y' ? 'ns-resize' : 'grabbing';
365
382
  setDraggingIndex(index);
383
+ const releaseScope = claimHandleDrag(duct.id, PATH_POINT_DRAG_LABEL, () => {
384
+ swallowNextClick();
385
+ finish(false);
386
+ });
366
387
  const isEndpoint = index === 0 || index === initialPath.length - 1;
367
388
  // Swing pivot: the across-run (side) and up / down arrows DON'T stretch the
368
389
  // run — they sweep the grabbed point around its neighbour at a fixed radius
@@ -452,6 +473,7 @@ const DuctPointHandles = ({ duct, target }) => {
452
473
  if (isEndpoint && (detached || !drag.fittingEndpoint)) {
453
474
  const port = findNearestPortXZ([next[0], next[1], next[2]], collectScenePorts({
454
475
  excludeNodeId: duct.id,
476
+ levelId: (findLevelAncestorId(duct.id, useScene.getState().nodes) ?? undefined),
455
477
  systems: DUCT_PORT_SYSTEMS,
456
478
  }), PORT_SNAP_RADIUS_M);
457
479
  if (port)
@@ -471,16 +493,10 @@ const DuctPointHandles = ({ duct, target }) => {
471
493
  triggerSFX('sfx:grid-snap');
472
494
  publishLivePreview(batch);
473
495
  };
474
- const onUp = () => {
496
+ const finish = (commit) => {
475
497
  const drag = dragRef.current;
476
498
  if (!drag)
477
499
  return;
478
- // Swallow the trailing synthetic click so it doesn't reach the
479
- // background-click deselect handler — `cleanup()` drops `inputDragging`
480
- // synchronously here, so without this the click that fires after
481
- // pointerup would land with the drag gate already down and clear the
482
- // selection. Mirrors `useHandleDrag`'s onUp.
483
- swallowNextClick();
484
500
  drag.cleanup();
485
501
  dragRef.current = null;
486
502
  setDraggingIndex(null);
@@ -491,7 +507,7 @@ const DuctPointHandles = ({ duct, target }) => {
491
507
  // detached — just the duct path).
492
508
  const detached = drag.detached;
493
509
  const moved = drag.current.some((v, axis) => v !== drag.initialPath[drag.index][axis]);
494
- const finalBatch = buildDragBatch(drag, drag.current, detached);
510
+ const finalBatch = commit ? buildDragBatch(drag, drag.current, detached) : null;
495
511
  resumeSceneHistory(useScene);
496
512
  if (moved && finalBatch) {
497
513
  // A manual corner edit invalidates any stored auto-offset base (the
@@ -509,10 +525,23 @@ const DuctPointHandles = ({ duct, target }) => {
509
525
  useScene.getState().updateNodes(finalWithTagStrip);
510
526
  }
511
527
  };
528
+ const onUp = () => {
529
+ if (!dragRef.current)
530
+ return;
531
+ // Swallow the trailing synthetic click so it doesn't reach the
532
+ // background-click deselect handler — `cleanup()` drops `inputDragging`
533
+ // synchronously here, so without this the click that fires after
534
+ // pointerup would land with the drag gate already down and clear the
535
+ // selection. Mirrors `useHandleDrag`'s onUp.
536
+ swallowNextClick();
537
+ finish(true);
538
+ };
539
+ const onCancel = () => finish(false);
512
540
  const cleanup = () => {
513
541
  window.removeEventListener('pointermove', onMove);
514
542
  window.removeEventListener('pointerup', onUp);
515
- window.removeEventListener('pointercancel', onUp);
543
+ window.removeEventListener('pointercancel', onCancel);
544
+ releaseScope();
516
545
  useViewer.getState().setInputDragging(false);
517
546
  document.body.style.cursor = '';
518
547
  };
@@ -530,7 +559,7 @@ const DuctPointHandles = ({ duct, target }) => {
530
559
  };
531
560
  window.addEventListener('pointermove', onMove);
532
561
  window.addEventListener('pointerup', onUp);
533
- window.addEventListener('pointercancel', onUp);
562
+ window.addEventListener('pointercancel', onCancel);
534
563
  };
535
564
  // Roll: spin the rect / oval cross-section about the run (length) axis. The
536
565
  // cursor's bearing in the plane perpendicular to the run direction (taken in
@@ -572,6 +601,10 @@ const DuctPointHandles = ({ duct, target }) => {
572
601
  useViewer.getState().setInputDragging(true);
573
602
  document.body.style.cursor = 'grabbing';
574
603
  setRolling(true);
604
+ const releaseScope = claimHandleDrag(duct.id, ROTATE_HANDLE_DRAG_LABEL, () => {
605
+ swallowNextClick();
606
+ finish(false);
607
+ });
575
608
  let current = startRoll;
576
609
  let lastStep = Number.NaN;
577
610
  const onMove = (event) => {
@@ -580,15 +613,16 @@ const DuctPointHandles = ({ duct, target }) => {
580
613
  const b = bearing(event.clientX, event.clientY);
581
614
  if (b === null)
582
615
  return;
583
- // Snap the roll to 45° steps only in the active angle mode.
616
+ // Snap the roll to 45° steps only in the active angle mode; held Alt rolls freely.
584
617
  const raw = b - startBearing;
585
- const delta = isAngleSnapActive() ? Math.round(raw / ROLL_STEP_RAD) * ROLL_STEP_RAD : raw;
618
+ const snapped = !event.altKey && isAngleSnapActive();
619
+ const delta = snapped ? Math.round(raw / ROLL_STEP_RAD) * ROLL_STEP_RAD : raw;
586
620
  const next = startRoll + delta;
587
621
  if (next === current)
588
622
  return;
589
623
  current = next;
590
624
  // Tick the rotate SFX each time a fresh snapped step is crossed.
591
- if (isAngleSnapActive()) {
625
+ if (snapped) {
592
626
  const step = Math.round(raw / ROLL_STEP_RAD);
593
627
  if (step !== lastStep) {
594
628
  lastStep = step;
@@ -598,11 +632,11 @@ const DuctPointHandles = ({ duct, target }) => {
598
632
  useLiveNodeOverrides.getState().set(duct.id, { roll: next });
599
633
  useScene.getState().markDirty(duct.id);
600
634
  };
601
- const onUp = () => {
602
- swallowNextClick();
635
+ const finish = (commit) => {
603
636
  window.removeEventListener('pointermove', onMove);
604
637
  window.removeEventListener('pointerup', onUp);
605
- window.removeEventListener('pointercancel', onUp);
638
+ window.removeEventListener('pointercancel', onCancel);
639
+ releaseScope();
606
640
  useViewer.getState().setInputDragging(false);
607
641
  clearPlacementSurface();
608
642
  document.body.style.cursor = '';
@@ -610,16 +644,21 @@ const DuctPointHandles = ({ duct, target }) => {
610
644
  useLiveNodeOverrides.getState().clear(duct.id);
611
645
  useScene.getState().markDirty(duct.id);
612
646
  resumeSceneHistory(useScene);
613
- if (current !== startRoll) {
647
+ if (commit && current !== startRoll) {
614
648
  useScene.getState().updateNode(duct.id, {
615
649
  roll: current,
616
650
  ...(readAutoOffsetTag(duct) ? { metadata: withoutAutoOffsetTag(duct.metadata) } : {}),
617
651
  });
618
652
  }
619
653
  };
654
+ const onUp = () => {
655
+ swallowNextClick();
656
+ finish(true);
657
+ };
658
+ const onCancel = () => finish(false);
620
659
  window.addEventListener('pointermove', onMove);
621
660
  window.addEventListener('pointerup', onUp);
622
- window.addEventListener('pointercancel', onUp);
661
+ window.addEventListener('pointercancel', onCancel);
623
662
  };
624
663
  // Move the WHOLE run, locked to one direction: the vertical world axis, or a
625
664
  // run-relative horizontal line (node-local XZ unit dir) so the along-/across-
@@ -755,10 +794,14 @@ const DuctPointHandles = ({ duct, target }) => {
755
794
  useViewer.getState().setInputDragging(true);
756
795
  document.body.style.cursor = kind.axis === 'y' ? 'ns-resize' : 'grabbing';
757
796
  setRunMoving(true);
797
+ const releaseScope = claimHandleDrag(duct.id, AXIS_MOVE_DRAG_LABEL, () => {
798
+ swallowNextClick();
799
+ finish(false);
800
+ });
758
801
  let delta = 0;
759
802
  // Last frame's offset outcome (vertical move only): a valid plan to mint on
760
803
  // release, an invalid marker (preview-only, snap back), or null for a plain
761
- // translate. `onUp` reads it to decide create vs. translate vs. nothing.
804
+ // translate. `finish` reads it to decide create vs. translate vs. nothing.
762
805
  let offsetResult = null;
763
806
  // Shift the LOGICAL L: vertical adds the carried `baseDy` plus this drag's
764
807
  // delta (so a re-drag accumulates from the L, not the lifted Z); horizontal
@@ -774,10 +817,10 @@ const DuctPointHandles = ({ duct, target }) => {
774
817
  }
775
818
  return next;
776
819
  });
777
- const batchFor = (path) => [
778
- { id: duct.id, data: { path } },
779
- ...connectivityUpdatesForPath(connectivity, path),
780
- ];
820
+ const batchFor = (path) => {
821
+ const followers = connectivityUpdatesForPath(connectivity, path);
822
+ return followers && [{ id: duct.id, data: { path } }, ...followers];
823
+ };
781
824
  // Patches restoring every connected partner to its post-rewind (logical-L)
782
825
  // pose — runs by path, fittings by position (+ a re-aimed elbow's rotation /
783
826
  // angle). Used to FREEZE partners on an invalid frame.
@@ -878,30 +921,37 @@ const DuctPointHandles = ({ duct, target }) => {
878
921
  const s = sample(event.clientX, event.clientY);
879
922
  if (s === null)
880
923
  return;
881
- const step = isGridSnapActive() ? useEditor.getState().gridSnapStep : 0;
924
+ const step = !event.altKey && isGridSnapActive() ? useEditor.getState().gridSnapStep : 0;
882
925
  const next = snap(s - startSample, step);
883
926
  if (next === delta)
884
927
  return;
885
- delta = next;
886
- if (step > 0)
887
- triggerSFX('sfx:grid-snap');
888
928
  const dyEff = baseDy + next;
889
929
  // Vertical move: connected ends stay welded to their (stationary)
890
930
  // partner via an auto-routed elbow → riser → elbow offset, planned from
891
931
  // the LOGICAL L by the accumulated lift. The planner returns valid (offset
892
932
  // fits), invalid (connected but no clean offset at this height), or null
893
933
  // (no connections, or dyEff 0 → back at the L → plain translate).
894
- offsetResult =
895
- isVertical && dyEff !== 0
896
- ? planVerticalOffsets({
897
- duct: logicalDuct,
898
- dy: dyEff,
899
- profile,
900
- connections: connectivity?.connections ?? [],
901
- scenePorts,
902
- nodesById,
903
- })
904
- : null;
934
+ const result = isVertical && dyEff !== 0
935
+ ? planVerticalOffsets({
936
+ duct: logicalDuct,
937
+ dy: dyEff,
938
+ profile,
939
+ connections: connectivity?.connections ?? [],
940
+ scenePorts,
941
+ nodesById,
942
+ })
943
+ : null;
944
+ const followUpdates = result?.status === 'invalid'
945
+ ? []
946
+ : connectivityUpdatesForPath(connectivity, result?.status === 'valid' ? result.plan.followPath : shiftedPath(next));
947
+ // Joints that cannot follow hold the last shown frame, which is what
948
+ // release commits.
949
+ if (!followUpdates)
950
+ return;
951
+ delta = next;
952
+ offsetResult = result;
953
+ if (step > 0)
954
+ triggerSFX('sfx:grid-snap');
905
955
  if (offsetResult?.status === 'valid') {
906
956
  applyLogicalBasePreview();
907
957
  // Lift the run to the offset path; trim run-offset partners back one
@@ -913,7 +963,6 @@ const DuctPointHandles = ({ duct, target }) => {
913
963
  const scene = useScene.getState();
914
964
  const deletePreview = (plan.delete ?? []).filter((id) => scene.nodes[id]);
915
965
  setPreviewHidden([...mintedIds, ...deletePreview]);
916
- const followUpdates = connectivityUpdatesForPath(connectivity, plan.followPath);
917
966
  const updates = [
918
967
  { id: duct.id, data: { path: plan.ductPath } },
919
968
  ...plan.updates.filter((u) => scene.nodes[u.id]),
@@ -941,15 +990,17 @@ const DuctPointHandles = ({ duct, target }) => {
941
990
  else {
942
991
  applyLogicalBasePreview();
943
992
  setVerticalGhost(null);
944
- const updates = batchFor(shiftedPath(next));
945
- publishLivePreview(updates);
993
+ publishLivePreview([
994
+ { id: duct.id, data: { path: shiftedPath(next) } },
995
+ ...followUpdates,
996
+ ]);
946
997
  }
947
998
  };
948
- const onUp = () => {
949
- swallowNextClick();
999
+ const finish = (commit) => {
950
1000
  window.removeEventListener('pointermove', onMove);
951
1001
  window.removeEventListener('pointerup', onUp);
952
- window.removeEventListener('pointercancel', onUp);
1002
+ window.removeEventListener('pointercancel', onCancel);
1003
+ releaseScope();
953
1004
  useViewer.getState().setInputDragging(false);
954
1005
  document.body.style.cursor = '';
955
1006
  setRunMoving(false);
@@ -957,7 +1008,7 @@ const DuctPointHandles = ({ duct, target }) => {
957
1008
  clearLivePreview();
958
1009
  setPreviewHidden([]);
959
1010
  resumeSceneHistory(useScene);
960
- if (delta === 0)
1011
+ if (!commit || delta === 0)
961
1012
  return;
962
1013
  const dyEff = baseDy + delta;
963
1014
  const result = offsetResult;
@@ -983,6 +1034,8 @@ const DuctPointHandles = ({ duct, target }) => {
983
1034
  base,
984
1035
  };
985
1036
  const followUpdates = connectivityUpdatesForPath(connectivity, plan.followPath);
1037
+ if (!followUpdates)
1038
+ return;
986
1039
  const updates = [
987
1040
  {
988
1041
  id: duct.id,
@@ -1068,6 +1121,8 @@ const DuctPointHandles = ({ duct, target }) => {
1068
1121
  return;
1069
1122
  }
1070
1123
  const updates = batchFor(finalPath);
1124
+ if (!updates)
1125
+ return;
1071
1126
  if (isVertical && existingTag) {
1072
1127
  updates[0] = {
1073
1128
  ...updates[0],
@@ -1095,9 +1150,14 @@ const DuctPointHandles = ({ duct, target }) => {
1095
1150
  ensureSceneObjectsVisible(updates.map((update) => update.id));
1096
1151
  }
1097
1152
  };
1153
+ const onUp = () => {
1154
+ swallowNextClick();
1155
+ finish(true);
1156
+ };
1157
+ const onCancel = () => finish(false);
1098
1158
  window.addEventListener('pointermove', onMove);
1099
1159
  window.addEventListener('pointerup', onUp);
1100
- window.addEventListener('pointercancel', onUp);
1160
+ window.addEventListener('pointercancel', onCancel);
1101
1161
  };
1102
1162
  const cornerArrows = useMemo(() => getCornerArrows(displayDuct), [displayDuct]);
1103
1163
  const rollGizmo = useMemo(() => (displayDuct.shape === 'round' ? null : runAxisAndCenter(displayDuct)), [displayDuct]);
@@ -1 +1 @@
1
- {"version":3,"file":"tool.d.ts","sourceRoot":"","sources":["../../src/duct-segment/tool.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,OAAO,EAAE,KAAK,eAAe,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAA;AAQtF,OAAO,EAOL,KAAK,UAAU,EACf,KAAK,gBAAgB,EACrB,KAAK,SAAS,EAGf,MAAM,iCAAiC,CAAA;AA+JxC,qEAAqE;AACrE,KAAK,YAAY,GAAG;IAClB,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,CAAA;IAChC,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;CACf,CAAA;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,YAAY,EAAE,IAAI,UAAQ,GAAG,MAAM,CAUjF;AAgDD;;;;;6BAK6B;AAC7B,KAAK,YAAY,GAAG;IAClB,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAA;IAChC,QAAQ,EAAE,eAAe,EAAE,CAAA;IAC3B,KAAK,EAAE,eAAe,EAAE,CAAA;IACxB,KAAK,EAAE,eAAe,EAAE,CAAA;IACxB,OAAO,EAAE;QAAE,EAAE,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;QAAC,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,CAAA;KAAE,EAAE,CAAA;IACxD,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,EAAE,CAAA;CACxB,CAAA;AA4CD;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAC1B,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAC/B,GAAG,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAC7B,SAAS,EAAE,SAAS,GAAG,IAAI,EAC3B,SAAS,EAAE,UAAU,GAAG,IAAI,EAC5B,OAAO,EAAE,SAAS,GAAG,IAAI,EACzB,OAAO,EAAE,UAAU,GAAG,IAAI,EAC1B,OAAO,EAAE,YAAY,EACrB,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EACxC,OAAO,CAAC,EAAE,gBAAgB,GAAG,IAAI,EACjC,WAAW,UAAQ,EACnB,YAAY,GAAE,OAAO,CAAC,eAAe,CAAM,EAC3C,WAAW,GAAE,QAAQ,GAAG,QAAmB,GAC1C,YAAY,GAAG,IAAI,CAwLrB;AAED,QAAA,MAAM,eAAe,0CAuRpB,CAAA;eAEc,eAAe"}
1
+ {"version":3,"file":"tool.d.ts","sourceRoot":"","sources":["../../src/duct-segment/tool.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,OAAO,EAAE,KAAK,eAAe,EAAE,eAAe,EAAgB,MAAM,kBAAkB,CAAA;AAQpG,OAAO,EAOL,KAAK,UAAU,EACf,KAAK,gBAAgB,EACrB,KAAK,SAAS,EAGf,MAAM,iCAAiC,CAAA;AAiKxC,qEAAqE;AACrE,KAAK,YAAY,GAAG;IAClB,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,CAAA;IAChC,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;CACf,CAAA;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,YAAY,EAAE,IAAI,UAAQ,GAAG,MAAM,CAUjF;AAgDD;;;;;6BAK6B;AAC7B,KAAK,YAAY,GAAG;IAClB,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAA;IAChC,QAAQ,EAAE,eAAe,EAAE,CAAA;IAC3B,KAAK,EAAE,eAAe,EAAE,CAAA;IACxB,KAAK,EAAE,eAAe,EAAE,CAAA;IACxB,OAAO,EAAE;QAAE,EAAE,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;QAAC,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,CAAA;KAAE,EAAE,CAAA;IACxD,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,EAAE,CAAA;CACxB,CAAA;AA4CD;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAC1B,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAC/B,GAAG,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAC7B,SAAS,EAAE,SAAS,GAAG,IAAI,EAC3B,SAAS,EAAE,UAAU,GAAG,IAAI,EAC5B,OAAO,EAAE,SAAS,GAAG,IAAI,EACzB,OAAO,EAAE,UAAU,GAAG,IAAI,EAC1B,OAAO,EAAE,YAAY,EACrB,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EACxC,OAAO,CAAC,EAAE,gBAAgB,GAAG,IAAI,EACjC,WAAW,UAAQ,EACnB,YAAY,GAAE,OAAO,CAAC,eAAe,CAAM,EAC3C,WAAW,GAAE,QAAQ,GAAG,QAAmB,GAC1C,YAAY,GAAG,IAAI,CAsNrB;AAED,QAAA,MAAM,eAAe,0CA6VpB,CAAA;eAEc,eAAe"}
@@ -1,9 +1,9 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- import { DuctSegmentNode } from '@pascal-app/core';
3
+ import { DuctSegmentNode, nodeRegistry } from '@pascal-app/core';
4
4
  import { EDITOR_LAYER, triggerSFX, useEditor, usePathDraftPreview, useRegistryToolContext, } from '@pascal-app/editor';
5
5
  import { collectScenePorts, createRunWallAttachment, DistributionRunCursor, runDistanceSquared as dist2, findNearestRunBody3D, findRunBodyCrossingSurface, stepNominalRunSize, useDistributionRunTool, } from '@pascal-app/editor/distribution';
6
- import { useEffect, useMemo, useRef, useState } from 'react';
6
+ import { useEffect, useMemo, useRef } from 'react';
7
7
  import { Euler, Vector3 } from 'three';
8
8
  import { getDuctFittingPorts } from '../duct-fitting/ports.js';
9
9
  import { planCrossAtRunBody, planElbowAtPort, planElbowRealign, planTeeAtRunBody, } from '../shared/auto-fitting.js';
@@ -16,9 +16,11 @@ import { DuctSegmentGhost, FittingGhost } from '../shared/mep-ghost.js';
16
16
  import { DUCT_PORT_SYSTEMS, runSectionHalfSizeM } from '../shared/port-systems.js';
17
17
  import { RunHangerPreview } from '../shared/run-hanger-controls.js';
18
18
  import { useRunHangerMode } from '../shared/run-hanger-mode.js';
19
- import { currentDuctContinuationSeed, ductEndpointPort } from './continuation.js';
19
+ import { clearRunContinuation, updateRunDefaults } from '../shared/run-tool-options.js';
20
+ import { currentDuctContinuationSeed } from './continuation.js';
21
+ import { ductEndpointPort } from './continuation-handle.js';
20
22
  import { ductSegmentDefinition } from './definition.js';
21
- import { rectSectionAxes, rollToContinueAcrossElbow } from './geometry.js';
23
+ import { rectSectionAxes, rollToContinueAcrossElbow } from './profile.js';
22
24
  /**
23
25
  * Continuous placement tool for duct segments.
24
26
  *
@@ -245,6 +247,30 @@ export function planDuctDraw(start, end, startPort, startBody, endPort, endBody,
245
247
  updates: [],
246
248
  delete: [],
247
249
  });
250
+ const system = toolDefaults.system ?? startPort?.system ?? endPort?.system ?? 'supply';
251
+ for (const [port, away] of [
252
+ [startPort, dir],
253
+ [endPort, [-dir[0], -dir[1], -dir[2]]],
254
+ ]) {
255
+ if (!port)
256
+ continue;
257
+ const owner = nodes[port.nodeId];
258
+ if (!owner || owner.type === 'duct-segment' || owner.type === 'duct-fitting')
259
+ continue;
260
+ const occupied = Object.values(nodes).some((node) => node.id !== owner.id &&
261
+ node.parentId === owner.parentId &&
262
+ (nodeRegistry.get(node.type)?.ports?.(node) ?? []).some((other) => other.system === port.system &&
263
+ dist2([...other.position], [...port.position]) < 0.005 ** 2));
264
+ const message = port.system !== system
265
+ ? 'Use the same supply or return system as the collar.'
266
+ : occupied
267
+ ? 'This collar is already connected.'
268
+ : new Vector3(...away).dot(new Vector3(...port.direction).normalize()) < 0.9999
269
+ ? 'Draw the first section straight out of the collar, then add a bend from the new duct endpoint.'
270
+ : null;
271
+ if (message)
272
+ return { ...invalidPlan(), validationMessage: message };
273
+ }
248
274
  if (startPlan?.hasClearance === false || endPlan?.hasClearance === false)
249
275
  return invalidPlan();
250
276
  const startRealign = startPlan ? null : realignPlanFor(startPort, dir, nodes);
@@ -306,7 +332,7 @@ export function planDuctDraw(start, end, startPort, startBody, endPort, endBody,
306
332
  if (!endTee && endTeePlan)
307
333
  ductEnd = endRealign?.collarPoint ?? end;
308
334
  const realigns = [startRealign, endRealign].filter((p) => p !== null);
309
- const crossHit = surface
335
+ const crossHit = surface && toolDefaults.crossingMode !== 'cross'
310
336
  ? findRunBodyCrossingSurface(start, end, BODY_SNAP_RADIUS_M, surface, {
311
337
  kinds: ['duct-segment'],
312
338
  })
@@ -336,6 +362,7 @@ export function planDuctDraw(start, end, startPort, startBody, endPort, endBody,
336
362
  const makeDuct = (from, to) => DuctSegmentNode.parse({
337
363
  ...defaults,
338
364
  ...toolDefaults,
365
+ system,
339
366
  autoHangers,
340
367
  hangerStyle,
341
368
  name: profile.shape === 'rect' ? 'Trunk' : 'Duct run',
@@ -406,27 +433,47 @@ const DuctSegmentTool = () => {
406
433
  const autoHangersRef = useRef(autoHangers);
407
434
  autoHangersRef.current = autoHangers;
408
435
  const pendingPromotionRef = useRef(continuationSeed?.promotedFitting ?? null);
409
- const [profile, setProfile] = useState(() => {
410
- const defaults = ductSegmentDefinition.defaults();
411
- const seeded = useEditor.getState().toolDefaults['duct-segment'];
412
- return {
413
- shape: continuationSeed?.duct.shape ?? seeded?.shape ?? defaults.shape,
414
- diameter: continuationSeed?.duct.diameter ?? seeded?.diameter ?? defaults.diameter,
415
- width: continuationSeed?.duct.width ?? seeded?.width ?? defaults.width,
416
- height: continuationSeed?.duct.height ?? seeded?.height ?? defaults.height,
417
- };
418
- });
436
+ const initialProfile = useRef(null);
437
+ if (!initialProfile.current)
438
+ initialProfile.current = (() => {
439
+ const defaults = ductSegmentDefinition.defaults();
440
+ const seeded = useEditor.getState().toolDefaults['duct-segment'];
441
+ return {
442
+ shape: continuationSeed?.duct.shape ?? seeded?.shape ?? defaults.shape,
443
+ diameter: continuationSeed?.duct.diameter ?? seeded?.diameter ?? defaults.diameter,
444
+ width: continuationSeed?.duct.width ?? seeded?.width ?? defaults.width,
445
+ height: continuationSeed?.duct.height ?? seeded?.height ?? defaults.height,
446
+ };
447
+ })();
448
+ const profile = useMemo(() => ({
449
+ shape: toolDefaults?.shape ?? initialProfile.current.shape,
450
+ diameter: toolDefaults?.diameter ?? initialProfile.current.diameter,
451
+ width: toolDefaults?.width ?? initialProfile.current.width,
452
+ height: toolDefaults?.height ?? initialProfile.current.height,
453
+ }), [toolDefaults?.shape, toolDefaults?.diameter, toolDefaults?.width, toolDefaults?.height]);
454
+ const setProfile = (value) => updateRunDefaults('duct-segment', typeof value === 'function' ? value(profile) : value);
419
455
  const profileRef = useRef(profile);
420
456
  profileRef.current = profile;
421
457
  useEffect(() => {
422
458
  const mode = useRunHangerMode.getState();
423
459
  mode.setEnabled('duct-segment', initialAutoHangersRef.current);
424
- return () => mode.setEnabled('duct-segment', false);
460
+ return () => {
461
+ updateRunDefaults('duct-segment', {
462
+ autoHangers: useRunHangerMode.getState().enabled['duct-segment'],
463
+ });
464
+ mode.setEnabled('duct-segment', false);
465
+ };
425
466
  }, []);
426
467
  const run = useDistributionRunTool({
427
468
  active: !!activeLevelId,
428
469
  levelId: activeLevelId,
429
470
  toolName: 'duct-segment',
471
+ routingMode: hangerDefaults?.routingMode === 'horizontal' || hangerDefaults?.routingMode === 'vertical'
472
+ ? hangerDefaults.routingMode
473
+ : 'surface',
474
+ elevation: typeof hangerDefaults?.elevation === 'number' ? hangerDefaults.elevation : 0,
475
+ targetElevation: typeof hangerDefaults?.targetElevation === 'number' ? hangerDefaults.targetElevation : 3,
476
+ connectCrossings: hangerDefaults?.crossingMode !== 'cross',
430
477
  initialStart: continuationSeed
431
478
  ? [...(continuationSeed.port?.position ?? continuationSeed.body?.point ?? [0, 0, 0])]
432
479
  : null,
@@ -440,6 +487,15 @@ const DuctSegmentTool = () => {
440
487
  }),
441
488
  surfaceClearance: (surface) => surface ? ductSurfaceClearanceM(profileRef.current, surface.kind === 'wall') : 0,
442
489
  minimumSegmentLength: 0.08,
490
+ resolveFreeEnd: (start, end, connection) => {
491
+ const port = connection.port;
492
+ const owner = port ? sceneApi.get(port.nodeId) : null;
493
+ if (!port || !owner || owner.type === 'duct-segment' || owner.type === 'duct-fitting')
494
+ return end;
495
+ const axis = new Vector3(...port.direction).normalize();
496
+ const distance = Math.max(0, new Vector3(...end).sub(new Vector3(...start)).dot(axis));
497
+ return new Vector3(...start).addScaledVector(axis, distance).toArray();
498
+ },
443
499
  inheritFromConnection: ({ port }) => {
444
500
  if (!port)
445
501
  return;
@@ -493,6 +549,14 @@ const DuctSegmentTool = () => {
493
549
  delete: plan.delete,
494
550
  });
495
551
  pendingPromotionRef.current = null;
552
+ const startOwner = startConnection.port && !promotedFitting ? sceneApi.get(startConnection.port.nodeId) : null;
553
+ // A riser out of a fixed collar reaches the target; staying vertical would aim the
554
+ // next section at the riser's own top.
555
+ if (hangerDefaults?.routingMode === 'vertical' &&
556
+ startOwner &&
557
+ startOwner.type !== 'duct-segment' &&
558
+ startOwner.type !== 'duct-fitting')
559
+ updateRunDefaults('duct-segment', { routingMode: 'horizontal' });
496
560
  const nextDuct = plan.ducts.at(-1);
497
561
  const nextStart = nextDuct ? nextDuct.path[nextDuct.path.length - 1] : end;
498
562
  const nextPort = nextDuct ? ductEndpointPort(nextDuct, 'end') : endConnection.port;
@@ -529,15 +593,8 @@ const DuctSegmentTool = () => {
529
593
  },
530
594
  });
531
595
  useEffect(() => {
532
- if (!toolDefaults)
533
- return;
534
- setProfile((current) => ({
535
- shape: toolDefaults.shape ?? current.shape,
536
- diameter: toolDefaults.diameter ?? current.diameter,
537
- width: toolDefaults.width ?? current.width,
538
- height: toolDefaults.height ?? current.height,
539
- }));
540
- }, [toolDefaults]);
596
+ updateRunDefaults('duct-segment', initialProfile.current);
597
+ }, []);
541
598
  const previewPlan = useMemo(() => {
542
599
  if (!(activeLevelId && run.start && run.cursor))
543
600
  return null;
@@ -555,6 +612,11 @@ const DuctSegmentTool = () => {
555
612
  run.surfaceTarget,
556
613
  sceneApi,
557
614
  ]);
615
+ // Profile changes alter the centreline clearance even with a stationary pointer.
616
+ // biome-ignore lint/correctness/useExhaustiveDependencies: the resolver reads the profile through a ref
617
+ useEffect(() => {
618
+ run.refreshCursor();
619
+ }, [profile, run.refreshCursor]);
558
620
  const ghostFittings = useMemo(() => previewPlan?.fittings ?? [], [previewPlan]);
559
621
  useEffect(() => {
560
622
  usePathDraftPreview
@@ -562,7 +624,7 @@ const DuctSegmentTool = () => {
562
624
  .setDraft('duct-segment', run.start ? [run.start] : [], run.cursor, { ...profile, autoHangers, hangerStyle }, ghostFittings);
563
625
  }, [autoHangers, hangerStyle, ghostFittings, profile, run.cursor, run.start]);
564
626
  useEffect(() => () => usePathDraftPreview.getState().clear('duct-segment'), []);
565
- useEffect(() => () => useEditor.getState().setToolDefaults('duct-segment', null), []);
627
+ useEffect(() => () => clearRunContinuation('duct-segment'), []);
566
628
  if (!activeLevelId)
567
629
  return null;
568
630
  const extraParts = profile.shape === 'round'
@@ -571,9 +633,24 @@ const DuctSegmentTool = () => {
571
633
  { key: 'trunk-w', prefix: 'W', value: profile.width * 0.0254 },
572
634
  { key: 'trunk-h', prefix: 'H', value: profile.height * 0.0254 },
573
635
  ];
574
- return (_jsxs(LevelOffsetGroup, { children: [_jsx(ConnectionFeedback, { point: run.cursor, target: run.endConnection.port, levelId: activeLevelId, profile: {
636
+ return (_jsxs(LevelOffsetGroup, { children: [_jsx(ConnectionFeedback, { detail: ghostFittings
637
+ .filter((fitting) => ['reducer', 'transition'].includes(fitting.fittingType))
638
+ .map((fitting) => {
639
+ const size = (outlet) => {
640
+ const shape = outlet
641
+ ? (fitting.outletShape ?? fitting.shape2)
642
+ : (fitting.inletShape ?? fitting.shape);
643
+ return shape === 'round'
644
+ ? `Ø${outlet ? fitting.diameter2 : fitting.diameter} in`
645
+ : `${outlet ? fitting.width2 : fitting.width} × ${outlet ? fitting.height2 : fitting.height} in ${shape}`;
646
+ };
647
+ const ports = getDuctFittingPorts(fitting);
648
+ const length = new Vector3(...ports[0].position).distanceTo(new Vector3(...ports[1].position));
649
+ return `${size(false)} → ${size(true)} · ${length.toFixed(2)} m long`;
650
+ })
651
+ .join('; ') || undefined, point: run.cursor, target: run.endConnection.port, screen: run.snapScreen ?? run.cursorScreen, error: run.cursorScreen ? (previewPlan?.validationMessage ?? run.validationMessage) : undefined, levelId: activeLevelId, profile: {
575
652
  ...profile,
576
653
  system: String(hangerDefaults?.system ?? ductSegmentDefinition.defaults().system),
577
- } }), _jsx(DistributionRunCursor, { altActive: run.altActive, cursor: run.cursor, cursorRef: cursorRef, directionMode: run.directionMode, extraParts: extraParts, lengthInput: run.lengthInput, onLengthInputChange: run.onLengthInputChange, onDirectionSelect: run.onDirectionSelect, validationMessage: previewPlan?.validationMessage ?? run.validationMessage, snapTarget: run.snapTarget, snapScreen: run.snapScreen, start: run.start, startDirection: run.startConnection.port?.direction ?? null, unit: unit }), run.start && (_jsxs("mesh", { layers: EDITOR_LAYER, position: run.start, children: [_jsx("sphereGeometry", { args: [0.07, 16, 12] }), _jsx("meshBasicMaterial", { color: "#818cf8", depthTest: false })] })), previewPlan?.ducts.map((duct, index) => (_jsx(DuctSegmentGhost, { duct: duct }, index))), previewPlan?.ducts.map((duct, index) => (_jsx(RunHangerPreview, { run: duct, levelId: activeLevelId }, `hanger-${index}`))), ghostFittings.map((fitting) => (_jsx(FittingGhost, { fitting: fitting }, fitting.id)))] }));
654
+ } }), _jsx(DistributionRunCursor, { altActive: run.altActive, cursor: run.cursor, cursorRef: cursorRef, directionMode: run.directionMode, routingMode: run.routingMode, extraParts: extraParts, lengthInput: run.lengthInput, onLengthInputChange: run.onLengthInputChange, onDirectionSelect: run.onDirectionSelect, validationMessage: previewPlan?.validationMessage ?? run.validationMessage, snapTarget: run.snapTarget, snapScreen: run.snapScreen, start: run.start, startDirection: run.startConnection.port?.direction ?? null, unit: unit }), run.start && (_jsxs("mesh", { layers: EDITOR_LAYER, position: run.start, children: [_jsx("sphereGeometry", { args: [0.07, 16, 12] }), _jsx("meshBasicMaterial", { color: "#818cf8", depthTest: false })] })), previewPlan?.ducts.map((duct, index) => (_jsx(DuctSegmentGhost, { duct: duct }, index))), previewPlan?.ducts.map((duct, index) => (_jsx(RunHangerPreview, { run: duct, levelId: activeLevelId }, `hanger-${index}`))), ghostFittings.map((fitting) => (_jsx(FittingGhost, { fitting: fitting }, fitting.id)))] }));
578
655
  };
579
656
  export default DuctSegmentTool;