@pascal-app/nodes 1.0.0 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (439) hide show
  1. package/dist/block/definition.d.ts.map +1 -1
  2. package/dist/block/definition.js +4 -1
  3. package/dist/block/face-host.d.ts.map +1 -1
  4. package/dist/block/face-host.js +19 -2
  5. package/dist/block/hosted-edit.d.ts +13 -0
  6. package/dist/block/hosted-edit.d.ts.map +1 -0
  7. package/dist/block/hosted-edit.js +205 -0
  8. package/dist/block/last-operation.d.ts +1 -1
  9. package/dist/block/last-operation.d.ts.map +1 -1
  10. package/dist/block/last-operation.js +6 -4
  11. package/dist/block/modal-session.d.ts +2 -1
  12. package/dist/block/modal-session.d.ts.map +1 -1
  13. package/dist/block/modal-session.js +2 -2
  14. package/dist/block/selection.d.ts.map +1 -1
  15. package/dist/block/selection.js +82 -24
  16. package/dist/block/surface.d.ts +4 -0
  17. package/dist/block/surface.d.ts.map +1 -0
  18. package/dist/block/surface.js +54 -0
  19. package/dist/block/use-block-face-operation.d.ts +2 -2
  20. package/dist/block/use-block-face-operation.d.ts.map +1 -1
  21. package/dist/block/use-block-face-operation.js +25 -11
  22. package/dist/box-vent/definition.d.ts.map +1 -1
  23. package/dist/box-vent/definition.js +1 -0
  24. package/dist/box-vent/panel.js +4 -4
  25. package/dist/building/renderer.d.ts.map +1 -1
  26. package/dist/building/renderer.js +1 -1
  27. package/dist/cabinet/appliance-layout.d.ts +26 -0
  28. package/dist/cabinet/appliance-layout.d.ts.map +1 -0
  29. package/dist/cabinet/appliance-layout.js +52 -0
  30. package/dist/cabinet/countertop-layout.d.ts +173 -0
  31. package/dist/cabinet/countertop-layout.d.ts.map +1 -0
  32. package/dist/cabinet/countertop-layout.js +80 -0
  33. package/dist/cabinet/definition.d.ts.map +1 -1
  34. package/dist/cabinet/definition.js +17 -8
  35. package/dist/cabinet/geometry/cooktop.d.ts.map +1 -1
  36. package/dist/cabinet/geometry/cooktop.js +2 -2
  37. package/dist/cabinet/geometry/run.d.ts.map +1 -1
  38. package/dist/cabinet/geometry/run.js +10 -71
  39. package/dist/cabinet/geometry/sink.d.ts +2 -12
  40. package/dist/cabinet/geometry/sink.d.ts.map +1 -1
  41. package/dist/cabinet/geometry/sink.js +8 -39
  42. package/dist/cabinet/hosted-resize.d.ts +5 -0
  43. package/dist/cabinet/hosted-resize.d.ts.map +1 -0
  44. package/dist/cabinet/hosted-resize.js +14 -0
  45. package/dist/cabinet/placement-snap.d.ts.map +1 -1
  46. package/dist/cabinet/placement-snap.js +4 -2
  47. package/dist/cabinet/run-layout.d.ts +8 -1
  48. package/dist/cabinet/run-layout.d.ts.map +1 -1
  49. package/dist/cabinet/run-layout.js +22 -14
  50. package/dist/cabinet/run-ops.d.ts +3 -3
  51. package/dist/cabinet/run-ops.js +3 -3
  52. package/dist/cabinet/run-panel.d.ts +1 -1
  53. package/dist/cabinet/run-panel.d.ts.map +1 -1
  54. package/dist/cabinet/run-panel.js +16 -7
  55. package/dist/cabinet/surfaces.d.ts +5 -0
  56. package/dist/cabinet/surfaces.d.ts.map +1 -0
  57. package/dist/cabinet/surfaces.js +113 -0
  58. package/dist/cabinet/tool.d.ts.map +1 -1
  59. package/dist/cabinet/tool.js +8 -4
  60. package/dist/cabinet/tree-structure.d.ts.map +1 -1
  61. package/dist/cabinet/tree-structure.js +10 -9
  62. package/dist/ceiling/definition.d.ts.map +1 -1
  63. package/dist/ceiling/definition.js +6 -1
  64. package/dist/ceiling/floorplan-affordances.d.ts +4 -4
  65. package/dist/ceiling/panel.js +1 -1
  66. package/dist/ceiling/renderer.d.ts.map +1 -1
  67. package/dist/ceiling/renderer.js +3 -2
  68. package/dist/chimney/definition.d.ts.map +1 -1
  69. package/dist/chimney/definition.js +1 -0
  70. package/dist/chimney/panel.js +9 -9
  71. package/dist/column/definition.d.ts.map +1 -1
  72. package/dist/column/definition.js +10 -3
  73. package/dist/column/floorplan-affordances.d.ts.map +1 -1
  74. package/dist/column/floorplan-affordances.js +6 -1
  75. package/dist/column/floorplan.d.ts.map +1 -1
  76. package/dist/column/floorplan.js +23 -11
  77. package/dist/column/hosted-resize.d.ts +116 -0
  78. package/dist/column/hosted-resize.d.ts.map +1 -0
  79. package/dist/column/hosted-resize.js +9 -0
  80. package/dist/column/panel.d.ts.map +1 -1
  81. package/dist/column/panel.js +6 -3
  82. package/dist/column/renderer.d.ts.map +1 -1
  83. package/dist/column/renderer.js +25 -103
  84. package/dist/column/shape.d.ts +22 -0
  85. package/dist/column/shape.d.ts.map +1 -0
  86. package/dist/column/shape.js +120 -0
  87. package/dist/column/surface.d.ts +4 -0
  88. package/dist/column/surface.d.ts.map +1 -0
  89. package/dist/column/surface.js +66 -0
  90. package/dist/cupola/definition.d.ts.map +1 -1
  91. package/dist/cupola/definition.js +1 -0
  92. package/dist/cupola/panel.js +1 -1
  93. package/dist/door/definition.d.ts.map +1 -1
  94. package/dist/door/definition.js +40 -1
  95. package/dist/door/door-math.d.ts +1 -1
  96. package/dist/door/door-math.d.ts.map +1 -1
  97. package/dist/door/door-math.js +7 -10
  98. package/dist/door/floorplan-affordances.d.ts.map +1 -1
  99. package/dist/door/floorplan-affordances.js +8 -12
  100. package/dist/door/move-tool.d.ts.map +1 -1
  101. package/dist/door/move-tool.js +3 -4
  102. package/dist/door/panel.d.ts.map +1 -1
  103. package/dist/door/panel.js +28 -57
  104. package/dist/door/tool.d.ts.map +1 -1
  105. package/dist/door/tool.js +20 -2
  106. package/dist/dormer/definition.d.ts.map +1 -1
  107. package/dist/dormer/definition.js +1 -0
  108. package/dist/dormer/panel-position-section.js +2 -2
  109. package/dist/dormer/panel.js +1 -1
  110. package/dist/downspout/definition.d.ts.map +1 -1
  111. package/dist/downspout/definition.js +1 -0
  112. package/dist/duct-segment/parametrics.d.ts.map +1 -1
  113. package/dist/duct-segment/parametrics.js +5 -1
  114. package/dist/duct-segment/tool.d.ts +1 -0
  115. package/dist/duct-segment/tool.d.ts.map +1 -1
  116. package/dist/duct-segment/tool.js +21 -8
  117. package/dist/duct-terminal/tool.d.ts.map +1 -1
  118. package/dist/duct-terminal/tool.js +77 -8
  119. package/dist/elevator/definition.d.ts.map +1 -1
  120. package/dist/elevator/definition.js +2 -0
  121. package/dist/elevator/parametrics.d.ts.map +1 -1
  122. package/dist/elevator/parametrics.js +98 -1
  123. package/dist/eyebrow-vent/definition.d.ts.map +1 -1
  124. package/dist/eyebrow-vent/definition.js +1 -0
  125. package/dist/eyebrow-vent/panel.js +1 -1
  126. package/dist/fence/definition.d.ts.map +1 -1
  127. package/dist/fence/definition.js +1 -0
  128. package/dist/fence/inspector-editors.js +1 -1
  129. package/dist/fence/tool.js +2 -2
  130. package/dist/guide/definition.d.ts.map +1 -1
  131. package/dist/guide/definition.js +1 -0
  132. package/dist/gutter/definition.d.ts.map +1 -1
  133. package/dist/gutter/definition.js +1 -0
  134. package/dist/hvac-equipment/tool.d.ts.map +1 -1
  135. package/dist/hvac-equipment/tool.js +8 -2
  136. package/dist/imported-mesh/definition.d.ts +5 -0
  137. package/dist/imported-mesh/definition.d.ts.map +1 -0
  138. package/dist/imported-mesh/definition.js +38 -0
  139. package/dist/imported-mesh/floorplan.d.ts +4 -0
  140. package/dist/imported-mesh/floorplan.d.ts.map +1 -0
  141. package/dist/imported-mesh/floorplan.js +34 -0
  142. package/dist/imported-mesh/geometry.d.ts +5 -0
  143. package/dist/imported-mesh/geometry.d.ts.map +1 -0
  144. package/dist/imported-mesh/geometry.js +34 -0
  145. package/dist/imported-mesh/index.d.ts +4 -0
  146. package/dist/imported-mesh/index.d.ts.map +1 -0
  147. package/dist/imported-mesh/index.js +3 -0
  148. package/dist/imported-mesh/schema.d.ts +2 -0
  149. package/dist/imported-mesh/schema.d.ts.map +1 -0
  150. package/dist/imported-mesh/schema.js +1 -0
  151. package/dist/index.d.ts +2 -0
  152. package/dist/index.d.ts.map +1 -1
  153. package/dist/index.js +8 -0
  154. package/dist/item/__fixtures__/main-floorplan.d.ts +26 -0
  155. package/dist/item/__fixtures__/main-floorplan.d.ts.map +1 -0
  156. package/dist/item/__fixtures__/main-floorplan.js +297 -0
  157. package/dist/item/definition.d.ts.map +1 -1
  158. package/dist/item/definition.js +3 -1
  159. package/dist/item/floorplan-move.d.ts +9 -1
  160. package/dist/item/floorplan-move.d.ts.map +1 -1
  161. package/dist/item/floorplan-move.js +231 -99
  162. package/dist/item/floorplan.d.ts +22 -0
  163. package/dist/item/floorplan.d.ts.map +1 -1
  164. package/dist/item/floorplan.js +72 -2
  165. package/dist/item/move-tool.d.ts +1 -1
  166. package/dist/item/move-tool.d.ts.map +1 -1
  167. package/dist/item/move-tool.js +15 -7
  168. package/dist/item/panel.js +1 -1
  169. package/dist/item/renderer.d.ts.map +1 -1
  170. package/dist/item/renderer.js +8 -2
  171. package/dist/level/renderer.js +1 -1
  172. package/dist/lineset/tool.d.ts.map +1 -1
  173. package/dist/lineset/tool.js +1 -0
  174. package/dist/liquid-line/tool.d.ts.map +1 -1
  175. package/dist/liquid-line/tool.js +5 -1
  176. package/dist/measurement/definition.d.ts.map +1 -1
  177. package/dist/measurement/definition.js +1 -0
  178. package/dist/pipe-segment/parametrics.d.ts.map +1 -1
  179. package/dist/pipe-segment/parametrics.js +5 -1
  180. package/dist/pipe-segment/tool.d.ts.map +1 -1
  181. package/dist/pipe-segment/tool.js +14 -3
  182. package/dist/pipe-trap/tool.d.ts.map +1 -1
  183. package/dist/pipe-trap/tool.js +7 -8
  184. package/dist/procedural-item/definition.d.ts +4 -0
  185. package/dist/procedural-item/definition.d.ts.map +1 -0
  186. package/dist/procedural-item/definition.js +257 -0
  187. package/dist/procedural-item/geometry.d.ts +31 -0
  188. package/dist/procedural-item/geometry.d.ts.map +1 -0
  189. package/dist/procedural-item/geometry.js +88 -0
  190. package/dist/procedural-item/index.d.ts +3 -0
  191. package/dist/procedural-item/index.d.ts.map +1 -0
  192. package/dist/procedural-item/index.js +2 -0
  193. package/dist/procedural-item/move-session.d.ts +15 -0
  194. package/dist/procedural-item/move-session.d.ts.map +1 -0
  195. package/dist/procedural-item/move-session.js +197 -0
  196. package/dist/procedural-item/move-tool.d.ts +5 -0
  197. package/dist/procedural-item/move-tool.d.ts.map +1 -0
  198. package/dist/procedural-item/move-tool.js +193 -0
  199. package/dist/procedural-item/renderer.d.ts +5 -0
  200. package/dist/procedural-item/renderer.d.ts.map +1 -0
  201. package/dist/procedural-item/renderer.js +66 -0
  202. package/dist/ridge-vent/definition.d.ts.map +1 -1
  203. package/dist/ridge-vent/definition.js +1 -0
  204. package/dist/ridge-vent/panel.js +4 -4
  205. package/dist/roof/definition.d.ts.map +1 -1
  206. package/dist/roof/definition.js +4 -1
  207. package/dist/roof/panel-model.d.ts +4 -0
  208. package/dist/roof/panel-model.d.ts.map +1 -0
  209. package/dist/roof/panel-model.js +151 -0
  210. package/dist/roof/panel.d.ts.map +1 -1
  211. package/dist/roof/panel.js +9 -8
  212. package/dist/roof/parametrics.d.ts.map +1 -1
  213. package/dist/roof/parametrics.js +16 -1
  214. package/dist/roof-segment/definition.d.ts.map +1 -1
  215. package/dist/roof-segment/definition.js +1 -0
  216. package/dist/roof-segment/panel.d.ts.map +1 -1
  217. package/dist/roof-segment/panel.js +5 -5
  218. package/dist/roof-segment/parametrics.d.ts.map +1 -1
  219. package/dist/roof-segment/parametrics.js +176 -1
  220. package/dist/scan/definition.d.ts.map +1 -1
  221. package/dist/scan/definition.js +1 -0
  222. package/dist/shared/automatic-run-end-cap.d.ts +1 -0
  223. package/dist/shared/automatic-run-end-cap.d.ts.map +1 -1
  224. package/dist/shared/automatic-run-end-cap.js +10 -0
  225. package/dist/shared/commit-opening-move.d.ts +4 -0
  226. package/dist/shared/commit-opening-move.d.ts.map +1 -0
  227. package/dist/shared/commit-opening-move.js +9 -0
  228. package/dist/shared/curtain-opening-limits.d.ts +14 -0
  229. package/dist/shared/curtain-opening-limits.d.ts.map +1 -0
  230. package/dist/shared/curtain-opening-limits.js +53 -0
  231. package/dist/shared/distribution-run-tool.d.ts +10 -0
  232. package/dist/shared/distribution-run-tool.d.ts.map +1 -1
  233. package/dist/shared/distribution-run-tool.js +56 -11
  234. package/dist/shared/draft-axis-guides.d.ts +0 -6
  235. package/dist/shared/draft-axis-guides.d.ts.map +1 -1
  236. package/dist/shared/draft-axis-guides.js +1 -8
  237. package/dist/shared/hosted-resize.d.ts +12 -0
  238. package/dist/shared/hosted-resize.d.ts.map +1 -0
  239. package/dist/shared/hosted-resize.js +166 -0
  240. package/dist/shared/opening-grid-follow.d.ts +8 -0
  241. package/dist/shared/opening-grid-follow.d.ts.map +1 -0
  242. package/dist/shared/opening-grid-follow.js +12 -0
  243. package/dist/shared/opening-property-preview-host.d.ts +3 -0
  244. package/dist/shared/opening-property-preview-host.d.ts.map +1 -0
  245. package/dist/shared/opening-property-preview-host.js +21 -0
  246. package/dist/shared/opening-property-preview.d.ts +19 -0
  247. package/dist/shared/opening-property-preview.d.ts.map +1 -0
  248. package/dist/shared/opening-property-preview.js +99 -0
  249. package/dist/shared/panel-fields.d.ts +15 -0
  250. package/dist/shared/panel-fields.d.ts.map +1 -0
  251. package/dist/shared/panel-fields.js +31 -0
  252. package/dist/shared/resting-surface-plan.d.ts +4 -0
  253. package/dist/shared/resting-surface-plan.d.ts.map +1 -0
  254. package/dist/shared/resting-surface-plan.js +53 -0
  255. package/dist/shared/surface-counterparts.d.ts +12 -0
  256. package/dist/shared/surface-counterparts.d.ts.map +1 -0
  257. package/dist/shared/surface-counterparts.js +27 -0
  258. package/dist/shared/wall-attach-target.d.ts +1 -0
  259. package/dist/shared/wall-attach-target.d.ts.map +1 -1
  260. package/dist/shared/wall-attach-target.js +4 -1
  261. package/dist/shared/wall-event-from-grid.d.ts +5 -0
  262. package/dist/shared/wall-event-from-grid.d.ts.map +1 -0
  263. package/dist/shared/wall-event-from-grid.js +36 -0
  264. package/dist/shelf/definition.d.ts.map +1 -1
  265. package/dist/shelf/definition.js +5 -2
  266. package/dist/shelf/floorplan-affordances.d.ts.map +1 -1
  267. package/dist/shelf/floorplan-affordances.js +5 -3
  268. package/dist/shelf/floorplan-move.d.ts.map +1 -1
  269. package/dist/shelf/floorplan-move.js +3 -2
  270. package/dist/shelf/floorplan.d.ts.map +1 -1
  271. package/dist/shelf/floorplan.js +9 -2
  272. package/dist/shelf/geometry.d.ts.map +1 -1
  273. package/dist/shelf/geometry.js +2 -10
  274. package/dist/site/renderer.d.ts.map +1 -1
  275. package/dist/site/renderer.js +9 -2
  276. package/dist/skylight/definition.d.ts.map +1 -1
  277. package/dist/skylight/definition.js +1 -0
  278. package/dist/skylight/panel.js +6 -6
  279. package/dist/slab/definition.d.ts.map +1 -1
  280. package/dist/slab/definition.js +4 -0
  281. package/dist/slab/panel.js +1 -1
  282. package/dist/solar-panel/definition.d.ts.map +1 -1
  283. package/dist/solar-panel/definition.js +1 -0
  284. package/dist/solar-panel/panel.js +2 -2
  285. package/dist/spawn/definition.d.ts.map +1 -1
  286. package/dist/spawn/definition.js +1 -0
  287. package/dist/spawn/panel.js +1 -1
  288. package/dist/stair/definition.d.ts.map +1 -1
  289. package/dist/stair/definition.js +2 -0
  290. package/dist/stair/panel.d.ts.map +1 -1
  291. package/dist/stair/panel.js +9 -7
  292. package/dist/stair/parametrics.d.ts.map +1 -1
  293. package/dist/stair/parametrics.js +164 -1
  294. package/dist/stair-segment/definition.d.ts.map +1 -1
  295. package/dist/stair-segment/definition.js +1 -0
  296. package/dist/stair-segment/panel.js +4 -4
  297. package/dist/stair-segment/parametrics.d.ts.map +1 -1
  298. package/dist/stair-segment/parametrics.js +81 -1
  299. package/dist/turbine-vent/definition.d.ts.map +1 -1
  300. package/dist/turbine-vent/definition.js +1 -0
  301. package/dist/turbine-vent/panel.js +1 -1
  302. package/dist/unit/definition.d.ts +10 -0
  303. package/dist/unit/definition.d.ts.map +1 -0
  304. package/dist/unit/definition.js +38 -0
  305. package/dist/unit/index.d.ts +2 -0
  306. package/dist/unit/index.d.ts.map +1 -0
  307. package/dist/unit/index.js +1 -0
  308. package/dist/unit/parametrics.d.ts +3 -0
  309. package/dist/unit/parametrics.d.ts.map +1 -0
  310. package/dist/unit/parametrics.js +4 -0
  311. package/dist/unit/schema.d.ts +2 -0
  312. package/dist/unit/schema.d.ts.map +1 -0
  313. package/dist/unit/schema.js +1 -0
  314. package/dist/unit/unit-panel.d.ts +5 -0
  315. package/dist/unit/unit-panel.d.ts.map +1 -0
  316. package/dist/unit/unit-panel.js +61 -0
  317. package/dist/wall/actions.d.ts +3 -0
  318. package/dist/wall/actions.d.ts.map +1 -0
  319. package/dist/wall/actions.js +56 -0
  320. package/dist/wall/curtain-opening-frame.d.ts +14 -0
  321. package/dist/wall/curtain-opening-frame.d.ts.map +1 -0
  322. package/dist/wall/curtain-opening-frame.js +111 -0
  323. package/dist/wall/curtain-panel-highlight.d.ts +3 -0
  324. package/dist/wall/curtain-panel-highlight.d.ts.map +1 -0
  325. package/dist/wall/curtain-panel-highlight.js +113 -0
  326. package/dist/wall/curtain-wall-adapter.d.ts +3 -0
  327. package/dist/wall/curtain-wall-adapter.d.ts.map +1 -0
  328. package/dist/wall/curtain-wall-adapter.js +55 -0
  329. package/dist/wall/curtain-wall-floorplan.d.ts +3 -0
  330. package/dist/wall/curtain-wall-floorplan.d.ts.map +1 -0
  331. package/dist/wall/curtain-wall-floorplan.js +91 -0
  332. package/dist/wall/curtain-wall-geometry.d.ts +4 -0
  333. package/dist/wall/curtain-wall-geometry.d.ts.map +1 -0
  334. package/dist/wall/curtain-wall-geometry.js +226 -0
  335. package/dist/wall/curtain-wall-layout.d.ts +16 -0
  336. package/dist/wall/curtain-wall-layout.d.ts.map +1 -0
  337. package/dist/wall/curtain-wall-layout.js +176 -0
  338. package/dist/wall/curtain-wall-materials.d.ts +5 -0
  339. package/dist/wall/curtain-wall-materials.d.ts.map +1 -0
  340. package/dist/wall/curtain-wall-materials.js +55 -0
  341. package/dist/wall/curtain-wall-panel.d.ts +14 -0
  342. package/dist/wall/curtain-wall-panel.d.ts.map +1 -0
  343. package/dist/wall/curtain-wall-panel.js +167 -0
  344. package/dist/wall/curtain-wall-piece-geometry.d.ts +5 -0
  345. package/dist/wall/curtain-wall-piece-geometry.d.ts.map +1 -0
  346. package/dist/wall/curtain-wall-piece-geometry.js +220 -0
  347. package/dist/wall/curtain-wall-shadow.d.ts +4 -0
  348. package/dist/wall/curtain-wall-shadow.d.ts.map +1 -0
  349. package/dist/wall/curtain-wall-shadow.js +15 -0
  350. package/dist/wall/definition.d.ts +0 -15
  351. package/dist/wall/definition.d.ts.map +1 -1
  352. package/dist/wall/definition.js +65 -4
  353. package/dist/wall/drawing-mode.d.ts +12 -0
  354. package/dist/wall/drawing-mode.d.ts.map +1 -0
  355. package/dist/wall/drawing-mode.js +38 -0
  356. package/dist/wall/floorplan-tool.d.ts +4 -0
  357. package/dist/wall/floorplan-tool.d.ts.map +1 -0
  358. package/dist/wall/floorplan-tool.js +107 -0
  359. package/dist/wall/floorplan.d.ts.map +1 -1
  360. package/dist/wall/floorplan.js +6 -2
  361. package/dist/wall/length-patch.d.ts +3 -0
  362. package/dist/wall/length-patch.d.ts.map +1 -0
  363. package/dist/wall/length-patch.js +14 -0
  364. package/dist/wall/move-tool.d.ts.map +1 -1
  365. package/dist/wall/move-tool.js +23 -1
  366. package/dist/wall/paint.d.ts.map +1 -1
  367. package/dist/wall/paint.js +39 -4
  368. package/dist/wall/panel-model.d.ts +4 -0
  369. package/dist/wall/panel-model.d.ts.map +1 -0
  370. package/dist/wall/panel-model.js +117 -0
  371. package/dist/wall/panel.d.ts.map +1 -1
  372. package/dist/wall/panel.js +20 -24
  373. package/dist/wall/property-preview.d.ts +7 -0
  374. package/dist/wall/property-preview.d.ts.map +1 -0
  375. package/dist/wall/property-preview.js +31 -0
  376. package/dist/wall/rectangle-command.d.ts +149 -0
  377. package/dist/wall/rectangle-command.d.ts.map +1 -0
  378. package/dist/wall/rectangle-command.js +22 -0
  379. package/dist/wall/rectangle-tool.d.ts +2 -0
  380. package/dist/wall/rectangle-tool.d.ts.map +1 -0
  381. package/dist/wall/rectangle-tool.js +147 -0
  382. package/dist/wall/renderer.d.ts.map +1 -1
  383. package/dist/wall/renderer.js +7 -4
  384. package/dist/wall/slots.d.ts +2 -2
  385. package/dist/wall/slots.d.ts.map +1 -1
  386. package/dist/wall/slots.js +10 -2
  387. package/dist/wall/split-floorplan-layer.d.ts +4 -0
  388. package/dist/wall/split-floorplan-layer.d.ts.map +1 -0
  389. package/dist/wall/split-floorplan-layer.js +71 -0
  390. package/dist/wall/split-pointer.d.ts +3 -0
  391. package/dist/wall/split-pointer.d.ts.map +1 -0
  392. package/dist/wall/split-pointer.js +95 -0
  393. package/dist/wall/split-preview.d.ts +55 -0
  394. package/dist/wall/split-preview.d.ts.map +1 -0
  395. package/dist/wall/split-preview.js +106 -0
  396. package/dist/wall/split-session.d.ts +16 -0
  397. package/dist/wall/split-session.d.ts.map +1 -0
  398. package/dist/wall/split-session.js +138 -0
  399. package/dist/wall/split-store.d.ts +16 -0
  400. package/dist/wall/split-store.d.ts.map +1 -0
  401. package/dist/wall/split-store.js +6 -0
  402. package/dist/wall/split-tool.d.ts +10 -0
  403. package/dist/wall/split-tool.d.ts.map +1 -0
  404. package/dist/wall/split-tool.js +95 -0
  405. package/dist/wall/system.d.ts.map +1 -1
  406. package/dist/wall/system.js +3 -1
  407. package/dist/wall/tool.d.ts.map +1 -1
  408. package/dist/wall/tool.js +14 -6
  409. package/dist/wall/wall-batch-system.d.ts.map +1 -1
  410. package/dist/wall/wall-batch-system.js +3 -0
  411. package/dist/window/definition.d.ts.map +1 -1
  412. package/dist/window/definition.js +48 -1
  413. package/dist/window/floorplan-affordances.d.ts.map +1 -1
  414. package/dist/window/floorplan-affordances.js +8 -10
  415. package/dist/window/move-tool.d.ts.map +1 -1
  416. package/dist/window/move-tool.js +4 -6
  417. package/dist/window/panel.d.ts.map +1 -1
  418. package/dist/window/panel.js +22 -60
  419. package/dist/window/tool.d.ts.map +1 -1
  420. package/dist/window/tool.js +34 -2
  421. package/dist/window/window-math.d.ts +1 -1
  422. package/dist/window/window-math.d.ts.map +1 -1
  423. package/dist/window/window-math.js +8 -11
  424. package/dist/zone/definition.d.ts.map +1 -1
  425. package/dist/zone/definition.js +8 -1
  426. package/dist/zone/floorplan.d.ts +1 -3
  427. package/dist/zone/floorplan.d.ts.map +1 -1
  428. package/dist/zone/floorplan.js +43 -28
  429. package/dist/zone/quantities-panel.d.ts.map +1 -1
  430. package/dist/zone/quantities-panel.js +32 -44
  431. package/dist/zone/renderer.d.ts.map +1 -1
  432. package/dist/zone/renderer.js +21 -7
  433. package/dist/zone/unit-membership.d.ts +12 -0
  434. package/dist/zone/unit-membership.d.ts.map +1 -0
  435. package/dist/zone/unit-membership.js +22 -0
  436. package/package.json +15 -9
  437. package/dist/shared/opening-documentation-fields.d.ts +0 -16
  438. package/dist/shared/opening-documentation-fields.d.ts.map +0 -1
  439. package/dist/shared/opening-documentation-fields.js +0 -54
