@pascal-app/nodes 0.1.1 → 1.0.0-beta.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.
- package/README.md +34 -0
- package/dist/building/definition.js +1 -1
- package/dist/cabinet/definition.d.ts.map +1 -1
- package/dist/cabinet/definition.js +809 -72
- package/dist/cabinet/geometry.d.ts.map +1 -1
- package/dist/cabinet/geometry.js +4 -0
- package/dist/cabinet/move-frame.js +3 -3
- package/dist/cabinet/panel.d.ts.map +1 -1
- package/dist/cabinet/panel.js +1 -0
- package/dist/cabinet/placement-snap.d.ts +8 -0
- package/dist/cabinet/placement-snap.d.ts.map +1 -0
- package/dist/cabinet/placement-snap.js +19 -0
- package/dist/cabinet/presets.js +8 -8
- package/dist/cabinet/quick-actions.d.ts.map +1 -1
- package/dist/cabinet/quick-actions.js +9 -3
- package/dist/cabinet/resize-limits.d.ts +11 -0
- package/dist/cabinet/resize-limits.d.ts.map +1 -0
- package/dist/cabinet/resize-limits.js +22 -0
- package/dist/cabinet/run-layout.d.ts +8 -2
- package/dist/cabinet/run-layout.d.ts.map +1 -1
- package/dist/cabinet/run-layout.js +59 -7
- package/dist/cabinet/run-ops.d.ts +44 -3
- package/dist/cabinet/run-ops.d.ts.map +1 -1
- package/dist/cabinet/run-ops.js +646 -110
- package/dist/cabinet/run-panel.d.ts +2 -1
- package/dist/cabinet/run-panel.d.ts.map +1 -1
- package/dist/cabinet/run-panel.js +38 -4
- package/dist/cabinet/stack-transitions.js +4 -4
- package/dist/cabinet/tool.d.ts.map +1 -1
- package/dist/cabinet/tool.js +95 -17
- package/dist/cabinet/wall-snap.d.ts.map +1 -1
- package/dist/cabinet/wall-snap.js +2 -6
- package/dist/ceiling/boundary-editor.d.ts.map +1 -1
- package/dist/ceiling/boundary-editor.js +2 -2
- package/dist/ceiling/definition.d.ts +1 -1
- package/dist/ceiling/definition.d.ts.map +1 -1
- package/dist/ceiling/definition.js +36 -5
- package/dist/ceiling/floorplan-affordances.d.ts +4 -4
- package/dist/ceiling/floorplan-move.d.ts +4 -4
- package/dist/ceiling/floorplan-move.d.ts.map +1 -1
- package/dist/ceiling/floorplan-move.js +5 -4
- package/dist/ceiling/hole-editor.d.ts.map +1 -1
- package/dist/ceiling/hole-editor.js +2 -2
- package/dist/ceiling/move-tool.d.ts.map +1 -1
- package/dist/ceiling/move-tool.js +4 -3
- package/dist/ceiling/panel.d.ts.map +1 -1
- package/dist/ceiling/panel.js +65 -3
- package/dist/ceiling/renderer.d.ts.map +1 -1
- package/dist/ceiling/renderer.js +6 -2
- package/dist/ceiling/tool.d.ts.map +1 -1
- package/dist/ceiling/tool.js +12 -1
- package/dist/chimney/definition.d.ts.map +1 -1
- package/dist/chimney/definition.js +1 -0
- package/dist/chimney/tool.d.ts.map +1 -1
- package/dist/chimney/tool.js +16 -1
- package/dist/column/definition.d.ts.map +1 -1
- package/dist/column/definition.js +14 -2
- package/dist/column/floorplan-affordances.d.ts.map +1 -1
- package/dist/column/floorplan-affordances.js +19 -14
- package/dist/column/floorplan-move.d.ts.map +1 -1
- package/dist/column/floorplan-move.js +7 -2
- package/dist/column/floorplan.d.ts +9 -1
- package/dist/column/floorplan.d.ts.map +1 -1
- package/dist/column/floorplan.js +59 -4
- package/dist/column/tool.d.ts.map +1 -1
- package/dist/column/tool.js +33 -7
- package/dist/construction-dimension/definition.d.ts +4 -0
- package/dist/construction-dimension/definition.d.ts.map +1 -0
- package/dist/construction-dimension/definition.js +83 -0
- package/dist/construction-dimension/drawing-coordination.d.ts +7 -0
- package/dist/construction-dimension/drawing-coordination.d.ts.map +1 -0
- package/dist/construction-dimension/drawing-coordination.js +54 -0
- package/dist/construction-dimension/floorplan-affordances.d.ts +4 -0
- package/dist/construction-dimension/floorplan-affordances.d.ts.map +1 -0
- package/dist/construction-dimension/floorplan-affordances.js +114 -0
- package/dist/construction-dimension/floorplan-tool.d.ts +21 -0
- package/dist/construction-dimension/floorplan-tool.d.ts.map +1 -0
- package/dist/construction-dimension/floorplan-tool.js +557 -0
- package/dist/construction-dimension/floorplan.d.ts +3 -0
- package/dist/construction-dimension/floorplan.d.ts.map +1 -0
- package/dist/construction-dimension/floorplan.js +457 -0
- package/dist/construction-dimension/geometry.d.ts +31 -0
- package/dist/construction-dimension/geometry.d.ts.map +1 -0
- package/dist/construction-dimension/geometry.js +144 -0
- package/dist/construction-dimension/index.d.ts +4 -0
- package/dist/construction-dimension/index.d.ts.map +1 -0
- package/dist/construction-dimension/index.js +3 -0
- package/dist/construction-dimension/panel.d.ts +2 -0
- package/dist/construction-dimension/panel.d.ts.map +1 -0
- package/dist/construction-dimension/panel.js +128 -0
- package/dist/construction-dimension/parametrics.d.ts +3 -0
- package/dist/construction-dimension/parametrics.d.ts.map +1 -0
- package/dist/construction-dimension/parametrics.js +4 -0
- package/dist/construction-dimension/schema.d.ts +2 -0
- package/dist/construction-dimension/schema.d.ts.map +1 -0
- package/dist/construction-dimension/schema.js +1 -0
- package/dist/door/contextual-dimensions.d.ts +3 -0
- package/dist/door/contextual-dimensions.d.ts.map +1 -0
- package/dist/door/contextual-dimensions.js +7 -0
- package/dist/door/definition.d.ts.map +1 -1
- package/dist/door/definition.js +13 -8
- package/dist/door/floorplan-affordances.d.ts +2 -5
- package/dist/door/floorplan-affordances.d.ts.map +1 -1
- package/dist/door/floorplan-affordances.js +9 -18
- package/dist/door/floorplan.d.ts +3 -4
- package/dist/door/floorplan.d.ts.map +1 -1
- package/dist/door/floorplan.js +88 -6
- package/dist/door/move-tool.d.ts.map +1 -1
- package/dist/door/move-tool.js +2 -2
- package/dist/door/panel.d.ts.map +1 -1
- package/dist/door/panel.js +3 -1
- package/dist/door/schema.d.ts +1 -1
- package/dist/door/schema.d.ts.map +1 -1
- package/dist/door/schema.js +1 -1
- package/dist/door/tool.d.ts.map +1 -1
- package/dist/door/tool.js +63 -6
- package/dist/dormer/definition.d.ts.map +1 -1
- package/dist/dormer/definition.js +1 -0
- package/dist/dormer/tool.d.ts.map +1 -1
- package/dist/dormer/tool.js +23 -1
- package/dist/duct-segment/tool.d.ts.map +1 -1
- package/dist/duct-segment/tool.js +20 -9
- package/dist/duct-terminal/tool.d.ts.map +1 -1
- package/dist/duct-terminal/tool.js +9 -6
- package/dist/elevator/floorplan-affordances.d.ts +2 -6
- package/dist/elevator/floorplan-affordances.d.ts.map +1 -1
- package/dist/elevator/floorplan-affordances.js +13 -12
- package/dist/fence/actions/move-endpoint.d.ts.map +1 -1
- package/dist/fence/actions/move-endpoint.js +29 -1
- package/dist/fence/definition.d.ts.map +1 -1
- package/dist/fence/definition.js +67 -14
- package/dist/fence/floorplan-affordances.d.ts.map +1 -1
- package/dist/fence/floorplan-affordances.js +48 -11
- package/dist/fence/floorplan-move.d.ts.map +1 -1
- package/dist/fence/floorplan-move.js +38 -3
- package/dist/fence/geometry.d.ts.map +1 -1
- package/dist/fence/geometry.js +9 -1
- package/dist/fence/lift.d.ts +15 -0
- package/dist/fence/lift.d.ts.map +1 -0
- package/dist/fence/lift.js +23 -0
- package/dist/fence/move-tool.d.ts.map +1 -1
- package/dist/fence/move-tool.js +25 -5
- package/dist/fence/system.d.ts +3 -0
- package/dist/fence/system.d.ts.map +1 -0
- package/dist/fence/system.js +41 -0
- package/dist/fence/tool.d.ts.map +1 -1
- package/dist/fence/tool.js +103 -32
- package/dist/hvac-equipment/tool.d.ts.map +1 -1
- package/dist/hvac-equipment/tool.js +8 -3
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -0
- package/dist/item/definition.d.ts.map +1 -1
- package/dist/item/definition.js +7 -1
- package/dist/item/floorplan-move.d.ts.map +1 -1
- package/dist/item/floorplan-move.js +50 -43
- package/dist/item/floorplan.d.ts +1 -0
- package/dist/item/floorplan.d.ts.map +1 -1
- package/dist/item/floorplan.js +49 -0
- package/dist/item/renderer.d.ts +3 -0
- package/dist/item/renderer.d.ts.map +1 -1
- package/dist/item/renderer.js +96 -8
- package/dist/level/definition.d.ts.map +1 -1
- package/dist/level/definition.js +7 -3
- package/dist/lineset/tool.d.ts.map +1 -1
- package/dist/lineset/tool.js +5 -1
- package/dist/liquid-line/tool.d.ts.map +1 -1
- package/dist/liquid-line/tool.js +7 -1
- package/dist/measurement/definition.d.ts.map +1 -1
- package/dist/measurement/definition.js +5 -0
- package/dist/measurement/floorplan.d.ts.map +1 -1
- package/dist/measurement/floorplan.js +11 -10
- package/dist/measurement/index.d.ts +1 -1
- package/dist/measurement/index.d.ts.map +1 -1
- package/dist/measurement/index.js +1 -1
- package/dist/measurement/resolve.d.ts +5 -0
- package/dist/measurement/resolve.d.ts.map +1 -1
- package/dist/measurement/resolve.js +2 -2
- package/dist/measurement/surface-query.js +5 -5
- package/dist/measurement/tool.d.ts +6 -1
- package/dist/measurement/tool.d.ts.map +1 -1
- package/dist/measurement/tool.js +7 -11
- package/dist/pipe-segment/tool.d.ts.map +1 -1
- package/dist/pipe-segment/tool.js +22 -19
- package/dist/roof-segment/floorplan-affordances.d.ts.map +1 -1
- package/dist/roof-segment/floorplan-affordances.js +14 -8
- package/dist/shared/construction-dimension-standards.d.ts +34 -0
- package/dist/shared/construction-dimension-standards.d.ts.map +1 -0
- package/dist/shared/construction-dimension-standards.js +18 -0
- package/dist/shared/construction-length.d.ts +10 -0
- package/dist/shared/construction-length.d.ts.map +1 -0
- package/dist/shared/construction-length.js +57 -0
- package/dist/shared/dimension-string.d.ts +20 -0
- package/dist/shared/dimension-string.d.ts.map +1 -0
- package/dist/shared/dimension-string.js +19 -0
- package/dist/shared/draft-axis-guides.d.ts +36 -0
- package/dist/shared/draft-axis-guides.d.ts.map +1 -0
- package/dist/shared/draft-axis-guides.js +107 -0
- package/dist/shared/move-roof-tool.d.ts.map +1 -1
- package/dist/shared/move-roof-tool.js +17 -3
- package/dist/shared/opening-documentation-fields.d.ts +16 -0
- package/dist/shared/opening-documentation-fields.d.ts.map +1 -0
- package/dist/shared/opening-documentation-fields.js +54 -0
- package/dist/shared/opening-documentation.d.ts +47 -0
- package/dist/shared/opening-documentation.d.ts.map +1 -0
- package/dist/shared/opening-documentation.js +300 -0
- package/dist/shared/opening-guides-runtime.d.ts.map +1 -1
- package/dist/shared/opening-guides-runtime.js +3 -2
- package/dist/shared/opening-placement-dimensions.d.ts.map +1 -1
- package/dist/shared/opening-placement-dimensions.js +14 -5
- package/dist/shared/wall-opening-ceiling.d.ts +30 -0
- package/dist/shared/wall-opening-ceiling.d.ts.map +1 -0
- package/dist/shared/wall-opening-ceiling.js +29 -0
- package/dist/shelf/floorplan-affordances.d.ts.map +1 -1
- package/dist/shelf/floorplan-affordances.js +10 -5
- package/dist/shelf/floorplan-move.d.ts +2 -16
- package/dist/shelf/floorplan-move.d.ts.map +1 -1
- package/dist/shelf/floorplan-move.js +19 -40
- package/dist/shelf/tool.d.ts.map +1 -1
- package/dist/shelf/tool.js +8 -3
- package/dist/site/recessed-slab-ground-holes.d.ts.map +1 -1
- package/dist/site/recessed-slab-ground-holes.js +1 -4
- package/dist/site/renderer.d.ts.map +1 -1
- package/dist/site/renderer.js +118 -28
- package/dist/site/terrain-drape.d.ts +91 -0
- package/dist/site/terrain-drape.d.ts.map +1 -0
- package/dist/site/terrain-drape.js +205 -0
- package/dist/site/terrain-geometry.d.ts +131 -0
- package/dist/site/terrain-geometry.d.ts.map +1 -0
- package/dist/site/terrain-geometry.js +259 -0
- package/dist/site/terrain-mesh.d.ts +49 -0
- package/dist/site/terrain-mesh.d.ts.map +1 -0
- package/dist/site/terrain-mesh.js +122 -0
- package/dist/site/terrain-renderer.d.ts +28 -0
- package/dist/site/terrain-renderer.d.ts.map +1 -0
- package/dist/site/terrain-renderer.js +69 -0
- package/dist/skylight/definition.d.ts.map +1 -1
- package/dist/skylight/definition.js +1 -0
- package/dist/skylight/tool.d.ts.map +1 -1
- package/dist/skylight/tool.js +16 -1
- package/dist/slab/definition.d.ts.map +1 -1
- package/dist/slab/definition.js +87 -10
- package/dist/slab/elevation-limit.d.ts +43 -0
- package/dist/slab/elevation-limit.d.ts.map +1 -0
- package/dist/slab/elevation-limit.js +124 -0
- package/dist/slab/floorplan-affordances.d.ts +16 -0
- package/dist/slab/floorplan-affordances.d.ts.map +1 -1
- package/dist/slab/geometry.d.ts.map +1 -1
- package/dist/slab/geometry.js +98 -5
- package/dist/slab/panel.d.ts.map +1 -1
- package/dist/slab/panel.js +82 -4
- package/dist/slab/parametrics.d.ts +1 -1
- package/dist/slab/parametrics.d.ts.map +1 -1
- package/dist/slab/parametrics.js +13 -1
- package/dist/slab/placement-ownership.d.ts +3 -0
- package/dist/slab/placement-ownership.d.ts.map +1 -0
- package/dist/slab/placement-ownership.js +3 -0
- package/dist/slab/quick-measurement.d.ts.map +1 -1
- package/dist/slab/quick-measurement.js +3 -2
- package/dist/slab/system.d.ts.map +1 -1
- package/dist/slab/system.js +14 -4
- package/dist/slab/tool.d.ts.map +1 -1
- package/dist/slab/tool.js +81 -23
- package/dist/solar-panel/definition.d.ts.map +1 -1
- package/dist/solar-panel/definition.js +1 -0
- package/dist/solar-panel/tool.d.ts.map +1 -1
- package/dist/solar-panel/tool.js +17 -1
- package/dist/spawn/definition.d.ts.map +1 -1
- package/dist/spawn/definition.js +1 -0
- package/dist/spawn/floorplan-affordances.d.ts.map +1 -1
- package/dist/spawn/floorplan-affordances.js +7 -4
- package/dist/spawn/floorplan-move.d.ts.map +1 -1
- package/dist/spawn/floorplan-move.js +8 -6
- package/dist/spawn/renderer.d.ts +4 -0
- package/dist/spawn/renderer.d.ts.map +1 -1
- package/dist/spawn/renderer.js +32 -18
- package/dist/spawn/tool.d.ts +2 -2
- package/dist/spawn/tool.d.ts.map +1 -1
- package/dist/spawn/tool.js +78 -11
- package/dist/stair/definition.d.ts.map +1 -1
- package/dist/stair/definition.js +15 -7
- package/dist/stair/destination.d.ts +16 -0
- package/dist/stair/destination.d.ts.map +1 -0
- package/dist/stair/destination.js +24 -0
- package/dist/stair/documentation.d.ts +8 -0
- package/dist/stair/documentation.d.ts.map +1 -0
- package/dist/stair/documentation.js +245 -0
- package/dist/stair/floor-stack.d.ts.map +1 -1
- package/dist/stair/floor-stack.js +38 -0
- package/dist/stair/floorplan-affordances.d.ts.map +1 -1
- package/dist/stair/floorplan-affordances.js +28 -9
- package/dist/stair/floorplan-move.d.ts +3 -5
- package/dist/stair/floorplan-move.d.ts.map +1 -1
- package/dist/stair/floorplan-move.js +14 -16
- package/dist/stair/floorplan.d.ts.map +1 -1
- package/dist/stair/floorplan.js +27 -14
- package/dist/stair/panel.d.ts.map +1 -1
- package/dist/stair/panel.js +35 -2
- package/dist/stair/renderer.d.ts.map +1 -1
- package/dist/stair/renderer.js +4 -3
- package/dist/structural-grid/coordination.d.ts +16 -0
- package/dist/structural-grid/coordination.d.ts.map +1 -0
- package/dist/structural-grid/coordination.js +105 -0
- package/dist/structural-grid/definition.d.ts +4 -0
- package/dist/structural-grid/definition.d.ts.map +1 -0
- package/dist/structural-grid/definition.js +51 -0
- package/dist/structural-grid/floorplan-tool.d.ts +16 -0
- package/dist/structural-grid/floorplan-tool.d.ts.map +1 -0
- package/dist/structural-grid/floorplan-tool.js +183 -0
- package/dist/structural-grid/floorplan.d.ts +3 -0
- package/dist/structural-grid/floorplan.d.ts.map +1 -0
- package/dist/structural-grid/floorplan.js +61 -0
- package/dist/structural-grid/index.d.ts +2 -0
- package/dist/structural-grid/index.d.ts.map +1 -0
- package/dist/structural-grid/index.js +1 -0
- package/dist/structural-grid/schema.d.ts +2 -0
- package/dist/structural-grid/schema.d.ts.map +1 -0
- package/dist/structural-grid/schema.js +1 -0
- package/dist/wall/construction-dimensions.d.ts +32 -0
- package/dist/wall/construction-dimensions.d.ts.map +1 -0
- package/dist/wall/construction-dimensions.js +1031 -0
- package/dist/wall/contextual-dimensions.d.ts +13 -0
- package/dist/wall/contextual-dimensions.d.ts.map +1 -0
- package/dist/wall/contextual-dimensions.js +221 -0
- package/dist/wall/definition.d.ts.map +1 -1
- package/dist/wall/definition.js +20 -1
- package/dist/wall/floorplan-affordances.d.ts.map +1 -1
- package/dist/wall/floorplan-affordances.js +23 -8
- package/dist/wall/floorplan-overrides.d.ts +9 -6
- package/dist/wall/floorplan-overrides.d.ts.map +1 -1
- package/dist/wall/floorplan-overrides.js +20 -11
- package/dist/wall/floorplan.d.ts +12 -3
- package/dist/wall/floorplan.d.ts.map +1 -1
- package/dist/wall/floorplan.js +121 -79
- package/dist/wall/measurement.d.ts.map +1 -1
- package/dist/wall/measurement.js +17 -4
- package/dist/wall/move-endpoint-tool.d.ts.map +1 -1
- package/dist/wall/move-endpoint-tool.js +74 -27
- package/dist/wall/move-shared.d.ts.map +1 -1
- package/dist/wall/move-shared.js +3 -2
- package/dist/wall/move-tool.d.ts.map +1 -1
- package/dist/wall/move-tool.js +15 -3
- package/dist/wall/paint.d.ts.map +1 -1
- package/dist/wall/paint.js +10 -6
- package/dist/wall/panel.d.ts.map +1 -1
- package/dist/wall/panel.js +32 -5
- package/dist/wall/parametrics.d.ts.map +1 -1
- package/dist/wall/parametrics.js +2 -0
- package/dist/wall/preview.d.ts +8 -0
- package/dist/wall/preview.d.ts.map +1 -0
- package/dist/wall/preview.js +39 -0
- package/dist/wall/quick-measurement.d.ts.map +1 -1
- package/dist/wall/quick-measurement.js +3 -2
- package/dist/wall/renderer.d.ts.map +1 -1
- package/dist/wall/renderer.js +7 -5
- package/dist/wall/system.d.ts +1 -1
- package/dist/wall/system.d.ts.map +1 -1
- package/dist/wall/system.js +37 -2
- package/dist/wall/tool.d.ts.map +1 -1
- package/dist/wall/tool.js +148 -96
- package/dist/wall/treatment-level-data.d.ts +14 -0
- package/dist/wall/treatment-level-data.d.ts.map +1 -0
- package/dist/wall/treatment-level-data.js +31 -0
- package/dist/wall/treatments.d.ts +8 -2
- package/dist/wall/treatments.d.ts.map +1 -1
- package/dist/wall/treatments.js +58 -15
- package/dist/window/contextual-dimensions.d.ts +3 -0
- package/dist/window/contextual-dimensions.d.ts.map +1 -0
- package/dist/window/contextual-dimensions.js +7 -0
- package/dist/window/definition.d.ts.map +1 -1
- package/dist/window/definition.js +15 -10
- package/dist/window/floorplan-affordances.d.ts +2 -5
- package/dist/window/floorplan-affordances.d.ts.map +1 -1
- package/dist/window/floorplan-affordances.js +9 -15
- package/dist/window/floorplan-move.d.ts.map +1 -1
- package/dist/window/floorplan-move.js +1 -1
- package/dist/window/floorplan.d.ts.map +1 -1
- package/dist/window/floorplan.js +7 -1
- package/dist/window/move-tool.d.ts.map +1 -1
- package/dist/window/move-tool.js +3 -3
- package/dist/window/panel.d.ts.map +1 -1
- package/dist/window/panel.js +4 -1
- package/dist/window/schema.d.ts +1 -1
- package/dist/window/schema.d.ts.map +1 -1
- package/dist/window/schema.js +1 -1
- package/dist/window/tool.d.ts.map +1 -1
- package/dist/window/tool.js +64 -7
- package/dist/window/window-math.d.ts +7 -3
- package/dist/window/window-math.d.ts.map +1 -1
- package/dist/window/window-math.js +8 -3
- package/dist/zone/contextual-dimensions.d.ts +3 -0
- package/dist/zone/contextual-dimensions.d.ts.map +1 -0
- package/dist/zone/contextual-dimensions.js +43 -0
- package/dist/zone/definition.d.ts.map +1 -1
- package/dist/zone/definition.js +9 -1
- package/dist/zone/floorplan-affordances.d.ts +36 -0
- package/dist/zone/floorplan-affordances.d.ts.map +1 -1
- package/dist/zone/floorplan.d.ts.map +1 -1
- package/dist/zone/floorplan.js +59 -3
- package/dist/zone/quantities-panel.d.ts.map +1 -1
- package/dist/zone/quantities-panel.js +48 -4
- package/dist/zone/room-clear-dimensions.d.ts +3 -0
- package/dist/zone/room-clear-dimensions.d.ts.map +1 -0
- package/dist/zone/room-clear-dimensions.js +406 -0
- package/dist/zone/room-documentation.d.ts +11 -0
- package/dist/zone/room-documentation.d.ts.map +1 -0
- package/dist/zone/room-documentation.js +97 -0
- package/package.json +7 -7
package/dist/spawn/renderer.js
CHANGED
|
@@ -1,29 +1,18 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
3
|
import { useLiveNodeOverrides, useLiveTransforms, useRegistry, } from '@pascal-app/core';
|
|
4
4
|
import { createDefaultMaterial, useNodeEvents, useViewer } from '@pascal-app/viewer';
|
|
5
5
|
import { useMemo, useRef } from 'react';
|
|
6
6
|
import { Color, Shape } from 'three';
|
|
7
7
|
const SPAWN_COLOR = new Color('#818cf8');
|
|
8
|
+
const disableRaycast = () => { };
|
|
8
9
|
/**
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* geometry and event surface. When the spawn definition lands
|
|
12
|
-
* in `builtinPlugin.nodes`, the Phase 0 dispatch shims switch the renderer
|
|
13
|
-
* here and the legacy one is short-circuited.
|
|
14
|
-
*
|
|
15
|
-
* Lives in `@pascal-app/nodes` (not viewer) so the kind owns its own render
|
|
16
|
-
* code. Phase 5's batch migration applies the same pattern to every node.
|
|
10
|
+
* Shared visible spawn model. Placement uses the same four meshes as the
|
|
11
|
+
* committed renderer so the orientation shown before click is authoritative.
|
|
17
12
|
*/
|
|
18
|
-
const
|
|
19
|
-
const ref = useRef(null);
|
|
13
|
+
const SpawnVisual = ({ ghost = false, layers, node, }) => {
|
|
20
14
|
const handlers = useNodeEvents(node, 'spawn');
|
|
21
|
-
const liveOverride = useLiveNodeOverrides((state) => state.get(node.id));
|
|
22
|
-
const effectiveNode = useMemo(() => (liveOverride ? { ...node, ...liveOverride } : node), [node, liveOverride]);
|
|
23
|
-
const liveTransform = useLiveTransforms((state) => state.get(node.id));
|
|
24
|
-
const walkthroughMode = useViewer((state) => state.walkthroughMode);
|
|
25
15
|
const shading = useViewer((state) => state.shading);
|
|
26
|
-
useRegistry(node.id, 'spawn', ref);
|
|
27
16
|
const material = useMemo(() => {
|
|
28
17
|
const next = createDefaultMaterial('#818cf8', 0.42, shading);
|
|
29
18
|
next.emissive?.copy(SPAWN_COLOR);
|
|
@@ -31,9 +20,14 @@ const SpawnRenderer = ({ node }) => {
|
|
|
31
20
|
next.emissiveIntensity = 0.08;
|
|
32
21
|
if ('metalness' in next)
|
|
33
22
|
next.metalness = 0.03;
|
|
23
|
+
if (ghost) {
|
|
24
|
+
next.transparent = true;
|
|
25
|
+
next.opacity = 0.5;
|
|
26
|
+
next.depthWrite = false;
|
|
27
|
+
}
|
|
34
28
|
next.needsUpdate = true;
|
|
35
29
|
return next;
|
|
36
|
-
}, [shading]);
|
|
30
|
+
}, [ghost, shading]);
|
|
37
31
|
const arrowShape = useMemo(() => {
|
|
38
32
|
const shape = new Shape();
|
|
39
33
|
shape.moveTo(0, 0.24);
|
|
@@ -42,6 +36,26 @@ const SpawnRenderer = ({ node }) => {
|
|
|
42
36
|
shape.closePath();
|
|
43
37
|
return shape;
|
|
44
38
|
}, []);
|
|
45
|
-
return (_jsxs(
|
|
39
|
+
return (_jsxs(_Fragment, { children: [_jsxs("mesh", { layers: layers, position: [0, 0.09, 0], raycast: ghost ? disableRaycast : undefined, rotation: [-Math.PI / 2, 0, 0], ...(ghost ? {} : handlers), children: [_jsx("ringGeometry", { args: [0.34, 0.48, 48] }), _jsx("primitive", { attach: "material", object: material })] }), _jsxs("mesh", { layers: layers, position: [0, 0.1, -0.52], raycast: ghost ? disableRaycast : undefined, rotation: [-Math.PI / 2, 0, 0], ...(ghost ? {} : handlers), children: [_jsx("shapeGeometry", { args: [arrowShape] }), _jsx("primitive", { attach: "material", object: material })] }), _jsxs("mesh", { layers: layers, position: [0, 0.41, 0], raycast: ghost ? disableRaycast : undefined, ...(ghost ? {} : handlers), children: [_jsx("boxGeometry", { args: [0.3, 0.54, 0.16] }), _jsx("primitive", { attach: "material", object: material })] }), _jsxs("mesh", { layers: layers, position: [0, 0.83, 0], raycast: ghost ? disableRaycast : undefined, ...(ghost ? {} : handlers), children: [_jsx("boxGeometry", { args: [0.18, 0.18, 0.18] }), _jsx("primitive", { attach: "material", object: material })] })] }));
|
|
40
|
+
};
|
|
41
|
+
export const SpawnPreview = ({ layers, node }) => (_jsx(SpawnVisual, { ghost: true, layers: layers, node: node }));
|
|
42
|
+
/**
|
|
43
|
+
* Registry-driven spawn renderer. Behaviorally identical to the legacy
|
|
44
|
+
* `@pascal-app/viewer/components/renderers/spawn/spawn-renderer.tsx` — same
|
|
45
|
+
* geometry and event surface. When the spawn definition lands
|
|
46
|
+
* in `builtinPlugin.nodes`, the Phase 0 dispatch shims switch the renderer
|
|
47
|
+
* here and the legacy one is short-circuited.
|
|
48
|
+
*
|
|
49
|
+
* Lives in `@pascal-app/nodes` (not viewer) so the kind owns its own render
|
|
50
|
+
* code. Phase 5's batch migration applies the same pattern to every node.
|
|
51
|
+
*/
|
|
52
|
+
const SpawnRenderer = ({ node }) => {
|
|
53
|
+
const ref = useRef(null);
|
|
54
|
+
const liveOverride = useLiveNodeOverrides((state) => state.get(node.id));
|
|
55
|
+
const effectiveNode = useMemo(() => (liveOverride ? { ...node, ...liveOverride } : node), [node, liveOverride]);
|
|
56
|
+
const liveTransform = useLiveTransforms((state) => state.get(node.id));
|
|
57
|
+
const walkthroughMode = useViewer((state) => state.walkthroughMode);
|
|
58
|
+
useRegistry(node.id, 'spawn', ref);
|
|
59
|
+
return (_jsx("group", { position: liveTransform?.position ?? effectiveNode.position, ref: ref, rotation: [0, liveTransform?.rotation ?? effectiveNode.rotation, 0], visible: !walkthroughMode && effectiveNode.visible !== false, children: _jsx(SpawnVisual, { node: effectiveNode }) }));
|
|
46
60
|
};
|
|
47
61
|
export default SpawnRenderer;
|
package/dist/spawn/tool.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Registry-driven spawn placement tool. Reads `activeLevelId` from useViewer
|
|
3
3
|
* directly (no props), broadcasts placement via store updates + SFX, and
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* shows the real spawn model as a translucent placement ghost, and supports
|
|
5
|
+
* R/T yaw before commit. Snapping is mode-driven (grid + Figma-style
|
|
6
6
|
* alignment "lines"), matching the shelf / column build tools.
|
|
7
7
|
*/
|
|
8
8
|
declare const SpawnTool: () => import("react").JSX.Element | null;
|
package/dist/spawn/tool.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool.d.ts","sourceRoot":"","sources":["../../src/spawn/tool.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"tool.d.ts","sourceRoot":"","sources":["../../src/spawn/tool.tsx"],"names":[],"mappings":"AAyCA;;;;;;GAMG;AACH,QAAA,MAAM,SAAS,0CA8Kd,CAAA;AAED,eAAe,SAAS,CAAA"}
|
package/dist/spawn/tool.js
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
-
import { collectAlignmentAnchors, emitter, SpawnNode, useScene, } from '@pascal-app/core';
|
|
4
|
-
import {
|
|
3
|
+
import { collectAlignmentAnchors, emitter, resolveSupportSlabPatch, SpawnNode, useScene, } from '@pascal-app/core';
|
|
4
|
+
import { EDITOR_LAYER, getFloorStackPreviewPosition, isAlignmentGuideActive, isGridSnapActive, isMagneticSnapActive, movementSfxStepKey, triggerSFX, useAlignmentGuides, useEditor, usePlacementPreview, } from '@pascal-app/editor';
|
|
5
5
|
import { useViewer } from '@pascal-app/viewer';
|
|
6
|
-
import { useEffect, useMemo, useRef } from 'react';
|
|
6
|
+
import { useEffect, useMemo, useRef, useState } from 'react';
|
|
7
7
|
import { getLevelLocalSnappedPosition, resolveAlignedFloorPlacement, } from '../shared/floor-placement';
|
|
8
|
+
import { SpawnPreview } from './renderer';
|
|
9
|
+
const ROTATION_STEP = Math.PI / 4;
|
|
8
10
|
function getExistingSpawnIds() {
|
|
9
11
|
const nodes = useScene.getState().nodes;
|
|
10
12
|
return Object.values(nodes)
|
|
@@ -15,23 +17,34 @@ function getExistingSpawnIds() {
|
|
|
15
17
|
/**
|
|
16
18
|
* Registry-driven spawn placement tool. Reads `activeLevelId` from useViewer
|
|
17
19
|
* directly (no props), broadcasts placement via store updates + SFX, and
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
+
* shows the real spawn model as a translucent placement ghost, and supports
|
|
21
|
+
* R/T yaw before commit. Snapping is mode-driven (grid + Figma-style
|
|
20
22
|
* alignment "lines"), matching the shelf / column build tools.
|
|
21
23
|
*/
|
|
22
24
|
const SpawnTool = () => {
|
|
23
25
|
const activeLevelId = useViewer((state) => state.selection.levelId);
|
|
24
26
|
const cursorRef = useRef(null);
|
|
25
27
|
const previousSnapRef = useRef(null);
|
|
28
|
+
const rotationRef = useRef(0);
|
|
29
|
+
const cursorVisibleRef = useRef(false);
|
|
30
|
+
const [cursorVisible, setCursorVisible] = useState(false);
|
|
26
31
|
// Default spawn for the footprint anchors the alignment solver reads.
|
|
27
32
|
const previewNode = useMemo(() => SpawnNode.parse({ name: 'Spawn Point', position: [0, 0, 0], rotation: 0 }), []);
|
|
28
33
|
useEffect(() => {
|
|
29
34
|
if (!activeLevelId)
|
|
30
35
|
return;
|
|
31
36
|
previousSnapRef.current = null;
|
|
37
|
+
rotationRef.current = 0;
|
|
38
|
+
cursorRef.current?.rotation.set(0, 0, 0);
|
|
39
|
+
cursorVisibleRef.current = false;
|
|
40
|
+
setCursorVisible(false);
|
|
32
41
|
const lastCursorRef = { current: null };
|
|
33
42
|
let alignmentCandidates = collectAlignmentAnchors(useScene.getState().nodes, previewNode.id);
|
|
34
43
|
const onGridMove = (event) => {
|
|
44
|
+
if (!cursorVisibleRef.current) {
|
|
45
|
+
cursorVisibleRef.current = true;
|
|
46
|
+
setCursorVisible(true);
|
|
47
|
+
}
|
|
35
48
|
const { position, guides } = resolveAlignedFloorPlacement({
|
|
36
49
|
node: previewNode,
|
|
37
50
|
rawX: event.localPosition[0],
|
|
@@ -46,11 +59,16 @@ const SpawnTool = () => {
|
|
|
46
59
|
const visualPosition = getFloorStackPreviewPosition({
|
|
47
60
|
node: previewNode,
|
|
48
61
|
position,
|
|
49
|
-
rotation:
|
|
62
|
+
rotation: rotationRef.current,
|
|
50
63
|
levelId: activeLevelId,
|
|
51
64
|
});
|
|
52
65
|
cursorRef.current?.position.set(...visualPosition);
|
|
53
66
|
lastCursorRef.current = position;
|
|
67
|
+
usePlacementPreview.getState().set({
|
|
68
|
+
...previewNode,
|
|
69
|
+
position,
|
|
70
|
+
rotation: rotationRef.current,
|
|
71
|
+
});
|
|
54
72
|
const nextSnapKey = movementSfxStepKey({
|
|
55
73
|
coords: [position[0], position[2]],
|
|
56
74
|
gridSnapActive: isGridSnapActive(),
|
|
@@ -68,10 +86,18 @@ const SpawnTool = () => {
|
|
|
68
86
|
const [existingSpawnId, ...duplicates] = getExistingSpawnIds();
|
|
69
87
|
let placedId;
|
|
70
88
|
if (existingSpawnId) {
|
|
89
|
+
const live = useScene.getState().nodes[existingSpawnId];
|
|
90
|
+
const effectiveSpawn = SpawnNode.parse({
|
|
91
|
+
...live,
|
|
92
|
+
parentId: activeLevelId,
|
|
93
|
+
position: next,
|
|
94
|
+
rotation: rotationRef.current,
|
|
95
|
+
});
|
|
71
96
|
useScene.getState().updateNode(existingSpawnId, {
|
|
72
97
|
parentId: activeLevelId,
|
|
73
98
|
position: next,
|
|
74
|
-
rotation:
|
|
99
|
+
rotation: rotationRef.current,
|
|
100
|
+
...resolveSupportSlabPatch(effectiveSpawn, useScene.getState().nodes),
|
|
75
101
|
});
|
|
76
102
|
if (duplicates.length > 0) {
|
|
77
103
|
useScene.getState().deleteNodes(duplicates);
|
|
@@ -82,28 +108,69 @@ const SpawnTool = () => {
|
|
|
82
108
|
const spawn = SpawnNode.parse({
|
|
83
109
|
name: 'Spawn Point',
|
|
84
110
|
position: next,
|
|
85
|
-
rotation:
|
|
111
|
+
rotation: rotationRef.current,
|
|
112
|
+
parentId: activeLevelId,
|
|
113
|
+
});
|
|
114
|
+
const committedSpawn = SpawnNode.parse({
|
|
115
|
+
...spawn,
|
|
116
|
+
...resolveSupportSlabPatch(spawn, useScene.getState().nodes),
|
|
86
117
|
});
|
|
87
|
-
useScene.getState().createNode(
|
|
88
|
-
placedId =
|
|
118
|
+
useScene.getState().createNode(committedSpawn, activeLevelId);
|
|
119
|
+
placedId = committedSpawn.id;
|
|
89
120
|
}
|
|
90
121
|
useViewer.getState().setSelection({ selectedIds: [placedId] });
|
|
91
122
|
triggerSFX('sfx:structure-build');
|
|
92
123
|
alignmentCandidates = collectAlignmentAnchors(useScene.getState().nodes, previewNode.id);
|
|
93
124
|
useAlignmentGuides.getState().clear();
|
|
125
|
+
usePlacementPreview.getState().clear();
|
|
94
126
|
useEditor.getState().setTool(null);
|
|
95
127
|
useEditor.getState().setMode('select');
|
|
96
128
|
};
|
|
129
|
+
const onKeyDown = (event) => {
|
|
130
|
+
const target = event.target;
|
|
131
|
+
if (event.repeat ||
|
|
132
|
+
event.metaKey ||
|
|
133
|
+
event.ctrlKey ||
|
|
134
|
+
event.altKey ||
|
|
135
|
+
target?.tagName === 'INPUT' ||
|
|
136
|
+
target?.tagName === 'TEXTAREA' ||
|
|
137
|
+
target?.isContentEditable) {
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
let delta = 0;
|
|
141
|
+
if (event.key === 'r' || event.key === 'R')
|
|
142
|
+
delta = ROTATION_STEP;
|
|
143
|
+
else if (event.key === 't' || event.key === 'T')
|
|
144
|
+
delta = -ROTATION_STEP;
|
|
145
|
+
else
|
|
146
|
+
return;
|
|
147
|
+
event.preventDefault();
|
|
148
|
+
event.stopPropagation();
|
|
149
|
+
rotationRef.current += delta;
|
|
150
|
+
if (cursorRef.current)
|
|
151
|
+
cursorRef.current.rotation.y = rotationRef.current;
|
|
152
|
+
if (lastCursorRef.current) {
|
|
153
|
+
usePlacementPreview.getState().set({
|
|
154
|
+
...previewNode,
|
|
155
|
+
position: lastCursorRef.current,
|
|
156
|
+
rotation: rotationRef.current,
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
triggerSFX('sfx:item-rotate');
|
|
160
|
+
};
|
|
97
161
|
emitter.on('grid:move', onGridMove);
|
|
98
162
|
emitter.on('grid:click', onGridClick);
|
|
163
|
+
window.addEventListener('keydown', onKeyDown, true);
|
|
99
164
|
return () => {
|
|
100
165
|
emitter.off('grid:move', onGridMove);
|
|
101
166
|
emitter.off('grid:click', onGridClick);
|
|
167
|
+
window.removeEventListener('keydown', onKeyDown, true);
|
|
102
168
|
useAlignmentGuides.getState().clear();
|
|
169
|
+
usePlacementPreview.getState().clear();
|
|
103
170
|
};
|
|
104
171
|
}, [activeLevelId, previewNode]);
|
|
105
172
|
if (!activeLevelId)
|
|
106
173
|
return null;
|
|
107
|
-
return _jsx(
|
|
174
|
+
return (_jsx("group", { ref: cursorRef, visible: cursorVisible, children: _jsx(SpawnPreview, { layers: EDITOR_LAYER, node: previewNode }) }));
|
|
108
175
|
};
|
|
109
176
|
export default SpawnTool;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"definition.d.ts","sourceRoot":"","sources":["../../src/stair/definition.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"definition.d.ts","sourceRoot":"","sources":["../../src/stair/definition.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,cAAc,EAQpB,MAAM,kBAAkB,CAAA;AAuZzB,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AAGpC;;;;GAIG;AACH,eAAO,MAAM,eAAe,EAAE,cAAc,CAAC,OAAO,SAAS,CAgH5D,CAAA"}
|
package/dist/stair/definition.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { StairNode as StairNodeSchema, stairFootprintAABB, } from '@pascal-app/core';
|
|
1
|
+
import { resolveStairTotalRise, StairNode as StairNodeSchema, stairFootprintAABB, useScene, } from '@pascal-app/core';
|
|
2
2
|
const MIN_CURVED_RISE = 0.3;
|
|
3
3
|
const MIN_CURVED_WIDTH = 0.4;
|
|
4
4
|
const MIN_CURVED_INNER_RADIUS_SPIRAL = 0.05;
|
|
@@ -21,10 +21,13 @@ const CURVED_INNER_RING_MIN = 0.05;
|
|
|
21
21
|
const STAIR_ROTATE_CORNER_OFFSET = 0.4;
|
|
22
22
|
const STAIR_ROTATE_RING_OFFSET = 0.08;
|
|
23
23
|
const STAIR_MOVE_FRONT_OFFSET = 0.35;
|
|
24
|
+
function readTotalRise(node) {
|
|
25
|
+
return Math.max(resolveStairTotalRise(node, useScene.getState().nodes), 0.1);
|
|
26
|
+
}
|
|
24
27
|
function readCurvedStairGeometry(node) {
|
|
25
28
|
const isSpiral = node.stairType === 'spiral';
|
|
26
29
|
const stepCount = Math.max(2, Math.round(node.stepCount ?? 10));
|
|
27
|
-
const totalRise =
|
|
30
|
+
const totalRise = readTotalRise(node);
|
|
28
31
|
const width = Math.max(node.width ?? 1, MIN_CURVED_WIDTH);
|
|
29
32
|
const minInnerRadius = isSpiral ? MIN_CURVED_INNER_RADIUS_SPIRAL : MIN_CURVED_INNER_RADIUS_CURVED;
|
|
30
33
|
const innerRadius = Math.max(minInnerRadius, node.innerRadius ?? 0.9);
|
|
@@ -61,7 +64,7 @@ function fallbackStraightStairMoveBounds(node) {
|
|
|
61
64
|
maxX: width / 2,
|
|
62
65
|
minZ: 0,
|
|
63
66
|
maxZ: depth,
|
|
64
|
-
height:
|
|
67
|
+
height: readTotalRise(node),
|
|
65
68
|
};
|
|
66
69
|
}
|
|
67
70
|
function readStraightStairMoveBounds(node, sceneApi) {
|
|
@@ -119,7 +122,7 @@ function curvedRiseHandle() {
|
|
|
119
122
|
axis: 'y',
|
|
120
123
|
anchor: 'min',
|
|
121
124
|
min: MIN_CURVED_RISE,
|
|
122
|
-
currentValue:
|
|
125
|
+
currentValue: readTotalRise,
|
|
123
126
|
apply: (_n, newRise) => ({ totalRise: newRise }),
|
|
124
127
|
placement: {
|
|
125
128
|
position: (n) => {
|
|
@@ -255,7 +258,7 @@ function stairRotateGizmoPosition(n) {
|
|
|
255
258
|
return [radius * Math.cos(angle), g.totalRise / 2, radius * Math.sin(angle)];
|
|
256
259
|
}
|
|
257
260
|
const width = Math.max(n.width ?? 1, MIN_CURVED_WIDTH);
|
|
258
|
-
const yMid =
|
|
261
|
+
const yMid = readTotalRise(n) / 2;
|
|
259
262
|
return [width / 2 + STAIR_ROTATE_CORNER_OFFSET, yMid, -STAIR_ROTATE_CORNER_OFFSET];
|
|
260
263
|
}
|
|
261
264
|
function stairRotateHandle() {
|
|
@@ -290,7 +293,7 @@ function stairRotateHandle() {
|
|
|
290
293
|
return (Math.hypot(width / 2 + STAIR_ROTATE_CORNER_OFFSET, STAIR_ROTATE_CORNER_OFFSET) +
|
|
291
294
|
STAIR_ROTATE_RING_OFFSET);
|
|
292
295
|
},
|
|
293
|
-
y: (n) =>
|
|
296
|
+
y: (n) => readTotalRise(n) / 2,
|
|
294
297
|
},
|
|
295
298
|
};
|
|
296
299
|
}
|
|
@@ -346,6 +349,11 @@ export const stairDefinition = {
|
|
|
346
349
|
schemaVersion: 1,
|
|
347
350
|
schema: StairNode,
|
|
348
351
|
category: 'structure',
|
|
352
|
+
extensions: {
|
|
353
|
+
'pascal:editor/floorplan': {
|
|
354
|
+
linkedLevelIds: (node) => node.toLevelId && node.toLevelId !== node.parentId ? [node.toLevelId] : [],
|
|
355
|
+
},
|
|
356
|
+
},
|
|
349
357
|
snapProfile: 'structural',
|
|
350
358
|
// A footprint with a clear front: you approach a stair from the low end,
|
|
351
359
|
// which sits on the -Z side of the run (the run ascends along +Z). Show the
|
|
@@ -377,7 +385,7 @@ export const stairDefinition = {
|
|
|
377
385
|
const aabb = stairFootprintAABB(node, nodes);
|
|
378
386
|
return aabb ? { shape: 'aabb', ...aabb } : null;
|
|
379
387
|
},
|
|
380
|
-
duplicable: true,
|
|
388
|
+
duplicable: { subtree: true },
|
|
381
389
|
deletable: true,
|
|
382
390
|
floorPlaced: {
|
|
383
391
|
footprints: (node, ctx) => ctx ? getStairFloorPlacedFootprints(node, ctx.nodes) : [],
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { AnyNode, StairNode } from '@pascal-app/core';
|
|
2
|
+
/**
|
|
3
|
+
* Computes the stair patch for a destination ("To") switch.
|
|
4
|
+
*
|
|
5
|
+
* Attaching to a deck clears any explicit custom rise (the rise follows the
|
|
6
|
+
* deck's elevation from now on) and disables the auto cutout — a deck stair
|
|
7
|
+
* lands ON its destination slab, not through it. Switching a deck-attached
|
|
8
|
+
* stair back to a level clears both again so the rise re-derives from the
|
|
9
|
+
* storey height, and restores `slabOpeningMode: 'destination'` — the
|
|
10
|
+
* placement default (the schema default is 'none', but the stair tool places
|
|
11
|
+
* ordinary stairs with 'destination', so that is what a level-destination
|
|
12
|
+
* stair regains). Plain level-to-level switches leave rise and opening mode
|
|
13
|
+
* alone.
|
|
14
|
+
*/
|
|
15
|
+
export declare function getStairDestinationUpdates(stair: StairNode, target: AnyNode | undefined, targetId: string): Partial<StairNode>;
|
|
16
|
+
//# sourceMappingURL=destination.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"destination.d.ts","sourceRoot":"","sources":["../../src/stair/destination.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAE1D;;;;;;;;;;;;GAYG;AACH,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,SAAS,EAChB,MAAM,EAAE,OAAO,GAAG,SAAS,EAC3B,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,SAAS,CAAC,CAUpB"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Computes the stair patch for a destination ("To") switch.
|
|
3
|
+
*
|
|
4
|
+
* Attaching to a deck clears any explicit custom rise (the rise follows the
|
|
5
|
+
* deck's elevation from now on) and disables the auto cutout — a deck stair
|
|
6
|
+
* lands ON its destination slab, not through it. Switching a deck-attached
|
|
7
|
+
* stair back to a level clears both again so the rise re-derives from the
|
|
8
|
+
* storey height, and restores `slabOpeningMode: 'destination'` — the
|
|
9
|
+
* placement default (the schema default is 'none', but the stair tool places
|
|
10
|
+
* ordinary stairs with 'destination', so that is what a level-destination
|
|
11
|
+
* stair regains). Plain level-to-level switches leave rise and opening mode
|
|
12
|
+
* alone.
|
|
13
|
+
*/
|
|
14
|
+
export function getStairDestinationUpdates(stair, target, targetId) {
|
|
15
|
+
if (target?.type === 'slab') {
|
|
16
|
+
return { deckSlabId: targetId, totalRise: undefined, slabOpeningMode: 'none' };
|
|
17
|
+
}
|
|
18
|
+
const updates = { toLevelId: targetId, deckSlabId: undefined };
|
|
19
|
+
if (stair.deckSlabId) {
|
|
20
|
+
updates.totalRise = undefined;
|
|
21
|
+
updates.slabOpeningMode = 'destination';
|
|
22
|
+
}
|
|
23
|
+
return updates;
|
|
24
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type FloorplanGeometry, type GeometryContext, type StairNode } from '@pascal-app/core';
|
|
2
|
+
import type { FloorplanStairArrowEntry, FloorplanStairEntry } from '@pascal-app/editor';
|
|
3
|
+
export type StairPlanDirection = 'up' | 'down';
|
|
4
|
+
export declare function resolveStairPlanDirection(stair: StairNode, activeLevelId: string | null | undefined): StairPlanDirection;
|
|
5
|
+
export declare function resolveStraightStairDirectionArrow(entry: FloorplanStairEntry, direction: StairPlanDirection): FloorplanStairArrowEntry | null;
|
|
6
|
+
export declare function stairPlanBreakStep(stepCount: number): number;
|
|
7
|
+
export declare function buildStairDocumentation(stair: StairNode, entry: FloorplanStairEntry, ctx: GeometryContext): FloorplanGeometry[];
|
|
8
|
+
//# sourceMappingURL=documentation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"documentation.d.ts","sourceRoot":"","sources":["../../src/stair/documentation.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,iBAAiB,EAEtB,KAAK,eAAe,EAGpB,KAAK,SAAS,EAEf,MAAM,kBAAkB,CAAA;AACzB,OAAO,KAAK,EACV,wBAAwB,EACxB,mBAAmB,EAEpB,MAAM,oBAAoB,CAAA;AAgB3B,MAAM,MAAM,kBAAkB,GAAG,IAAI,GAAG,MAAM,CAAA;AAE9C,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,SAAS,EAChB,aAAa,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GACvC,kBAAkB,CAUpB;AAED,wBAAgB,kCAAkC,CAChD,KAAK,EAAE,mBAAmB,EAC1B,SAAS,EAAE,kBAAkB,GAC5B,wBAAwB,GAAG,IAAI,CA0BjC;AAED,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAE5D;AAED,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,SAAS,EAChB,KAAK,EAAE,mBAAmB,EAC1B,GAAG,EAAE,eAAe,GACnB,iBAAiB,EAAE,CAYrB"}
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
import { resolveStairTotalRise, useScene, } from '@pascal-app/core';
|
|
2
|
+
import { floorplanGeometryMetadata, readFloorplanContext } from '@pascal-app/editor';
|
|
3
|
+
import { formatConstructionLength, } from '../shared/construction-length';
|
|
4
|
+
const ANNOTATION_OFFSET = 0.28;
|
|
5
|
+
const ANNOTATION_FONT_SIZE = 0.125;
|
|
6
|
+
const DIRECTION_FONT_SIZE = 0.16;
|
|
7
|
+
const BREAK_POSITION = 0.68;
|
|
8
|
+
const BREAK_ZIGZAG = 0.07;
|
|
9
|
+
const MIN_ARROW_HEAD = 0.14;
|
|
10
|
+
const MAX_ARROW_HEAD = 0.24;
|
|
11
|
+
export function resolveStairPlanDirection(stair, activeLevelId) {
|
|
12
|
+
if (activeLevelId &&
|
|
13
|
+
stair.toLevelId &&
|
|
14
|
+
stair.toLevelId !== stair.fromLevelId &&
|
|
15
|
+
activeLevelId === stair.toLevelId) {
|
|
16
|
+
return 'down';
|
|
17
|
+
}
|
|
18
|
+
return 'up';
|
|
19
|
+
}
|
|
20
|
+
export function resolveStraightStairDirectionArrow(entry, direction) {
|
|
21
|
+
const arrow = entry.arrow;
|
|
22
|
+
if (!arrow || direction === 'up')
|
|
23
|
+
return arrow;
|
|
24
|
+
const polyline = [...arrow.polyline].reverse();
|
|
25
|
+
const tip = polyline[polyline.length - 1];
|
|
26
|
+
const tail = polyline[polyline.length - 2];
|
|
27
|
+
if (!(tip && tail))
|
|
28
|
+
return null;
|
|
29
|
+
const bodyLength = distance(tail, tip);
|
|
30
|
+
if (bodyLength <= Number.EPSILON)
|
|
31
|
+
return null;
|
|
32
|
+
const headLength = clamp(bodyLength * 0.72, MIN_ARROW_HEAD, MAX_ARROW_HEAD);
|
|
33
|
+
const directionX = (tip.x - tail.x) / bodyLength;
|
|
34
|
+
const directionY = (tip.y - tail.y) / bodyLength;
|
|
35
|
+
const base = {
|
|
36
|
+
x: tip.x - directionX * headLength,
|
|
37
|
+
y: tip.y - directionY * headLength,
|
|
38
|
+
};
|
|
39
|
+
const halfWidth = headLength * 0.34;
|
|
40
|
+
return {
|
|
41
|
+
polyline,
|
|
42
|
+
head: [
|
|
43
|
+
tip,
|
|
44
|
+
{ x: base.x - directionY * halfWidth, y: base.y + directionX * halfWidth },
|
|
45
|
+
{ x: base.x + directionY * halfWidth, y: base.y - directionX * halfWidth },
|
|
46
|
+
],
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
export function stairPlanBreakStep(stepCount) {
|
|
50
|
+
return Math.max(1, Math.ceil(Math.max(1, Math.round(stepCount)) * BREAK_POSITION));
|
|
51
|
+
}
|
|
52
|
+
export function buildStairDocumentation(stair, entry, ctx) {
|
|
53
|
+
const activeLevelId = ctx.parent?.type === 'level' ? ctx.parent.id : stair.parentId;
|
|
54
|
+
const direction = resolveStairPlanDirection(stair, activeLevelId);
|
|
55
|
+
const unit = ctx.viewState?.unit ?? 'metric';
|
|
56
|
+
const floorplanContext = readFloorplanContext(ctx);
|
|
57
|
+
const profile = floorplanContext.purpose === 'document' ? 'document' : 'editor';
|
|
58
|
+
const metricNotation = floorplanContext.metricNotation;
|
|
59
|
+
const stroke = ctx.viewState?.palette.measurementStroke ?? '#334155';
|
|
60
|
+
return stair.stairType === 'straight'
|
|
61
|
+
? buildStraightDocumentation(stair, entry, direction, unit, profile, metricNotation, stroke)
|
|
62
|
+
: buildCurvedDocumentation(stair, direction, unit, profile, metricNotation, stroke);
|
|
63
|
+
}
|
|
64
|
+
function buildStraightDocumentation(stair, entry, direction, unit, profile, metricNotation, stroke) {
|
|
65
|
+
const geometries = [];
|
|
66
|
+
const arrow = resolveStraightStairDirectionArrow(entry, direction);
|
|
67
|
+
const arrowStart = arrow?.polyline[0];
|
|
68
|
+
const arrowNext = arrow?.polyline[1];
|
|
69
|
+
if (arrowStart && arrowNext) {
|
|
70
|
+
const arrowDirection = normalizedDirection(arrowStart, arrowNext);
|
|
71
|
+
const labelPoint = arrowDirection
|
|
72
|
+
? {
|
|
73
|
+
x: arrowStart.x - arrowDirection.y * 0.18,
|
|
74
|
+
y: arrowStart.y + arrowDirection.x * 0.18,
|
|
75
|
+
}
|
|
76
|
+
: arrowStart;
|
|
77
|
+
geometries.push(annotationText(labelPoint, direction === 'up' ? 'UP' : 'DN', DIRECTION_FONT_SIZE, stroke));
|
|
78
|
+
}
|
|
79
|
+
let railNotePlaced = false;
|
|
80
|
+
for (const segmentEntry of entry.segments) {
|
|
81
|
+
if (segmentEntry.segment.segmentType !== 'stair')
|
|
82
|
+
continue;
|
|
83
|
+
const frame = segmentFrame(segmentEntry);
|
|
84
|
+
if (!frame)
|
|
85
|
+
continue;
|
|
86
|
+
const segment = segmentEntry.segment;
|
|
87
|
+
const riserCount = Math.max(1, Math.round(segment.stepCount));
|
|
88
|
+
const riserHeight = segment.height / riserCount;
|
|
89
|
+
const treadDepth = segment.length / riserCount;
|
|
90
|
+
const rightAnchor = {
|
|
91
|
+
x: frame.rightMid.x + frame.widthDirection.x * ANNOTATION_OFFSET,
|
|
92
|
+
y: frame.rightMid.y + frame.widthDirection.y * ANNOTATION_OFFSET,
|
|
93
|
+
};
|
|
94
|
+
geometries.push(annotationText(rightAnchor, `${riserCount} R @ ${formatConstructionLength(riserHeight, unit, profile, { metricNotation })} · T ${formatConstructionLength(treadDepth, unit, profile, { metricNotation })} · CLR W ${formatConstructionLength(segment.width, unit, profile, { metricNotation })}`, ANNOTATION_FONT_SIZE, stroke), buildStraightBreakLine(segmentEntry, stroke));
|
|
95
|
+
if (!railNotePlaced && stair.railingMode !== 'none') {
|
|
96
|
+
const leftAnchor = {
|
|
97
|
+
x: frame.leftMid.x - frame.widthDirection.x * ANNOTATION_OFFSET,
|
|
98
|
+
y: frame.leftMid.y - frame.widthDirection.y * ANNOTATION_OFFSET,
|
|
99
|
+
};
|
|
100
|
+
geometries.push(annotationText(leftAnchor, `RAIL ${stair.railingMode.toLocaleUpperCase()} @ ${formatConstructionLength(stair.railingHeight, unit, profile, { metricNotation })}`, ANNOTATION_FONT_SIZE, stroke));
|
|
101
|
+
railNotePlaced = true;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return geometries;
|
|
105
|
+
}
|
|
106
|
+
function buildCurvedDocumentation(stair, direction, unit, profile, metricNotation, stroke) {
|
|
107
|
+
const stairType = stair.stairType === 'spiral' ? 'spiral' : 'curved';
|
|
108
|
+
const stepCount = Math.max(stairType === 'spiral' ? 6 : 4, Math.round(stair.stepCount));
|
|
109
|
+
const sweep = normalizedSweep(stair);
|
|
110
|
+
const startAngle = -stair.rotation - sweep / 2;
|
|
111
|
+
const endAngle = startAngle + sweep;
|
|
112
|
+
const innerRadius = Math.max(stairType === 'spiral' ? 0.05 : 0.2, stair.innerRadius);
|
|
113
|
+
const outerRadius = innerRadius + stair.width;
|
|
114
|
+
const walkingRadius = innerRadius + stair.width / 2;
|
|
115
|
+
const riserHeight = resolveStairTotalRise(stair, useScene.getState().nodes) / stepCount;
|
|
116
|
+
const treadDepth = (Math.abs(sweep) * walkingRadius) / stepCount;
|
|
117
|
+
const center = { x: stair.position[0], y: stair.position[2] };
|
|
118
|
+
const noteAngle = (startAngle + endAngle) / 2;
|
|
119
|
+
const notePoint = arcPoint(center, outerRadius + ANNOTATION_OFFSET, noteAngle);
|
|
120
|
+
const directionAngle = direction === 'up' ? startAngle + sweep * 0.18 : endAngle - sweep * 0.18;
|
|
121
|
+
const directionPoint = arcPoint(center, walkingRadius, directionAngle);
|
|
122
|
+
const breakAngle = startAngle + sweep * BREAK_POSITION;
|
|
123
|
+
const geometries = [
|
|
124
|
+
annotationText(notePoint, `${stepCount} R @ ${formatConstructionLength(riserHeight, unit, profile, { metricNotation })} · T(CL) ${formatConstructionLength(treadDepth, unit, profile, { metricNotation })} · CLR W ${formatConstructionLength(stair.width, unit, profile, { metricNotation })}`, ANNOTATION_FONT_SIZE, stroke),
|
|
125
|
+
annotationText(directionPoint, direction === 'up' ? 'UP' : 'DN', DIRECTION_FONT_SIZE, stroke),
|
|
126
|
+
buildCurvedBreakLine(center, innerRadius, outerRadius, breakAngle, stroke),
|
|
127
|
+
];
|
|
128
|
+
if (stair.railingMode !== 'none') {
|
|
129
|
+
geometries.push(annotationText(arcPoint(center, outerRadius + ANNOTATION_OFFSET * 2, noteAngle), `RAIL ${stair.railingMode.toLocaleUpperCase()} @ ${formatConstructionLength(stair.railingHeight, unit, profile, { metricNotation })}`, ANNOTATION_FONT_SIZE, stroke));
|
|
130
|
+
}
|
|
131
|
+
return geometries;
|
|
132
|
+
}
|
|
133
|
+
function buildStraightBreakLine(segmentEntry, stroke) {
|
|
134
|
+
const [backLeft, backRight, frontRight, frontLeft] = segmentEntry.innerPolygon;
|
|
135
|
+
if (!(backLeft && backRight && frontRight && frontLeft)) {
|
|
136
|
+
return { kind: 'group', children: [] };
|
|
137
|
+
}
|
|
138
|
+
const left = interpolate(backLeft, frontLeft, BREAK_POSITION);
|
|
139
|
+
const right = interpolate(backRight, frontRight, BREAK_POSITION);
|
|
140
|
+
const travel = normalizedDirection(backLeft, frontLeft) ?? { x: 0, y: 1 };
|
|
141
|
+
return {
|
|
142
|
+
kind: 'polyline',
|
|
143
|
+
points: [
|
|
144
|
+
toTuple(left),
|
|
145
|
+
offset(interpolate(left, right, 0.42), travel, BREAK_ZIGZAG),
|
|
146
|
+
offset(interpolate(left, right, 0.5), travel, -BREAK_ZIGZAG),
|
|
147
|
+
offset(interpolate(left, right, 0.58), travel, BREAK_ZIGZAG),
|
|
148
|
+
toTuple(right),
|
|
149
|
+
],
|
|
150
|
+
fill: 'none',
|
|
151
|
+
stroke,
|
|
152
|
+
strokeWidth: 1.5,
|
|
153
|
+
vectorEffect: 'non-scaling-stroke',
|
|
154
|
+
metadata: floorplanGeometryMetadata({ annotationRole: 'stair-annotation' }),
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
function buildCurvedBreakLine(center, innerRadius, outerRadius, angle, stroke) {
|
|
158
|
+
const radial = { x: Math.cos(angle), y: Math.sin(angle) };
|
|
159
|
+
const tangent = { x: -radial.y, y: radial.x };
|
|
160
|
+
const pointAt = (t, tangentOffset = 0) => {
|
|
161
|
+
const radius = innerRadius + (outerRadius - innerRadius) * t;
|
|
162
|
+
return [
|
|
163
|
+
center.x + radial.x * radius + tangent.x * tangentOffset,
|
|
164
|
+
center.y + radial.y * radius + tangent.y * tangentOffset,
|
|
165
|
+
];
|
|
166
|
+
};
|
|
167
|
+
return {
|
|
168
|
+
kind: 'polyline',
|
|
169
|
+
points: [
|
|
170
|
+
pointAt(0),
|
|
171
|
+
pointAt(0.42, BREAK_ZIGZAG),
|
|
172
|
+
pointAt(0.5, -BREAK_ZIGZAG),
|
|
173
|
+
pointAt(0.58, BREAK_ZIGZAG),
|
|
174
|
+
pointAt(1),
|
|
175
|
+
],
|
|
176
|
+
fill: 'none',
|
|
177
|
+
stroke,
|
|
178
|
+
strokeWidth: 1.5,
|
|
179
|
+
vectorEffect: 'non-scaling-stroke',
|
|
180
|
+
metadata: floorplanGeometryMetadata({ annotationRole: 'stair-annotation' }),
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
function annotationText(point, text, fontSize, fill) {
|
|
184
|
+
return {
|
|
185
|
+
kind: 'text',
|
|
186
|
+
x: point.x,
|
|
187
|
+
y: point.y,
|
|
188
|
+
text,
|
|
189
|
+
fontSize,
|
|
190
|
+
fill,
|
|
191
|
+
stroke: '#ffffff',
|
|
192
|
+
strokeWidth: fontSize * 0.22,
|
|
193
|
+
paintOrder: 'stroke',
|
|
194
|
+
fontFamily: 'ui-monospace, SFMono-Regular, Menlo, monospace',
|
|
195
|
+
fontWeight: 650,
|
|
196
|
+
textAnchor: 'middle',
|
|
197
|
+
dominantBaseline: 'central',
|
|
198
|
+
upright: true,
|
|
199
|
+
metadata: floorplanGeometryMetadata({ annotationRole: 'stair-annotation' }),
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
function segmentFrame(segmentEntry) {
|
|
203
|
+
const [backLeft, backRight, frontRight, frontLeft] = segmentEntry.polygon;
|
|
204
|
+
if (!(backLeft && backRight && frontRight && frontLeft))
|
|
205
|
+
return null;
|
|
206
|
+
const widthDirection = normalizedDirection(backLeft, backRight);
|
|
207
|
+
if (!widthDirection)
|
|
208
|
+
return null;
|
|
209
|
+
return {
|
|
210
|
+
widthDirection,
|
|
211
|
+
leftMid: interpolate(backLeft, frontLeft, 0.5),
|
|
212
|
+
rightMid: interpolate(backRight, frontRight, 0.5),
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
function normalizedSweep(stair) {
|
|
216
|
+
const defaultSweep = stair.stairType === 'spiral' ? Math.PI * 2 : Math.PI / 2;
|
|
217
|
+
const sweep = stair.sweepAngle ?? defaultSweep;
|
|
218
|
+
if (Math.abs(sweep) < Math.PI * 2)
|
|
219
|
+
return sweep;
|
|
220
|
+
return Math.sign(sweep || 1) * (Math.PI * 2 - 0.001);
|
|
221
|
+
}
|
|
222
|
+
function arcPoint(center, radius, angle) {
|
|
223
|
+
return { x: center.x + Math.cos(angle) * radius, y: center.y + Math.sin(angle) * radius };
|
|
224
|
+
}
|
|
225
|
+
function normalizedDirection(start, end) {
|
|
226
|
+
const dx = end.x - start.x;
|
|
227
|
+
const dy = end.y - start.y;
|
|
228
|
+
const length = Math.hypot(dx, dy);
|
|
229
|
+
return length <= Number.EPSILON ? null : { x: dx / length, y: dy / length };
|
|
230
|
+
}
|
|
231
|
+
function interpolate(start, end, t) {
|
|
232
|
+
return { x: start.x + (end.x - start.x) * t, y: start.y + (end.y - start.y) * t };
|
|
233
|
+
}
|
|
234
|
+
function offset(point, direction, amount) {
|
|
235
|
+
return [point.x + direction.x * amount, point.y + direction.y * amount];
|
|
236
|
+
}
|
|
237
|
+
function toTuple(point) {
|
|
238
|
+
return [point.x, point.y];
|
|
239
|
+
}
|
|
240
|
+
function distance(first, second) {
|
|
241
|
+
return Math.hypot(second.x - first.x, second.y - first.y);
|
|
242
|
+
}
|
|
243
|
+
function clamp(value, min, max) {
|
|
244
|
+
return Math.min(max, Math.max(min, value));
|
|
245
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"floor-stack.d.ts","sourceRoot":"","sources":["../../src/stair/floor-stack.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,OAAO,EACP,SAAS,EACT,oBAAoB,EACpB,SAAS,EACT,gBAAgB,EACjB,MAAM,kBAAkB,CAAA;AAEzB,KAAK,gBAAgB,GAAG;IACtB,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;IAClC,QAAQ,EAAE,MAAM,CAAA;CACjB,CAAA;AAED,wBAAgB,6BAA6B,CAC3C,KAAK,EAAE,SAAS,EAChB,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,GAC1C,oBAAoB,EAAE,
|
|
1
|
+
{"version":3,"file":"floor-stack.d.ts","sourceRoot":"","sources":["../../src/stair/floor-stack.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,OAAO,EACP,SAAS,EACT,oBAAoB,EACpB,SAAS,EACT,gBAAgB,EACjB,MAAM,kBAAkB,CAAA;AAEzB,KAAK,gBAAgB,GAAG;IACtB,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;IAClC,QAAQ,EAAE,MAAM,CAAA;CACjB,CAAA;AAED,wBAAgB,6BAA6B,CAC3C,KAAK,EAAE,SAAS,EAChB,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,GAC1C,oBAAoB,EAAE,CAUxB;AA+CD,wBAAgB,oCAAoC,CAClD,KAAK,EAAE,SAAS,EAChB,QAAQ,EAAE,SAAS,gBAAgB,EAAE,GACpC,oBAAoB,EAAE,CA4BxB;AAED,wBAAgB,uCAAuC,CACrD,QAAQ,EAAE,SAAS,gBAAgB,EAAE,GACpC,gBAAgB,EAAE,CAgDpB"}
|