@@ -0,0 +1,31 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useEffect, useRef, useState } from 'react';
4
+ export function PanelTextField({ label, onCommit, value, }) {
5
+ const [draft, setDraft] = useState(value);
6
+ const cancelRef = useRef(false);
7
+ useEffect(() => setDraft(value), [value]);
8
+ const commit = () => {
9
+ if (cancelRef.current) {
10
+ cancelRef.current = false;
11
+ setDraft(value);
12
+ return;
13
+ }
14
+ const next = draft.trim();
15
+ if (next !== value)
16
+ onCommit(next);
17
+ else
18
+ setDraft(value);
19
+ };
20
+ return (_jsxs("label", { className: "flex h-10 items-center gap-3 rounded-lg border border-border/50 bg-[#2C2C2E] px-3 text-sm", children: [_jsx("span", { className: "shrink-0 text-muted-foreground", children: label }), _jsx("input", { className: "min-w-0 flex-1 bg-transparent text-right text-foreground outline-none selection:bg-primary/30", onBlur: commit, onChange: (event) => setDraft(event.target.value), onKeyDown: (event) => {
21
+ if (event.key === 'Enter')
22
+ event.currentTarget.blur();
23
+ if (event.key === 'Escape') {
24
+ cancelRef.current = true;
25
+ event.currentTarget.blur();
26
+ }
27
+ }, type: "text", value: draft })] }));
28
+ }
29
+ export function PanelSelect({ label, onChange, options, value, }) {
30
+ return (_jsxs("label", { className: "flex h-10 items-center justify-between gap-3 rounded-lg border border-border/50 bg-[#2C2C2E] px-3 text-sm", children: [_jsx("span", { className: "text-muted-foreground", children: label }), _jsx("select", { className: "min-w-0 rounded-md border border-border/50 bg-[#232325] px-2 py-1 text-foreground text-xs outline-none", onChange: (event) => onChange(event.target.value), value: value, children: options.map((option) => (_jsx("option", { value: option.value, children: option.label }, option.value))) })] }));
31
+ }
@@ -0,0 +1,4 @@
1
+ import { type AnyNode, type AnyNodeDefinition, type AnyNodeId } from '@pascal-app/core';
2
+ export declare const restingFloorplanAffectedIds: NonNullable<AnyNodeDefinition['floorplanAffectedIds']>;
3
+ export declare function restingNodePlanFrame(node: AnyNode, resolve: (id: AnyNodeId) => AnyNode | undefined): import("@pascal-app/core/procedural-items").Frame;
4
+ //# sourceMappingURL=resting-surface-plan.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resting-surface-plan.d.ts","sourceRoot":"","sources":["../../src/shared/resting-surface-plan.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,OAAO,EACZ,KAAK,iBAAiB,EACtB,KAAK,SAAS,EAIf,MAAM,kBAAkB,CAAA;AAOzB,eAAO,MAAM,2BAA2B,EAAE,WAAW,CACnD,iBAAiB,CAAC,sBAAsB,CAAC,CAa1C,CAAA;AAED,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,OAAO,EACb,OAAO,EAAE,CAAC,EAAE,EAAE,SAAS,KAAK,OAAO,GAAG,SAAS,qDAkChD"}
@@ -0,0 +1,53 @@
1
+ import { collectSubtree, getEffectiveNode, useLiveTransforms, } from '@pascal-app/core';
2
+ import { nodeLevelFrame } from '@pascal-app/core/procedural-items';
3
+ // Live transforms do not replace the committed snapshot; topology edits do.
4
+ const affectedIdsBySnapshot = new WeakMap();
5
+ // Hosted footprints read ancestor poses, so a host preview invalidates its descendants too.
6
+ export const restingFloorplanAffectedIds = ({ nodeId, nodes }) => {
7
+ let cached = affectedIdsBySnapshot.get(nodes);
8
+ if (!cached) {
9
+ cached = new Map();
10
+ affectedIdsBySnapshot.set(nodes, cached);
11
+ }
12
+ let ids = cached.get(nodeId);
13
+ if (!ids) {
14
+ ids = collectSubtree(nodes, nodeId)?.descendants.map((node) => node.id) ?? [];
15
+ cached.set(nodeId, ids);
16
+ }
17
+ return ids;
18
+ };
19
+ export function restingNodePlanFrame(node, resolve) {
20
+ const nodes = { [node.id]: node };
21
+ let id = node.parentId;
22
+ const visited = new Set([node.id]);
23
+ while (id && !visited.has(id)) {
24
+ visited.add(id);
25
+ const parent = resolve(id);
26
+ if (!parent)
27
+ break;
28
+ const effective = getEffectiveNode(parent);
29
+ const live = useLiveTransforms.getState().get(parent.id);
30
+ nodes[id] =
31
+ live && parent.type !== 'item' && parent.type !== 'level'
32
+ ? {
33
+ ...effective,
34
+ position: live.position,
35
+ rotation: 'rotation' in effective && typeof effective.rotation === 'number'
36
+ ? live.rotation
37
+ : [
38
+ 'rotation' in effective && Array.isArray(effective.rotation)
39
+ ? effective.rotation[0]
40
+ : 0,
41
+ live.rotation,
42
+ 'rotation' in effective && Array.isArray(effective.rotation)
43
+ ? effective.rotation[2]
44
+ : 0,
45
+ ],
46
+ }
47
+ : effective;
48
+ if (parent.type === 'level')
49
+ break;
50
+ id = parent.parentId;
51
+ }
52
+ return nodeLevelFrame(node.id, nodes);
53
+ }
@@ -0,0 +1,12 @@
1
+ import type { AnyNode, AnyNodeId } from '@pascal-app/core';
2
+ /**
3
+ * The other surface of the same room: a slab's ceiling, a ceiling's slab —
4
+ * on the same level with the same outline. The plan draws them on top of each
5
+ * other (only the slab takes a click), so deselecting one deselects both.
6
+ * Both kinds declare it as their plan `selectionCounterparts`.
7
+ */
8
+ export declare function sameOutlineSurfaceCounterparts({ node, nodes, }: {
9
+ node: AnyNode;
10
+ nodes: Readonly<Record<string, AnyNode | undefined>>;
11
+ }): AnyNodeId[];
12
+ //# sourceMappingURL=surface-counterparts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"surface-counterparts.d.ts","sourceRoot":"","sources":["../../src/shared/surface-counterparts.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAwB1D;;;;;GAKG;AACH,wBAAgB,8BAA8B,CAAC,EAC7C,IAAI,EACJ,KAAK,GACN,EAAE;IACD,IAAI,EAAE,OAAO,CAAA;IACb,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,GAAG,SAAS,CAAC,CAAC,CAAA;CACrD,GAAG,SAAS,EAAE,CAYd"}
@@ -0,0 +1,27 @@
1
+ const POINT_EPSILON = 1e-6;
2
+ function isSurface(node) {
3
+ return ((node?.type === 'slab' || node?.type === 'ceiling') &&
4
+ Array.isArray(node.polygon));
5
+ }
6
+ function samePolygon(a, b) {
7
+ return (a.length === b.length &&
8
+ a.every((point, index) => Math.abs(point[0] - b[index][0]) <= POINT_EPSILON &&
9
+ Math.abs(point[1] - b[index][1]) <= POINT_EPSILON));
10
+ }
11
+ /**
12
+ * The other surface of the same room: a slab's ceiling, a ceiling's slab —
13
+ * on the same level with the same outline. The plan draws them on top of each
14
+ * other (only the slab takes a click), so deselecting one deselects both.
15
+ * Both kinds declare it as their plan `selectionCounterparts`.
16
+ */
17
+ export function sameOutlineSurfaceCounterparts({ node, nodes, }) {
18
+ if (!isSurface(node))
19
+ return [];
20
+ const other = node.type === 'slab' ? 'ceiling' : 'slab';
21
+ return Object.values(nodes)
22
+ .filter((candidate) => isSurface(candidate) &&
23
+ candidate.type === other &&
24
+ (candidate.parentId ?? null) === (node.parentId ?? null) &&
25
+ samePolygon(candidate.polygon, node.polygon))
26
+ .map((candidate) => candidate.id);
27
+ }
@@ -54,6 +54,7 @@ export type WallPlanAttachment = Omit<WallHit, 'wall'> & {
54
54
  };
55
55
  /** Resolve a plan point against one wall, including its curved centerline. */
56
56
  export declare function resolveWallAttachmentAtPlanPoint(wall: WallNode, planPoint: readonly [number, number], maxDistance?: number): WallPlanAttachment | null;
57
+ export declare function projectPlanPointToWallLocalX(wall: WallNode, planPoint: readonly [number, number]): number;
57
58
  /**
58
59
  * Return the closest wall attachment target in plan space, including curved
59
60
  * walls. This is deliberately separate from `findClosestWallInPlan`: doors,
@@ -1 +1 @@
1
- {"version":3,"file":"wall-attach-target.d.ts","sourceRoot":"","sources":["../../src/shared/wall-attach-target.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"wall-attach-target.d.ts","sourceRoot":"","sources":["../../src/shared/wall-attach-target.ts"],"names":[],"mappings":"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"}
@@ -120,6 +120,9 @@ export function resolveWallAttachmentAtPlanPoint(wall, planPoint, maxDistance =
120
120
  itemRotation: side === 'front' ? 0 : Math.PI,
121
121
  };
122
122
  }
123
+ export function projectPlanPointToWallLocalX(wall, planPoint) {
124
+ return resolveWallAttachmentAtPlanPoint(wall, planPoint, Number.POSITIVE_INFINITY)?.localX ?? 0;
125
+ }
123
126
  /**
124
127
  * Return the closest wall attachment target in plan space, including curved
125
128
  * walls. This is deliberately separate from `findClosestWallInPlan`: doors,
@@ -240,7 +243,7 @@ export function hasWallChildOverlap(wallId, nodes, clampedX, clampedY, width, he
240
243
  if (childId === ignoreId)
241
244
  continue;
242
245
  const child = nodes[childId];
243
- if (!child)
246
+ if (!child || child.metadata.isTransient)
244
247
  continue;
245
248
  let childLeft;
246
249
  let childRight;
@@ -0,0 +1,5 @@
1
+ import { type AnyNode, type AnyNodeId, type GridEvent, type WallEvent } from '@pascal-app/core';
2
+ import { type Object3D } from 'three';
3
+ /** Canvas surface queries still reach the host when a rendered child consumes mesh events. */
4
+ export declare function wallEventFromGrid(event: GridEvent, activeLevelId: AnyNodeId | null, nodes: Record<AnyNodeId, AnyNode>, objects: ReadonlyMap<string, Object3D>): WallEvent | null;
5
+ //# sourceMappingURL=wall-event-from-grid.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wall-event-from-grid.d.ts","sourceRoot":"","sources":["../../src/shared/wall-event-from-grid.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,OAAO,EACZ,KAAK,SAAS,EACd,KAAK,SAAS,EAEd,KAAK,SAAS,EACf,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAW,KAAK,QAAQ,EAAW,MAAM,OAAO,CAAA;AAEvD,8FAA8F;AAC9F,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,SAAS,EAChB,aAAa,EAAE,SAAS,GAAG,IAAI,EAC/B,KAAK,EAAE,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,EACjC,OAAO,EAAE,WAAW,CAAC,MAAM,EAAE,QAAQ,CAAC,GACrC,SAAS,GAAG,IAAI,CA8BlB"}
@@ -0,0 +1,36 @@
1
+ import { isCurvedWall, } from '@pascal-app/core';
2
+ import { Matrix3, Vector3 } from 'three';
3
+ /** Canvas surface queries still reach the host when a rendered child consumes mesh events. */
4
+ export function wallEventFromGrid(event, activeLevelId, nodes, objects) {
5
+ if (event.surfaceHit?.kind !== 'wall' || !event.surfaceNormal)
6
+ return null;
7
+ const wall = nodes[event.surfaceHit.hostId];
8
+ if (wall?.type !== 'wall' ||
9
+ wall.visible === false ||
10
+ wall.metadata.isTransient ||
11
+ wall.parentId !== activeLevelId ||
12
+ isCurvedWall(wall))
13
+ return null;
14
+ const object = objects.get(wall.id);
15
+ const frame = event.localFrameId ? objects.get(event.localFrameId) : undefined;
16
+ if (!object || (event.localFrameId && !frame))
17
+ return null;
18
+ object.updateWorldMatrix(true, false);
19
+ frame?.updateWorldMatrix(true, false);
20
+ const normal = new Vector3(...event.surfaceNormal);
21
+ if (frame)
22
+ normal.applyNormalMatrix(new Matrix3().getNormalMatrix(frame.matrixWorld));
23
+ normal.applyNormalMatrix(new Matrix3().getNormalMatrix(object.matrixWorld.clone().invert()));
24
+ if (Math.abs(normal.z) <= 0.7)
25
+ return null;
26
+ const position = object.worldToLocal(new Vector3(...event.position));
27
+ return {
28
+ node: wall,
29
+ object,
30
+ position: event.position,
31
+ localPosition: position.toArray(),
32
+ normal: normal.toArray(),
33
+ nativeEvent: event.nativeEvent,
34
+ stopPropagation: () => { },
35
+ };
36
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"definition.d.ts","sourceRoot":"","sources":["../../src/shelf/definition.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAoB,cAAc,EAA8B,MAAM,kBAAkB,CAAA;AAQpG,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AA4HpC,eAAO,MAAM,eAAe,EAAE,cAAc,CAAC,OAAO,SAAS,CAuJ5D,CAAA"}
1
+ {"version":3,"file":"definition.d.ts","sourceRoot":"","sources":["../../src/shelf/definition.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAoB,cAAc,EAA8B,MAAM,kBAAkB,CAAA;AASpG,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AA4HpC,eAAO,MAAM,eAAe,EAAE,cAAc,CAAC,OAAO,SAAS,CAyJ5D,CAAA"}
@@ -1,3 +1,4 @@
1
+ import { restingFloorplanAffectedIds } from '../shared/resting-surface-plan';
1
2
  import { sanitizeShelfDimensions } from './dimensions';
2
3
  import { buildShelfFloorplan } from './floorplan';
3
4
  import { shelfResizeAffordance, shelfRotateAffordance } from './floorplan-affordances';
@@ -173,7 +174,7 @@ export const shelfDefinition = {
173
174
  })),
174
175
  },
175
176
  selectable: { hitVolume: 'bbox' },
176
- duplicable: true,
177
+ duplicable: { subtree: 'with-children' },
177
178
  deletable: true,
178
179
  paint: shelfPaint,
179
180
  slots: (n) => shelfSlots(n),
@@ -194,7 +195,7 @@ export const shelfDefinition = {
194
195
  // declared here so the placement coordinator's shelf strategy can
195
196
  // confirm parent-kind compatibility before reparenting.
196
197
  relations: {
197
- hosts: ['item'],
198
+ hosts: ['item', 'procedural-item'],
198
199
  cascadeDelete: 'descendants',
199
200
  },
200
201
  parametrics: shelfParametrics,
@@ -209,6 +210,7 @@ export const shelfDefinition = {
209
210
  // Boards/posts/back depend only on these fields — never on hosted
210
211
  // `children`. Lets <GeometrySystem> skip the dispose+rebuild (and the
211
212
  // pointer enter/leave churn it causes) when an item reparents onto a row.
213
+ geometryChildTypes: [],
212
214
  geometryKey: (n) => {
213
215
  const s = sanitizeShelfDimensions(n);
214
216
  return JSON.stringify([
@@ -229,6 +231,7 @@ export const shelfDefinition = {
229
231
  ]);
230
232
  },
231
233
  floorplan: buildShelfFloorplan,
234
+ floorplanAffectedIds: restingFloorplanAffectedIds,
232
235
  // 2D move handler — Path 1 in `FloorplanRegistryMoveOverlay`. Without
233
236
  // this the overlay falls through to Path 2 which stomps the SVG
234
237
  // entry's `transform` attribute (set by the floor-plan layer to
@@ -1 +1 @@
1
- {"version":3,"file":"floorplan-affordances.d.ts","sourceRoot":"","sources":["../../src/shelf/floorplan-affordances.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,mBAAmB,EACxB,KAAK,SAAS,EAGf,MAAM,kBAAkB,CAAA;AASzB,MAAM,MAAM,kBAAkB,GAAG;IAC/B,GAAG,EAAE,OAAO,GAAG,OAAO,CAAA;IAGtB,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAC3B,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,EAAE,mBAAmB,CAAC,SAAS,CAmChE,CAAA;AAED;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,qBAAqB,EAAE,mBAAmB,CAAC,SAAS,CAiChE,CAAA"}
1
+ {"version":3,"file":"floorplan-affordances.d.ts","sourceRoot":"","sources":["../../src/shelf/floorplan-affordances.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,mBAAmB,EACxB,KAAK,SAAS,EAGf,MAAM,kBAAkB,CAAA;AASzB,MAAM,MAAM,kBAAkB,GAAG;IAC/B,GAAG,EAAE,OAAO,GAAG,OAAO,CAAA;IAGtB,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAC3B,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,EAAE,mBAAmB,CAAC,SAAS,CAoChE,CAAA;AAED;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,qBAAqB,EAAE,mBAAmB,CAAC,SAAS,CAkChE,CAAA"}
@@ -1,4 +1,4 @@
1
- import { useLiveNodeOverrides, useScene, } from '@pascal-app/core';
1
+ import { cascadeDirty, createSceneApi, useLiveNodeOverrides, useScene, } from '@pascal-app/core';
2
2
  import { isAngleSnapActive } from '@pascal-app/editor';
3
3
  import { rotateAffordanceDelta } from '../shared/rotate-affordance';
4
4
  // Mirror the 3D handles in `shelf/definition.ts` so a drag can't push a
@@ -32,7 +32,8 @@ export const shelfResizeAffordance = {
32
32
  lastPatch = { depth: Math.max(MIN_SHELF_DEPTH, initialDepth + 2 * projDelta) };
33
33
  }
34
34
  useLiveNodeOverrides.getState().set(shelfId, lastPatch);
35
- useScene.getState().markDirty(shelfId);
35
+ for (const id of cascadeDirty(shelfId, { scene: createSceneApi(useScene) }))
36
+ useScene.getState().markDirty(id);
36
37
  },
37
38
  canCommit() {
38
39
  return true;
@@ -79,7 +80,8 @@ export const shelfRotateAffordance = {
79
80
  const newRotationY = initialRotationY - delta;
80
81
  lastRotation = [r[0], newRotationY, r[2]];
81
82
  useLiveNodeOverrides.getState().set(shelfId, { rotation: lastRotation });
82
- useScene.getState().markDirty(shelfId);
83
+ for (const id of cascadeDirty(shelfId, { scene: createSceneApi(useScene) }))
84
+ useScene.getState().markDirty(id);
83
85
  },
84
86
  canCommit() {
85
87
  return true;
@@ -1 +1 @@
1
- {"version":3,"file":"floorplan-move.d.ts","sourceRoot":"","sources":["../../src/shelf/floorplan-move.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,mBAAmB,EAGxB,KAAK,SAAS,EAGf,MAAM,kBAAkB,CAAA;AAYzB;;;;;;;GAOG;AACH,eAAO,MAAM,wBAAwB,EAAE,mBAAmB,CAAC,SAAS,CAqEnE,CAAA"}
1
+ {"version":3,"file":"floorplan-move.d.ts","sourceRoot":"","sources":["../../src/shelf/floorplan-move.ts"],"names":[],"mappings":"AAAA,OAAO,EAML,KAAK,mBAAmB,EAGxB,KAAK,SAAS,EAGf,MAAM,kBAAkB,CAAA;AAYzB;;;;;;;GAOG;AACH,eAAO,MAAM,wBAAwB,EAAE,mBAAmB,CAAC,SAAS,CAsEnE,CAAA"}
@@ -1,4 +1,4 @@
1
- import { collectAlignmentAnchors, movingFootprintAnchors, useLiveNodeOverrides, useScene, } from '@pascal-app/core';
1
+ import { cascadeDirty, collectAlignmentAnchors, createSceneApi, movingFootprintAnchors, useLiveNodeOverrides, useScene, } from '@pascal-app/core';
2
2
  import { applyFloorplanAlignment, getFloorStackPreviewPosition, getSegmentGridStep, isGridSnapActive, isMagneticSnapActive, triggerSFX, } from '@pascal-app/editor';
3
3
  import { createFloorplanCursorResolver } from '../shared/floorplan-cursor';
4
4
  /**
@@ -52,7 +52,8 @@ export const shelfFloorplanMoveTarget = ({ node, nodes }) => {
52
52
  });
53
53
  lastVisualPosition = visualPosition;
54
54
  useLiveNodeOverrides.getState().set(shelfId, { position: visualPosition });
55
- useScene.getState().markDirty(shelfId);
55
+ for (const id of cascadeDirty(shelfId, { scene: createSceneApi(useScene) }))
56
+ useScene.getState().markDirty(id);
56
57
  },
57
58
  canCommit() {
58
59
  const live = useScene.getState().nodes[shelfId];
@@ -1 +1 @@
1
- {"version":3,"file":"floorplan.d.ts","sourceRoot":"","sources":["../../src/shelf/floorplan.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAA;AAG1E,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AAQzC;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,SAAS,EAAE,GAAG,CAAC,EAAE,eAAe,GAAG,iBAAiB,CAmH7F"}
1
+ {"version":3,"file":"floorplan.d.ts","sourceRoot":"","sources":["../../src/shelf/floorplan.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAa,iBAAiB,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAA;AAIrF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AAQzC;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,SAAS,EAAE,GAAG,CAAC,EAAE,eAAe,GAAG,iBAAiB,CA0H7F"}
@@ -1,3 +1,4 @@
1
+ import { restingNodePlanFrame } from '../shared/resting-surface-plan';
1
2
  import { sanitizeShelfDimensions } from './dimensions';
2
3
  // Offsets for the floor-plan selection chrome. Resize chevrons sit a
3
4
  // hair off the footprint rim; the rotate-arrow corner sits a bit further
@@ -22,8 +23,14 @@ const ROTATE_ARROW_CORNER_OFFSET = 0.22;
22
23
  */
23
24
  export function buildShelfFloorplan(node, ctx) {
24
25
  const shelf = sanitizeShelfDimensions(node);
25
- const [px, , pz] = shelf.position;
26
- const ry = shelf.rotation[1] ?? 0;
26
+ const parent = shelf.parentId ? ctx?.resolve(shelf.parentId) : undefined;
27
+ const hostedFrame = ctx && parent?.type === 'procedural-item' && parent.attachments[shelf.id] !== undefined
28
+ ? restingNodePlanFrame(shelf, ctx.resolve)
29
+ : null;
30
+ const [px, , pz] = hostedFrame?.position ?? shelf.position;
31
+ const ry = hostedFrame
32
+ ? Math.atan2(hostedFrame.axes[2][0], hostedFrame.axes[2][2])
33
+ : (shelf.rotation[1] ?? 0);
27
34
  // Floor-plan plots at `-ry` so SVG's CW-with-y-down `rotate` direction
28
35
  // ends up visually matching Three.js Y-rotation (CCW from a top-down
29
36
  // view) — same `rotation` value rotates the same way in both views.
@@ -1 +1 @@
1
- {"version":3,"file":"geometry.d.ts","sourceRoot":"","sources":["../../src/shelf/geometry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,eAAe,EAA0B,MAAM,kBAAkB,CAAA;AAC/E,OAAO,EAIL,KAAK,aAAa,EAEnB,MAAM,oBAAoB,CAAA;AAC3B,OAAO,EAAe,KAAK,EAAuB,MAAM,OAAO,CAAA;AAE/D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AAuFzC,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,SAAS,EAClB,GAAG,CAAC,EAAE,eAAe,EACrB,OAAO,GAAE,aAA0B,GAClC,KAAK,CAkCP;AAySD;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,EAAE,CAM3D"}
1
+ {"version":3,"file":"geometry.d.ts","sourceRoot":"","sources":["../../src/shelf/geometry.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,eAAe,EAGrB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAIL,KAAK,aAAa,EAEnB,MAAM,oBAAoB,CAAA;AAC3B,OAAO,EAAe,KAAK,EAAuB,MAAM,OAAO,CAAA;AAE/D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AA0EzC,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,SAAS,EAClB,GAAG,CAAC,EAAE,eAAe,EACrB,OAAO,GAAE,aAA0B,GAClC,KAAK,CAkCP;AAySD;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,EAAE,CAM3D"}
@@ -1,4 +1,4 @@
1
- import { getMaterialPresetByRef } from '@pascal-app/core';
1
+ import { SHELF_BOARD_INSET as BOARD_INSET, getMaterialPresetByRef, shelfBoardDimensions, } from '@pascal-app/core';
2
2
  import { applyMaterialPresetToMaterials, createDefaultMaterial, createMaterial, resolveMaterialRef, } from '@pascal-app/viewer';
3
3
  import { BoxGeometry, Group, Mesh } from 'three';
4
4
  import { sanitizeShelfDimensions } from './dimensions';
@@ -27,14 +27,6 @@ function stampShelfSlot(mesh, slotId) {
27
27
  mesh.userData.slotId = slotId;
28
28
  return mesh;
29
29
  }
30
- // A board's front/back faces land on the frame's outer faces (posts / back panel)
31
- // — coplanar surfaces the depth buffer can't separate, which flickers as z-fighting.
32
- // Recess 1mm so the board sits just inside: the meshes still overlap (no gap), but
33
- // no faces are coplanar. Depth is always recessed (boards reach into the back panel
34
- // / posts). Width is recessed only at call sites where boards span OVER posts
35
- // (open-rack / no-sides bookshelf); boards that ABUT side panels keep full width so
36
- // they meet the sides flush — abutting faces are back-to-back and never fight.
37
- const BOARD_INSET = 0.001;
38
30
  // Frame members that pass under the top board (dividers / back / corner posts) reach
39
31
  // y=unitHeight, coplanar with the top board's top face → z-fighting. Drop their top 1mm so
40
32
  // the board cleanly caps them; their bottom stays on the floor.
@@ -44,7 +36,7 @@ function cappedFrameY(unitHeight) {
44
36
  return { height, centerY: height / 2 };
45
37
  }
46
38
  function boardGeometry(width, thickness, depth, insetWidth = false) {
47
- return new BoxGeometry(insetWidth ? Math.max(width - 2 * BOARD_INSET, 0.001) : width, thickness, Math.max(depth - 2 * BOARD_INSET, 0.001));
39
+ return new BoxGeometry(...shelfBoardDimensions(width, thickness, depth, insetWidth));
48
40
  }
49
41
  export function buildShelfGeometry(rawNode, ctx, shading = 'rendered') {
50
42
  const node = sanitizeShelfDimensions(rawNode);
@@ -1 +1 @@
1
- {"version":3,"file":"renderer.d.ts","sourceRoot":"","sources":["../../src/site/renderer.tsx"],"names":[],"mappings":"AAEA,OAAO,EAEL,KAAK,QAAQ,EAQd,MAAM,kBAAkB,CAAA;AA6HzB,eAAO,MAAM,YAAY,GAAI,UAAU;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,uCAmSxD,CAAA;AAED,eAAe,YAAY,CAAA"}
1
+ {"version":3,"file":"renderer.d.ts","sourceRoot":"","sources":["../../src/site/renderer.tsx"],"names":[],"mappings":"AAEA,OAAO,EAEL,KAAK,QAAQ,EAQd,MAAM,kBAAkB,CAAA;AA8HzB,eAAO,MAAM,YAAY,GAAI,UAAU;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,uCA6SxD,CAAA;AAED,eAAe,YAAY,CAAA"}
@@ -1,7 +1,7 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { terrainFieldOf, unionPolygons, useLiveNodeOverrides, useLiveTerrain, useRegistry, useScene, } from '@pascal-app/core';
4
- import { backdropGradient, deepSkyColor, getSceneTheme, horizonHazeColor, NodeRenderer, useNodeEvents, useSceneAtmosphere, useSceneGroundReplacement, useViewer, } from '@pascal-app/viewer';
4
+ import { backdropGradient, deepSkyColor, getSceneTheme, horizonHazeColor, NodeRenderer, useImmersiveXRPresentation, useNodeEvents, useSceneAtmosphere, useSceneGroundReplacement, useViewer, } from '@pascal-app/viewer';
5
5
  import { useEffect, useMemo, useRef } from 'react';
6
6
  import { BufferAttribute, BufferGeometry, Path, Shape, ShapeGeometry } from 'three';
7
7
  import { cameraPosition, color, mix, positionWorld, smoothstep, float as tslFloat, vec2, } from 'three/tsl';
@@ -75,6 +75,7 @@ function addSlabHoles(shape, slabPolygons, originX = 0, originZ = 0) {
75
75
  }
76
76
  export const SiteRenderer = ({ node }) => {
77
77
  const ref = useRef(null);
78
+ const immersiveXR = useImmersiveXRPresentation();
78
79
  const atmosphere = useSceneAtmosphere();
79
80
  const groundReplaced = useSceneGroundReplacement();
80
81
  useRegistry(node.id, 'site', ref);
@@ -290,9 +291,15 @@ export const SiteRenderer = ({ node }) => {
290
291
  // inside TerrainRenderer so a stroke that starts on a site with no persisted
291
292
  // terrain still mounts the mesh.
292
293
  const showTerrain = terrainGrid !== null;
294
+ // The Site is the one kind whose `visible` flag stops at itself: hiding it
295
+ // drops the parcel's own presentation — ground fill, sculpted ground, lot
296
+ // line — while everything standing on the site keeps its own flag (the
297
+ // exporter and the 2D plan draw the same line). The horizon disc is a world
298
+ // backdrop rather than part of the parcel, so it stays either way.
299
+ const showSiteSurfaces = node.visible !== false;
293
300
  if (!(node && lineGeometry)) {
294
301
  return null;
295
302
  }
296
- return (_jsxs("group", { ref: ref, ...handlers, children: [(node.children ?? []).map((childId) => (_jsx(NodeRenderer, { nodeId: childId }, childId))), showTerrain && _jsx(TerrainRenderer, { material: groundMaterial, site: node }), groundGeometry && !showTerrain && (_jsx("mesh", { geometry: groundGeometry, material: groundMaterial, position: [0, -0.05, 0], receiveShadow: true, rotation: [-Math.PI / 2, 0, 0] })), horizonGeometry && horizonMaterial && fadeBounds && (_jsx("mesh", { geometry: horizonGeometry, material: horizonMaterial, position: [fadeBounds.cx, HORIZON_PLANE_Y, fadeBounds.cz], raycast: noopRaycast, receiveShadow: true, rotation: [-Math.PI / 2, 0, 0], userData: { pascalExport: 'strip' } })), _jsx("line", { frustumCulled: false, geometry: lineGeometry, renderOrder: 9, children: _jsx("lineBasicMaterial", { color: "#f59e0b", linewidth: 2, opacity: 0.6, transparent: true }) })] }));
303
+ return (_jsxs("group", { ref: ref, ...handlers, children: [(node.children ?? []).map((childId) => (_jsx(NodeRenderer, { nodeId: childId }, childId))), showSiteSurfaces && showTerrain && _jsx(TerrainRenderer, { material: groundMaterial, site: node }), showSiteSurfaces && groundGeometry && !showTerrain && (_jsx("mesh", { geometry: groundGeometry, material: groundMaterial, position: [0, -0.05, 0], receiveShadow: true, rotation: [-Math.PI / 2, 0, 0] })), !immersiveXR && horizonGeometry && horizonMaterial && fadeBounds && (_jsx("mesh", { geometry: horizonGeometry, material: horizonMaterial, position: [fadeBounds.cx, HORIZON_PLANE_Y, fadeBounds.cz], raycast: noopRaycast, receiveShadow: true, rotation: [-Math.PI / 2, 0, 0], userData: { pascalExport: 'strip' } })), showSiteSurfaces && (_jsx("line", { frustumCulled: false, geometry: lineGeometry, renderOrder: 9, children: _jsx("lineBasicMaterial", { color: "#f59e0b", linewidth: 2, opacity: 0.6, transparent: true }) }))] }));
297
304
  };
298
305
  export default SiteRenderer;
@@ -1 +1 @@
1
- {"version":3,"file":"definition.d.ts","sourceRoot":"","sources":["../../src/skylight/definition.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,cAAc,EAIpB,MAAM,kBAAkB,CAAA;AASzB,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AAoMvC;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,EAAE,cAAc,CAAC,OAAO,YAAY,CAiFlE,CAAA"}
1
+ {"version":3,"file":"definition.d.ts","sourceRoot":"","sources":["../../src/skylight/definition.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,cAAc,EAIpB,MAAM,kBAAkB,CAAA;AASzB,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AAoMvC;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,EAAE,cAAc,CAAC,OAAO,YAAY,CAkFlE,CAAA"}
@@ -226,6 +226,7 @@ export const skylightDefinition = {
226
226
  parametrics: skylightParametrics,
227
227
  handles: skylightHandles,
228
228
  floorplan: buildSkylightFloorplan,
229
+ rendersChildren: false,
229
230
  renderer: {
230
231
  kind: 'parametric',
231
232
  module: () => import('./renderer'),
@@ -218,7 +218,7 @@ export default function SkylightPanel() {
218
218
  return (_jsx("button", { className: cn('flex min-h-12 items-center gap-2.5 rounded-lg border px-3 py-2.5 text-left text-xs transition-colors', isSelected
219
219
  ? 'border-orange-400/60 bg-orange-400/10 text-foreground'
220
220
  : 'border-border/50 bg-[#2C2C2E] text-muted-foreground hover:bg-[#3e3e3e] hover:text-foreground'), onClick: () => handleTypeChange(skylightType), type: "button", children: _jsx("span", { className: "min-w-0 truncate font-medium", children: SKYLIGHT_TYPE_PRESETS[skylightType].label }) }, skylightType));
221
- }) }), _jsx(SliderControl, { label: "Glass Thickness", max: 0.05, min: 0.002, onChange: (v) => previewProp({ glassThickness: v }), onCommit: (v) => commitProp({ glassThickness: v }), precision: 3, restoreOnCommit: false, step: 0.001, unit: "m", value: Math.round((node.glassThickness ?? 0.01) * 1000) / 1000 }), activeSkylightType === 'lantern' && (_jsxs(_Fragment, { children: [_jsx(SliderControl, { label: "Lantern Height", max: 1.0, min: 0.05, onChange: (v) => previewProp({ lanternHeight: v }), onCommit: (v) => commitProp({ lanternHeight: v }), precision: 3, restoreOnCommit: false, step: 0.01, unit: "m", value: Math.round((node.lanternHeight ?? 0.25) * 1000) / 1000 }), _jsx(SliderControl, { label: "Top Scale", max: 0.95, min: 0, onChange: (v) => previewProp({ lanternTopScale: v }), onCommit: (v) => commitProp({ lanternTopScale: v }), precision: 2, restoreOnCommit: false, step: 0.05, unit: "", value: Math.round((node.lanternTopScale ?? 0.25) * 100) / 100 })] })), activeSkylightType === 'opening' && (_jsxs(_Fragment, { children: [_jsx(SliderControl, { label: "Open", max: 1, min: 0, onChange: (v) => previewProp({ operationState: v }), onCommit: (v) => commitProp({ operationState: v }), precision: 2, restoreOnCommit: false, step: 0.01, unit: "", value: Math.round((node.operationState ?? 0) * 100) / 100 }), _jsx(SliderControl, { label: "Opening Angle", max: 80, min: 0, onChange: (deg) => previewProp({ openingAngle: (deg * Math.PI) / 180 }), onCommit: (deg) => commitProp({ openingAngle: (deg * Math.PI) / 180 }), precision: 0, restoreOnCommit: false, step: 1, unit: "\u00B0", value: Math.round(((node.openingAngle ?? Math.PI / 10) * 180) / Math.PI) }), _jsx(SegmentedControl, { onChange: (v) => commitProp({ openingSide: v }), options: [
221
+ }) }), _jsx(SliderControl, { label: "Glass Thickness", max: 0.05, min: 0.002, onChange: (v) => previewProp({ glassThickness: v }), onCommit: (v) => commitProp({ glassThickness: v }), precision: 3, restoreOnCommit: false, step: 0.001, unit: "m", value: node.glassThickness ?? 0.01 }), activeSkylightType === 'lantern' && (_jsxs(_Fragment, { children: [_jsx(SliderControl, { label: "Lantern Height", max: 1.0, min: 0.05, onChange: (v) => previewProp({ lanternHeight: v }), onCommit: (v) => commitProp({ lanternHeight: v }), precision: 3, restoreOnCommit: false, step: 0.01, unit: "m", value: node.lanternHeight ?? 0.25 }), _jsx(SliderControl, { label: "Top Scale", max: 0.95, min: 0, onChange: (v) => previewProp({ lanternTopScale: v }), onCommit: (v) => commitProp({ lanternTopScale: v }), precision: 2, restoreOnCommit: false, step: 0.05, unit: "", value: Math.round((node.lanternTopScale ?? 0.25) * 100) / 100 })] })), activeSkylightType === 'opening' && (_jsxs(_Fragment, { children: [_jsx(SliderControl, { label: "Open", max: 1, min: 0, onChange: (v) => previewProp({ operationState: v }), onCommit: (v) => commitProp({ operationState: v }), precision: 2, restoreOnCommit: false, step: 0.01, unit: "", value: Math.round((node.operationState ?? 0) * 100) / 100 }), _jsx(SliderControl, { label: "Opening Angle", max: 80, min: 0, onChange: (deg) => previewProp({ openingAngle: (deg * Math.PI) / 180 }), onCommit: (deg) => commitProp({ openingAngle: (deg * Math.PI) / 180 }), precision: 0, restoreOnCommit: false, step: 1, unit: "\u00B0", value: Math.round(((node.openingAngle ?? Math.PI / 10) * 180) / Math.PI) }), _jsx(SegmentedControl, { onChange: (v) => commitProp({ openingSide: v }), options: [
222
222
  { label: 'Top', value: 'top' },
223
223
  { label: 'Bottom', value: 'bottom' },
224
224
  { label: 'Left', value: 'left' },
@@ -226,23 +226,23 @@ export default function SkylightPanel() {
226
226
  ], value: (node.openingSide ?? 'top') }), _jsx(SegmentedControl, { onChange: (v) => commitProp({ motorHousing: v === 'yes' }), options: [
227
227
  { label: 'Motor', value: 'yes' },
228
228
  { label: 'No Motor', value: 'no' },
229
- ], value: (node.motorHousing ?? false) ? 'yes' : 'no' }), (node.motorHousing ?? false) && (_jsx(SliderControl, { label: "Motor Housing", max: 0.2, min: 0.03, onChange: (v) => previewProp({ motorHousingSize: v }), onCommit: (v) => commitProp({ motorHousingSize: v }), precision: 3, restoreOnCommit: false, step: 0.005, unit: "m", value: Math.round((node.motorHousingSize ?? 0.08) * 1000) / 1000 }))] })), activeSkylightType === 'sliding' && (_jsxs(_Fragment, { children: [_jsx(SliderControl, { label: "Open", max: 1, min: 0, onChange: (v) => previewProp({ operationState: v }), onCommit: (v) => commitProp({ operationState: v }), precision: 2, restoreOnCommit: false, step: 0.01, unit: "", value: Math.round((node.operationState ?? 0) * 100) / 100 }), _jsx(SegmentedControl, { onChange: (v) => commitProp({ slideDirection: v }), options: [
229
+ ], value: (node.motorHousing ?? false) ? 'yes' : 'no' }), (node.motorHousing ?? false) && (_jsx(SliderControl, { label: "Motor Housing", max: 0.2, min: 0.03, onChange: (v) => previewProp({ motorHousingSize: v }), onCommit: (v) => commitProp({ motorHousingSize: v }), precision: 3, restoreOnCommit: false, step: 0.005, unit: "m", value: node.motorHousingSize ?? 0.08 }))] })), activeSkylightType === 'sliding' && (_jsxs(_Fragment, { children: [_jsx(SliderControl, { label: "Open", max: 1, min: 0, onChange: (v) => previewProp({ operationState: v }), onCommit: (v) => commitProp({ operationState: v }), precision: 2, restoreOnCommit: false, step: 0.01, unit: "", value: Math.round((node.operationState ?? 0) * 100) / 100 }), _jsx(SegmentedControl, { onChange: (v) => commitProp({ slideDirection: v }), options: [
230
230
  { label: 'Along Z', value: 'z' },
231
231
  { label: 'Along X', value: 'x' },
232
- ], value: (node.slideDirection ?? 'z') }), _jsx(SliderControl, { label: "Track Width", max: 0.12, min: 0.02, onChange: (v) => previewProp({ trackWidth: v }), onCommit: (v) => commitProp({ trackWidth: v }), precision: 3, restoreOnCommit: false, step: 0.005, unit: "m", value: Math.round((node.trackWidth ?? 0.045) * 1000) / 1000 })] }))] }), _jsxs(PanelSection, { title: "Dimensions", children: [_jsx(SliderControl, { label: "Width", max: 1000, min: 0.3, onChange: (v) => previewProp({ width: v }), onCommit: (v) => commitProp({ width: v }), precision: 2, restoreOnCommit: false, step: 0.05, unit: "m", value: Math.round(node.width * 100) / 100 }), _jsx(SliderControl, { label: "Height", max: 1000, min: 0.3, onChange: (v) => previewProp({ height: v }), onCommit: (v) => commitProp({ height: v }), precision: 2, restoreOnCommit: false, step: 0.05, unit: "m", value: Math.round(node.height * 100) / 100 })] }), _jsxs(PanelSection, { title: "Frame", children: [_jsx(SliderControl, { label: "Thickness", max: 0.2, min: 0.02, onChange: (v) => previewProp({ frameThickness: v }), onCommit: (v) => commitProp({ frameThickness: v }), precision: 3, restoreOnCommit: false, step: 0.005, unit: "m", value: Math.round((node.frameThickness ?? 0.05) * 1000) / 1000 }), _jsx(SliderControl, { label: "Depth", max: 0.3, min: 0.02, onChange: (v) => previewProp({ frameDepth: v }), onCommit: (v) => commitProp({ frameDepth: v }), precision: 3, restoreOnCommit: false, step: 0.005, unit: "m", value: Math.round((node.frameDepth ?? 0.08) * 1000) / 1000 }), _jsx(SliderControl, { label: "Cutout Offset", max: 0.2, min: 0, onChange: (v) => previewProp({ cutoutOffset: v }), onCommit: (v) => commitProp({ cutoutOffset: v }), precision: 3, restoreOnCommit: false, step: 0.005, unit: "m", value: Math.round((node.cutoutOffset ?? 0.01) * 1000) / 1000 })] }), _jsxs(PanelSection, { title: "Curb", children: [_jsx(SegmentedControl, { onChange: (v) => handleUpdate({ curb: v === 'yes' }), options: [
232
+ ], value: (node.slideDirection ?? 'z') }), _jsx(SliderControl, { label: "Track Width", max: 0.12, min: 0.02, onChange: (v) => previewProp({ trackWidth: v }), onCommit: (v) => commitProp({ trackWidth: v }), precision: 3, restoreOnCommit: false, step: 0.005, unit: "m", value: node.trackWidth ?? 0.045 })] }))] }), _jsxs(PanelSection, { title: "Dimensions", children: [_jsx(SliderControl, { label: "Width", max: 1000, min: 0.3, onChange: (v) => previewProp({ width: v }), onCommit: (v) => commitProp({ width: v }), precision: 2, restoreOnCommit: false, step: 0.05, unit: "m", value: node.width }), _jsx(SliderControl, { label: "Height", max: 1000, min: 0.3, onChange: (v) => previewProp({ height: v }), onCommit: (v) => commitProp({ height: v }), precision: 2, restoreOnCommit: false, step: 0.05, unit: "m", value: node.height })] }), _jsxs(PanelSection, { title: "Frame", children: [_jsx(SliderControl, { label: "Thickness", max: 0.2, min: 0.02, onChange: (v) => previewProp({ frameThickness: v }), onCommit: (v) => commitProp({ frameThickness: v }), precision: 3, restoreOnCommit: false, step: 0.005, unit: "m", value: node.frameThickness ?? 0.05 }), _jsx(SliderControl, { label: "Depth", max: 0.3, min: 0.02, onChange: (v) => previewProp({ frameDepth: v }), onCommit: (v) => commitProp({ frameDepth: v }), precision: 3, restoreOnCommit: false, step: 0.005, unit: "m", value: node.frameDepth ?? 0.08 }), _jsx(SliderControl, { label: "Cutout Offset", max: 0.2, min: 0, onChange: (v) => previewProp({ cutoutOffset: v }), onCommit: (v) => commitProp({ cutoutOffset: v }), precision: 3, restoreOnCommit: false, step: 0.005, unit: "m", value: node.cutoutOffset ?? 0.01 })] }), _jsxs(PanelSection, { title: "Curb", children: [_jsx(SegmentedControl, { onChange: (v) => handleUpdate({ curb: v === 'yes' }), options: [
233
233
  { label: 'Yes', value: 'yes' },
234
234
  { label: 'No', value: 'no' },
235
- ], value: (node.curb ?? false) ? 'yes' : 'no' }), (node.curb ?? false) && (_jsx(SliderControl, { label: "Height", max: 0.3, min: 0.02, onChange: (v) => previewProp({ curbHeight: v }), onCommit: (v) => commitProp({ curbHeight: v }), precision: 3, restoreOnCommit: false, step: 0.005, unit: "m", value: Math.round((node.curbHeight ?? 0.1) * 1000) / 1000 }))] }), _jsxs(PanelSection, { title: "Position", children: [_jsx(SliderControl, { label: "X", max: Math.round(worldMaxX * 10) / 10, min: Math.round(worldMinX * 10) / 10, onChange: (newWorldX) => {
235
+ ], value: (node.curb ?? false) ? 'yes' : 'no' }), (node.curb ?? false) && (_jsx(SliderControl, { label: "Height", max: 0.3, min: 0.02, onChange: (v) => previewProp({ curbHeight: v }), onCommit: (v) => commitProp({ curbHeight: v }), precision: 3, restoreOnCommit: false, step: 0.005, unit: "m", value: node.curbHeight ?? 0.1 }))] }), _jsxs(PanelSection, { title: "Position", children: [_jsx(SliderControl, { label: "X", max: Math.round(worldMaxX * 10) / 10, min: Math.round(worldMinX * 10) / 10, onChange: (newWorldX) => {
236
236
  if (!segment)
237
237
  return;
238
238
  const local = worldToSegLocal(newWorldX, worldZ_now, segment);
239
239
  previewProp({ position: [local.localX, 0, local.localZ] });
240
- }, onCommit: (newWorldX) => commitWorldPosition(newWorldX, worldZ_now), precision: 2, restoreOnCommit: false, step: 0.05, unit: "m", value: Math.round(worldX_now * 100) / 100 }), _jsx(SliderControl, { label: "Z", max: Math.round(worldMaxZ * 10) / 10, min: Math.round(worldMinZ * 10) / 10, onChange: (newWorldZ) => {
240
+ }, onCommit: (newWorldX) => commitWorldPosition(newWorldX, worldZ_now), precision: 2, restoreOnCommit: false, step: 0.05, unit: "m", value: worldX_now }), _jsx(SliderControl, { label: "Z", max: Math.round(worldMaxZ * 10) / 10, min: Math.round(worldMinZ * 10) / 10, onChange: (newWorldZ) => {
241
241
  if (!segment)
242
242
  return;
243
243
  const local = worldToSegLocal(worldX_now, newWorldZ, segment);
244
244
  previewProp({ position: [local.localX, 0, local.localZ] });
245
- }, onCommit: (newWorldZ) => commitWorldPosition(worldX_now, newWorldZ), precision: 2, restoreOnCommit: false, step: 0.05, unit: "m", value: Math.round(worldZ_now * 100) / 100 }), _jsx(SliderControl, { label: "Rotation", max: 180, min: -180, onChange: (degrees) => {
245
+ }, onCommit: (newWorldZ) => commitWorldPosition(worldX_now, newWorldZ), precision: 2, restoreOnCommit: false, step: 0.05, unit: "m", value: worldZ_now }), _jsx(SliderControl, { label: "Rotation", max: 180, min: -180, onChange: (degrees) => {
246
246
  const newWorldRot = (degrees * Math.PI) / 180;
247
247
  if (!skylightObj)
248
248
  return;
@@ -1 +1 @@
1
- {"version":3,"file":"definition.d.ts","sourceRoot":"","sources":["../../src/slab/definition.ts"],"names":[],"mappings":"AAAA,OAAO,EAML,KAAK,cAAc,EAKpB,MAAM,kBAAkB,CAAA;AA4BzB,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AAsNnC;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,cAAc,EAAE,cAAc,CAAC,OAAO,QAAQ,CAsH1D,CAAA"}
1
+ {"version":3,"file":"definition.d.ts","sourceRoot":"","sources":["../../src/slab/definition.ts"],"names":[],"mappings":"AAAA,OAAO,EAML,KAAK,cAAc,EAKpB,MAAM,kBAAkB,CAAA;AA8BzB,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AAsNnC;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,cAAc,EAAE,cAAc,CAAC,OAAO,QAAQ,CAyH1D,CAAA"}
@@ -1,6 +1,7 @@
1
1
  import { MIN_SLAB_THICKNESS, markSlabChangeDependents, pointInPolygon2D, syncStairRises, } from '@pascal-app/core';
2
2
  import { clearStructuralElevationGuide, DRAFTING_SURFACE_EXTENSION_KEY, publishStructuralElevationGuide, resolveStructuralElevationSnap, } from '@pascal-app/editor';
3
3
  import { polygonMeasurementFeatures } from '../shared/polygon-measurement';
4
+ import { sameOutlineSurfaceCounterparts } from '../shared/surface-counterparts';
4
5
  import { applySlabBaseElevationChange, applySlabThicknessChange, applySlabTopChange, getSlabBaseElevation, slabElevationUpperBound, } from './elevation-limit';
5
6
  import { buildSlabFloorplan } from './floorplan';
6
7
  import { slabAddVertexAffordance, slabDeleteVertexAffordance, slabMoveEdgeAffordance, slabMoveVertexAffordance, } from './floorplan-affordances';
@@ -201,6 +202,9 @@ export const slabDefinition = {
201
202
  [DRAFTING_SURFACE_EXTENSION_KEY]: {
202
203
  kind: 'slab',
203
204
  },
205
+ 'pascal:editor/floorplan': {
206
+ selectionCounterparts: sameOutlineSurfaceCounterparts,
207
+ },
204
208
  },
205
209
  defaults: () => ({
206
210
  object: 'node',
@@ -203,7 +203,7 @@ export function SlabPanel() {
203
203
  { label: 'Standard (5cm)', elevation: 0.05 },
204
204
  { label: 'Thick (15cm)', elevation: 0.15 },
205
205
  ];
206
- return (_jsxs(PanelWrapper, { icon: "/icons/floor.webp", onClose: handleClose, title: node.name || 'Slab', width: 320, children: [_jsxs(PanelSection, { title: "Elevation", children: [_jsx(SliderControl, { label: node.recessed ? 'Floor' : 'Surface', max: 20, min: -3, onChange: handleElevationChange, precision: 3, step: 0.01, unit: "m", value: Math.round(node.elevation * 1000) / 1000 }), _jsx(SliderControl, { label: node.recessed ? 'Rim' : 'Base', max: 20, min: -3, onChange: handleAnchorChange, precision: 3, step: 0.01, unit: "m", value: Math.round(getSlabAnchorElevation(node) * 1000) / 1000 }), node.recessed ? (_jsx(SliderControl, { label: "Depth", max: 1000, min: MIN_SLAB_THICKNESS, onChange: handleRecessDepthChange, precision: 2, step: 0.01, unit: "m", value: Math.round(getSlabRecessDepth(node) * 100) / 100 })) : (_jsx(SliderControl, { label: "Thickness", max: 1000, min: MIN_SLAB_THICKNESS, onChange: handleThicknessChange, precision: 2, step: 0.01, unit: "m", value: Math.round((node.thickness ?? 0.05) * 100) / 100 })), !node.recessed && (_jsxs(_Fragment, { children: [_jsx("div", { className: "px-1 font-medium text-[10px] text-muted-foreground/80 uppercase tracking-wider", children: "Foundation" }), _jsx(SegmentedControl, { onChange: handleTerrainModeChange, options: [
206
+ return (_jsxs(PanelWrapper, { icon: "/icons/floor.webp", onClose: handleClose, title: node.name || 'Slab', width: 320, children: [_jsxs(PanelSection, { title: "Elevation", children: [_jsx(SliderControl, { label: node.recessed ? 'Floor' : 'Surface', max: 20, min: -3, onChange: handleElevationChange, precision: 3, step: 0.01, unit: "m", value: node.elevation }), _jsx(SliderControl, { label: node.recessed ? 'Rim' : 'Base', max: 20, min: -3, onChange: handleAnchorChange, precision: 3, step: 0.01, unit: "m", value: getSlabAnchorElevation(node) }), node.recessed ? (_jsx(SliderControl, { label: "Depth", max: 1000, min: MIN_SLAB_THICKNESS, onChange: handleRecessDepthChange, precision: 2, step: 0.01, unit: "m", value: getSlabRecessDepth(node) })) : (_jsx(SliderControl, { label: "Thickness", max: 1000, min: MIN_SLAB_THICKNESS, onChange: handleThicknessChange, precision: 2, step: 0.01, unit: "m", value: node.thickness ?? 0.05 })), !node.recessed && (_jsxs(_Fragment, { children: [_jsx("div", { className: "px-1 font-medium text-[10px] text-muted-foreground/80 uppercase tracking-wider", children: "Foundation" }), _jsx(SegmentedControl, { onChange: handleTerrainModeChange, options: [
207
207
  { label: 'Fixed', value: 'fixed' },
208
208
  { label: 'Follows terrain', value: 'terrain' },
209
209
  ], value: node.fillToTerrain ? 'terrain' : 'fixed' }), node.fillToTerrain && (_jsx("div", { className: "px-1 text-[11px] text-muted-foreground", children: "Extends the perimeter down to terrain. The flat surface, base, and thickness stay unchanged." }))] })), _jsx("div", { className: "mt-2 grid grid-cols-2 gap-1.5 px-1 pb-1", children: elevationPresets.map((preset) => (_jsx(ActionButton, { label: preset.label, onClick: () => handleElevationPreset(preset.elevation) }, preset.label))) })] }), _jsx(PanelSection, { title: "Info", children: _jsxs("div", { className: "flex items-center justify-between px-2 py-1 text-muted-foreground text-sm", children: [_jsx("span", { children: "Area" }), _jsxs("span", { className: "font-mono text-white", children: [area.toFixed(2), " m\u00B2"] })] }) }), _jsxs(PanelSection, { title: "Holes", children: [node.holes && node.holes.length > 0 ? (_jsx("div", { className: "flex flex-col gap-1 pb-2", children: node.holes.map((hole, index) => {
@@ -1 +1 @@
1
- {"version":3,"file":"definition.d.ts","sourceRoot":"","sources":["../../src/solar-panel/definition.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,cAAc,EAGpB,MAAM,kBAAkB,CAAA;AAGzB,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAgNzC;;;;;;;;;;GAUG;AACH,eAAO,MAAM,oBAAoB,EAAE,cAAc,CAAC,OAAO,cAAc,CAyDtE,CAAA"}
1
+ {"version":3,"file":"definition.d.ts","sourceRoot":"","sources":["../../src/solar-panel/definition.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,cAAc,EAGpB,MAAM,kBAAkB,CAAA;AAGzB,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAgNzC;;;;;;;;;;GAUG;AACH,eAAO,MAAM,oBAAoB,EAAE,cAAc,CAAC,OAAO,cAAc,CA0DtE,CAAA"}
@@ -235,6 +235,7 @@ export const solarPanelDefinition = {
235
235
  parametrics: solarPanelParametrics,
236
236
  handles: solarPanelHandles,
237
237
  floorplan: buildSolarPanelFloorplan,
238
+ rendersChildren: false,
238
239
  renderer: {
239
240
  kind: 'parametric',
240
241
  module: () => import('./renderer'),
@@ -139,8 +139,8 @@ export default function SolarPanelPanel() {
139
139
  return (_jsxs("button", { className: cn('flex min-h-14 flex-col items-start gap-0.5 rounded-lg border px-2.5 py-2 text-left text-xs transition-colors', isSelected
140
140
  ? 'border-orange-400/60 bg-orange-400/10 text-foreground'
141
141
  : 'border-border/50 bg-[#2C2C2E] text-muted-foreground hover:bg-[#3e3e3e] hover:text-foreground'), onClick: () => handlePresetChange(card.key), type: "button", children: [_jsxs("span", { className: "flex items-center gap-1.5 font-medium", children: [_jsx(LayoutGrid, { className: "h-3.5 w-3.5 shrink-0" }), _jsx("span", { className: "truncate", children: card.label })] }), _jsx("span", { className: "pl-[20px] text-[10px] tabular-nums opacity-70", children: formatDims(dims.panelWidth, dims.panelHeight) })] }, card.key));
142
- }) }), !activePreset && (_jsx("p", { className: "px-1 pt-1 text-[11px] text-muted-foreground", children: "Custom \u2014 dimensions don't match any preset" }))] }), _jsxs(PanelSection, { title: "Array", children: [_jsx(SliderControl, { label: "Rows", max: 20, min: 1, onChange: (v) => previewProp({ rows: Math.round(v) }), onCommit: (v) => commitProp({ rows: Math.round(v) }), precision: 0, restoreOnCommit: false, step: 1, value: num(node.rows, 4) }), _jsx(SliderControl, { label: "Columns", max: 20, min: 1, onChange: (v) => previewProp({ columns: Math.round(v) }), onCommit: (v) => commitProp({ columns: Math.round(v) }), precision: 0, restoreOnCommit: false, step: 1, value: num(node.columns, 5) }), _jsx(SliderControl, { label: "Gap X", max: 0.2, min: 0, onChange: (v) => previewProp({ gapX: v }), onCommit: (v) => commitProp({ gapX: v }), precision: 3, restoreOnCommit: false, step: 0.005, unit: "m", value: Math.round(num(node.gapX, 0.02) * 1000) / 1000 }), _jsx(SliderControl, { label: "Gap Y", max: 0.2, min: 0, onChange: (v) => previewProp({ gapY: v }), onCommit: (v) => commitProp({ gapY: v }), precision: 3, restoreOnCommit: false, step: 0.005, unit: "m", value: Math.round(num(node.gapY, 0.02) * 1000) / 1000 }), _jsx(ActionGroup, { children: _jsx(ActionButton, { disabled: !segment, label: "Auto-fit to roof", onClick: handleAutoFit }) }), autoFitMessage ? _jsx("p", { className: "px-1 text-amber-400 text-xs", children: autoFitMessage }) : null] }), _jsxs(PanelSection, { title: "Panel", children: [_jsx(SliderControl, { label: "Width", max: 1000, min: 0.3, onChange: (v) => previewProp({ panelWidth: v }), onCommit: (v) => commitProp({ panelWidth: v }), precision: 2, restoreOnCommit: false, step: 0.05, unit: "m", value: Math.round(num(node.panelWidth, 1) * 100) / 100 }), _jsx(SliderControl, { label: "Height", max: 1000, min: 0.3, onChange: (v) => previewProp({ panelHeight: v }), onCommit: (v) => commitProp({ panelHeight: v }), precision: 2, restoreOnCommit: false, step: 0.05, unit: "m", value: Math.round(num(node.panelHeight, 1.65) * 100) / 100 }), _jsx(ActionGroup, { children: _jsx(ActionButton, { label: "Flip orientation", onClick: handleFlip }) }), _jsx(SliderControl, { label: "Frame thickness", max: 0.1, min: 0.005, onChange: (v) => previewProp({ frameThickness: v }), onCommit: (v) => commitProp({ frameThickness: v }), precision: 3, restoreOnCommit: false, step: 0.005, unit: "m", value: Math.round(num(node.frameThickness, 0.04) * 1000) / 1000 }), _jsx(SliderControl, { label: "Frame depth", max: 0.1, min: 0.005, onChange: (v) => previewProp({ frameDepth: v }), onCommit: (v) => commitProp({ frameDepth: v }), precision: 3, restoreOnCommit: false, step: 0.005, unit: "m", value: Math.round(num(node.frameDepth, 0.04) * 1000) / 1000 })] }), _jsxs(PanelSection, { title: "Mounting", children: [_jsx(SegmentedControl, { onChange: (v) => handleUpdate({ mountingType: v }), options: [
142
+ }) }), !activePreset && (_jsx("p", { className: "px-1 pt-1 text-[11px] text-muted-foreground", children: "Custom \u2014 dimensions don't match any preset" }))] }), _jsxs(PanelSection, { title: "Array", children: [_jsx(SliderControl, { label: "Rows", max: 20, min: 1, onChange: (v) => previewProp({ rows: Math.round(v) }), onCommit: (v) => commitProp({ rows: Math.round(v) }), precision: 0, restoreOnCommit: false, step: 1, value: num(node.rows, 4) }), _jsx(SliderControl, { label: "Columns", max: 20, min: 1, onChange: (v) => previewProp({ columns: Math.round(v) }), onCommit: (v) => commitProp({ columns: Math.round(v) }), precision: 0, restoreOnCommit: false, step: 1, value: num(node.columns, 5) }), _jsx(SliderControl, { label: "Gap X", max: 0.2, min: 0, onChange: (v) => previewProp({ gapX: v }), onCommit: (v) => commitProp({ gapX: v }), precision: 3, restoreOnCommit: false, step: 0.005, unit: "m", value: num(node.gapX, 0.02) }), _jsx(SliderControl, { label: "Gap Y", max: 0.2, min: 0, onChange: (v) => previewProp({ gapY: v }), onCommit: (v) => commitProp({ gapY: v }), precision: 3, restoreOnCommit: false, step: 0.005, unit: "m", value: num(node.gapY, 0.02) }), _jsx(ActionGroup, { children: _jsx(ActionButton, { disabled: !segment, label: "Auto-fit to roof", onClick: handleAutoFit }) }), autoFitMessage ? _jsx("p", { className: "px-1 text-amber-400 text-xs", children: autoFitMessage }) : null] }), _jsxs(PanelSection, { title: "Panel", children: [_jsx(SliderControl, { label: "Width", max: 1000, min: 0.3, onChange: (v) => previewProp({ panelWidth: v }), onCommit: (v) => commitProp({ panelWidth: v }), precision: 2, restoreOnCommit: false, step: 0.05, unit: "m", value: num(node.panelWidth, 1) }), _jsx(SliderControl, { label: "Height", max: 1000, min: 0.3, onChange: (v) => previewProp({ panelHeight: v }), onCommit: (v) => commitProp({ panelHeight: v }), precision: 2, restoreOnCommit: false, step: 0.05, unit: "m", value: num(node.panelHeight, 1.65) }), _jsx(ActionGroup, { children: _jsx(ActionButton, { label: "Flip orientation", onClick: handleFlip }) }), _jsx(SliderControl, { label: "Frame thickness", max: 0.1, min: 0.005, onChange: (v) => previewProp({ frameThickness: v }), onCommit: (v) => commitProp({ frameThickness: v }), precision: 3, restoreOnCommit: false, step: 0.005, unit: "m", value: num(node.frameThickness, 0.04) }), _jsx(SliderControl, { label: "Frame depth", max: 0.1, min: 0.005, onChange: (v) => previewProp({ frameDepth: v }), onCommit: (v) => commitProp({ frameDepth: v }), precision: 3, restoreOnCommit: false, step: 0.005, unit: "m", value: num(node.frameDepth, 0.04) })] }), _jsxs(PanelSection, { title: "Mounting", children: [_jsx(SegmentedControl, { onChange: (v) => handleUpdate({ mountingType: v }), options: [
143
143
  { label: 'Flush', value: 'flush' },
144
144
  { label: 'Tilted', value: 'tilted' },
145
- ], value: node.mountingType ?? 'flush' }), node.mountingType === 'tilted' && (_jsx(SliderControl, { label: "Tilt angle", max: 45, min: 0, onChange: (v) => previewProp({ tiltAngle: v }), onCommit: (v) => commitProp({ tiltAngle: v }), precision: 0, restoreOnCommit: false, step: 1, unit: "\u00B0", value: Math.round(num(node.tiltAngle, 15)) })), _jsx(SliderControl, { label: "Standoff", max: 0.3, min: 0, onChange: (v) => previewProp({ standoffHeight: v }), onCommit: (v) => commitProp({ standoffHeight: v }), precision: 3, restoreOnCommit: false, step: 0.005, unit: "m", value: Math.round(num(node.standoffHeight, 0.05) * 1000) / 1000 })] }), _jsx(PanelSection, { title: "Actions", children: _jsx(ActionGroup, { children: _jsx(ActionButton, { className: "hover:bg-red-500/20", icon: _jsx(Trash2, { className: "h-3.5 w-3.5 text-red-400" }), label: "Delete", onClick: handleDelete }) }) })] }));
145
+ ], value: node.mountingType ?? 'flush' }), node.mountingType === 'tilted' && (_jsx(SliderControl, { label: "Tilt angle", max: 45, min: 0, onChange: (v) => previewProp({ tiltAngle: v }), onCommit: (v) => commitProp({ tiltAngle: v }), precision: 0, restoreOnCommit: false, step: 1, unit: "\u00B0", value: Math.round(num(node.tiltAngle, 15)) })), _jsx(SliderControl, { label: "Standoff", max: 0.3, min: 0, onChange: (v) => previewProp({ standoffHeight: v }), onCommit: (v) => commitProp({ standoffHeight: v }), precision: 3, restoreOnCommit: false, step: 0.005, unit: "m", value: num(node.standoffHeight, 0.05) })] }), _jsx(PanelSection, { title: "Actions", children: _jsx(ActionGroup, { children: _jsx(ActionButton, { className: "hover:bg-red-500/20", icon: _jsx(Trash2, { className: "h-3.5 w-3.5 text-red-400" }), label: "Delete", onClick: handleDelete }) }) })] }));
146
146
  }