@pascal-app/editor 1.1.0 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (260) hide show
  1. package/package.json +9 -15
  2. package/src/components/editor/action-menu-button.tsx +1 -1
  3. package/src/components/editor/alignment-3d-guide-layer.tsx +1 -1
  4. package/src/components/editor/custom-camera-controls.tsx +11 -11
  5. package/src/components/editor/editor-layout-v2.tsx +1 -1
  6. package/src/components/editor/elevation-3d-guide-layer.tsx +1 -1
  7. package/src/components/editor/first-person-controls.tsx +20 -1981
  8. package/src/components/editor/floating-action-menu.tsx +1 -1
  9. package/src/components/editor/floating-building-action-menu.tsx +1 -1
  10. package/src/components/editor/floor-region-controls.tsx +6 -2
  11. package/src/components/editor/floorplan-navigation-presentation.test.ts +0 -40
  12. package/src/components/editor/floorplan-navigation-presentation.ts +0 -66
  13. package/src/components/editor/floorplan-panel.tsx +26 -22
  14. package/src/components/editor/floorplan-wall-typing-keys.ts +1 -1
  15. package/src/components/editor/follow-pascal.test.tsx +1 -2
  16. package/src/components/editor/follow-pascal.tsx +1 -1
  17. package/src/components/editor/footprint-height-handle.tsx +1 -1
  18. package/src/components/editor/group-actions.ts +1 -2
  19. package/src/components/editor/group-floating-action-menu.tsx +1 -1
  20. package/src/components/editor/group-move-3d.ts +1 -2
  21. package/src/components/editor/group-rotate-handle.tsx +1 -2
  22. package/src/components/editor/handles/use-handle-drag.ts +1 -2
  23. package/src/components/editor/index.tsx +24 -14
  24. package/src/components/editor/inspector-extension-actions.tsx +1 -1
  25. package/src/components/editor/node-arrow-handles.tsx +1 -1
  26. package/src/components/editor/open-wall-ends-3d-layer.tsx +1 -1
  27. package/src/components/editor/opening-guides-3d-layer.tsx +1 -1
  28. package/src/components/editor/room-controls.tsx +7 -4
  29. package/src/components/editor/room-handles-2d.tsx +2 -3
  30. package/src/components/editor/room-handles.tsx +1 -2
  31. package/src/components/editor/room-highlight.tsx +6 -105
  32. package/src/components/editor/room-labels.test.ts +8 -822
  33. package/src/components/editor/room-labels.tsx +40 -1671
  34. package/src/components/editor/room-webgpu-materials.test.ts +1 -1
  35. package/src/components/editor/selection-manager.tsx +5 -3
  36. package/src/components/editor/site-edge-labels.tsx +1 -1
  37. package/src/components/editor/snapshot-capture-overlay.tsx +2 -5
  38. package/src/components/editor/use-floorplan-background-placement.ts +2 -1
  39. package/src/components/editor/views/plugins-view.tsx +1 -1
  40. package/src/components/editor/views/view-bar.tsx +9 -9
  41. package/src/components/editor/wall-measurement-label.tsx +1 -1
  42. package/src/components/editor/wall-move-side-handles.tsx +1 -1
  43. package/src/components/editor/wall-pull-grip.tsx +2 -2
  44. package/src/components/editor-2d/floorplan-group-move.tsx +2 -3
  45. package/src/components/editor-2d/floorplan-measurement-tool-layer.tsx +1 -1
  46. package/src/components/editor-2d/floorplan-open-wall-ends-layer.tsx +1 -1
  47. package/src/components/editor-2d/floorplan-registry-move-overlay.tsx +1 -2
  48. package/src/components/editor-2d/renderers/floorplan-annotation-layout.test.ts +0 -37
  49. package/src/components/editor-2d/renderers/floorplan-annotation-layout.ts +0 -30
  50. package/src/components/editor-2d/renderers/floorplan-dimension-edit-overlay.tsx +13 -3
  51. package/src/components/editor-2d/renderers/floorplan-placement-preview-layer.tsx +1 -2
  52. package/src/components/editor-2d/renderers/floorplan-registry-layer.test.ts +8 -10
  53. package/src/components/editor-2d/renderers/floorplan-registry-layer.tsx +25 -33
  54. package/src/components/systems/roof/roof-edit-system.tsx +4 -3
  55. package/src/components/tools/distribution/distribution-run-tool.tsx +1 -1
  56. package/src/components/tools/item/placement-history.test.tsx +1 -1
  57. package/src/components/tools/item/use-placement-coordinator.tsx +2 -3
  58. package/src/components/tools/paint-region/wall-paint-region-tool.tsx +6 -2
  59. package/src/components/tools/registry/move-registry-node-tool.tsx +1 -2
  60. package/src/components/tools/shared/cursor-sphere.tsx +1 -1
  61. package/src/components/tools/shared/draft-measurement-label.tsx +1 -1
  62. package/src/components/tools/shared/placement-box.tsx +1 -1
  63. package/src/components/tools/shared/placement-dimension-guides.tsx +1 -1
  64. package/src/components/tools/site/terrain-brush-cursor.tsx +1 -1
  65. package/src/components/ui/action-menu/camera-actions.tsx +2 -2
  66. package/src/components/ui/action-menu/control-modes.tsx +1 -1
  67. package/src/components/ui/action-menu/follow-pascal-pill.tsx +1 -1
  68. package/src/components/ui/action-menu/index.tsx +3 -3
  69. package/src/components/ui/action-menu/measurement-control.tsx +3 -3
  70. package/src/components/ui/action-menu/placement.ts +0 -18
  71. package/src/components/ui/action-menu/point-ask-button.tsx +1 -1
  72. package/src/components/ui/action-menu/view-toggles.tsx +5 -5
  73. package/src/components/ui/controls/finish-swatch.tsx +1 -1
  74. package/src/components/ui/controls/material-paint-panel.tsx +2 -2
  75. package/src/components/ui/controls/scene-material-list.tsx +2 -2
  76. package/src/components/ui/controls/select-control.tsx +1 -1
  77. package/src/components/ui/controls/terrain-sculpt-panel.tsx +1 -1
  78. package/src/components/ui/floating-level-selector.tsx +3 -3
  79. package/src/components/ui/helpers/contextual-helper-panel.tsx +1 -1
  80. package/src/components/ui/helpers/helper-manager.test.tsx +1 -1
  81. package/src/components/ui/helpers/helper-manager.tsx +1 -1
  82. package/src/components/ui/level-duplicate-dialog.tsx +1 -1
  83. package/src/components/ui/panels/collections/collections-popover.tsx +2 -2
  84. package/src/components/ui/panels/floor-foundation-panel.tsx +2 -2
  85. package/src/components/ui/panels/floor-opening-panel.tsx +4 -4
  86. package/src/components/ui/panels/node-display.ts +1 -1
  87. package/src/components/ui/panels/panel-manager.tsx +1 -1
  88. package/src/components/ui/panels/panel-wrapper.tsx +1 -1
  89. package/src/components/ui/panels/parametric-inspector.tsx +1 -1
  90. package/src/components/ui/panels/room-construction-rows.tsx +6 -6
  91. package/src/components/ui/panels/room-name-options.ts +1 -5
  92. package/src/components/ui/panels/room-panel.tsx +6 -8
  93. package/src/components/ui/primitives/color-dot.tsx +2 -2
  94. package/src/components/ui/primitives/opacity-control.tsx +2 -2
  95. package/src/components/ui/primitives/sidebar.tsx +3 -3
  96. package/src/components/ui/right-stack.tsx +1 -1
  97. package/src/components/ui/sidebar/icon-rail.tsx +1 -1
  98. package/src/components/ui/sidebar/panels/items-panel/function-tree-panel.tsx +1 -1
  99. package/src/components/ui/sidebar/panels/settings-panel/audio-settings-dialog.tsx +2 -2
  100. package/src/components/ui/sidebar/panels/settings-panel/construction-animation-setting.tsx +1 -1
  101. package/src/components/ui/sidebar/panels/settings-panel/index.tsx +2 -2
  102. package/src/components/ui/sidebar/panels/settings-panel/keyboard-shortcuts-dialog.tsx +1 -1
  103. package/src/components/ui/sidebar/panels/settings-panel/load-build-dialog.tsx +1 -1
  104. package/src/components/ui/sidebar/panels/settings-panel/print-export-button.tsx +1 -1
  105. package/src/components/ui/sidebar/panels/site-panel/building-tree-node.tsx +1 -1
  106. package/src/components/ui/sidebar/panels/site-panel/index.tsx +2 -2
  107. package/src/components/ui/sidebar/panels/site-panel/inline-rename-input.tsx +1 -1
  108. package/src/components/ui/sidebar/panels/site-panel/level-tree-node.tsx +1 -1
  109. package/src/components/ui/sidebar/panels/site-panel/roof-tree-node.tsx +46 -7
  110. package/src/components/ui/sidebar/panels/site-panel/tree-node-actions.tsx +1 -1
  111. package/src/components/ui/sidebar/panels/site-panel/tree-node-drag.tsx +14 -5
  112. package/src/components/ui/sidebar/panels/site-panel/unit-tree-node.tsx +2 -2
  113. package/src/components/ui/sidebar/panels/zone-panel/index.tsx +3 -3
  114. package/src/components/ui/sidebar/tab-bar.tsx +1 -1
  115. package/src/components/ui/wall-type/wall-type-editor-dialog.tsx +1 -1
  116. package/src/components/ui/wall-type/wall-type-menu.tsx +1 -1
  117. package/src/components/viewer-overlay.tsx +1 -2
  118. package/src/hooks/use-auto-frame.ts +1 -2
  119. package/src/hooks/use-keyboard.ts +1 -2
  120. package/src/hooks/use-selected-room.ts +5 -7
  121. package/src/i18n/floor-footprint-name.ts +1 -1
  122. package/src/i18n/locales/en/messages.po +180 -182
  123. package/src/i18n/locales/es/messages.po +180 -182
  124. package/src/i18n/locales/fr/messages.po +180 -182
  125. package/src/i18n/locales/ja/messages.po +180 -182
  126. package/src/i18n/locales/zh-CN/messages.po +180 -182
  127. package/src/i18n/locales.test.ts +1 -1
  128. package/src/index.tsx +109 -131
  129. package/src/lib/below-grade.test.tsx +4 -4
  130. package/src/lib/camera-facing.test.ts +1 -1
  131. package/src/lib/camera-facing.ts +2 -3
  132. package/src/lib/editor-level-display.ts +1 -1
  133. package/src/lib/floor-footprints.test.ts +2 -2
  134. package/src/lib/floor-opening-draft.ts +1 -1
  135. package/src/lib/floorplan/annotation-visibility.test.ts +1 -1
  136. package/src/lib/floorplan/annotation-visibility.ts +1 -1
  137. package/src/lib/floorplan/floorplan-export.test.ts +1 -1
  138. package/src/lib/floorplan/floorplan-export.tsx +8 -11
  139. package/src/lib/floorplan/floorplan-extension.ts +4 -157
  140. package/src/lib/floorplan/floorplan-mode.ts +2 -1
  141. package/src/lib/floorplan/floorplan-pdfkit-renderer.test.ts +1 -1
  142. package/src/lib/floorplan/floorplan-pdfkit-renderer.ts +8 -6
  143. package/src/lib/floorplan/floorplan-plugin-install.test.tsx +3 -4
  144. package/src/lib/floorplan/geometry.ts +2 -112
  145. package/src/lib/floorplan/index.ts +0 -9
  146. package/src/lib/floorplan/items.ts +2 -1
  147. package/src/lib/floorplan/schedules.ts +6 -3
  148. package/src/lib/floorplan/sheet-export.ts +7 -3
  149. package/src/lib/floorplan/site-plan/site-parts.ts +7 -1
  150. package/src/lib/floorplan/site-plan/site-plan-layer.tsx +1 -1
  151. package/src/lib/follow-pascal-presentation.ts +1 -1
  152. package/src/lib/glb-export.ts +1 -1
  153. package/src/lib/material-paint.ts +1 -1
  154. package/src/lib/measurements.test.ts +2 -1
  155. package/src/lib/mezzanine-selection.test.ts +1 -1
  156. package/src/lib/paint-region-mode.ts +1 -1
  157. package/src/lib/point-ask/session.ts +1 -2
  158. package/src/lib/roof-duplication.test.ts +100 -0
  159. package/src/lib/roof-duplication.ts +30 -5
  160. package/src/lib/room-handle-drag.ts +2 -12
  161. package/src/lib/room-name-catalog.test.ts +2 -1
  162. package/src/lib/room-name-messages.test.ts +2 -1
  163. package/src/lib/room-name-messages.ts +1 -118
  164. package/src/lib/room-name-storage.test.ts +2 -1
  165. package/src/lib/room-selection-commands.ts +2 -2
  166. package/src/lib/room-selection.test.ts +6 -6
  167. package/src/lib/room-transform-session.ts +1 -2
  168. package/src/lib/room-zone-routing.ts +2 -2
  169. package/src/lib/selection-routing.test.ts +0 -28
  170. package/src/lib/selection-routing.ts +1 -40
  171. package/src/lib/sfx-bus.ts +8 -32
  172. package/src/lib/sfx-player.test.ts +72 -1
  173. package/src/lib/sfx-player.ts +49 -337
  174. package/src/lib/viewer-selection.test.ts +38 -10
  175. package/src/lib/wall-pull.test.ts +1 -1
  176. package/src/lib/wall-pull.ts +1 -27
  177. package/src/store/use-editor.tsx +17 -26
  178. package/src/store/use-floorplan-annotation-visibility.ts +5 -5
  179. package/src/store/use-wall-region-handles-selection.ts +1 -2
  180. package/src/components/editor/__bench__/room-label-placement.bench.ts +0 -108
  181. package/src/components/editor/first-person/build-collider-world.test.ts +0 -596
  182. package/src/components/editor/first-person/build-collider-world.ts +0 -549
  183. package/src/components/editor/first-person/ground-holes.test.ts +0 -128
  184. package/src/components/editor/first-person/ground-holes.ts +0 -130
  185. package/src/components/editor/first-person/mechanism-targets.test.ts +0 -162
  186. package/src/components/editor/first-person/mechanism-targets.ts +0 -88
  187. package/src/components/editor/first-person/terrain-collider.test.ts +0 -132
  188. package/src/components/editor/first-person/terrain-collider.ts +0 -212
  189. package/src/components/editor/floorplan-camera-sync.test.ts +0 -249
  190. package/src/components/editor/floorplan-camera-sync.ts +0 -213
  191. package/src/components/editor/localized-html.tsx +0 -22
  192. package/src/components/editor-2d/renderers/floorplan-dimension-renderer.test.tsx +0 -236
  193. package/src/components/editor-2d/renderers/floorplan-dimension-renderer.tsx +0 -708
  194. package/src/components/editor-2d/renderers/floorplan-geometry-renderer.test.tsx +0 -385
  195. package/src/components/editor-2d/renderers/floorplan-geometry-renderer.tsx +0 -670
  196. package/src/components/editor-2d/renderers/floorplan-label-angle.test.ts +0 -89
  197. package/src/components/editor-2d/renderers/floorplan-label-angle.ts +0 -106
  198. package/src/components/editor-2d/svg-paths.ts +0 -124
  199. package/src/components/ui/action-menu/action-button.tsx +0 -89
  200. package/src/components/ui/action-menu/follow-pascal-toggle.tsx +0 -42
  201. package/src/components/ui/primitives/button.tsx +0 -69
  202. package/src/components/ui/primitives/dropdown-menu.tsx +0 -232
  203. package/src/components/ui/primitives/popover.tsx +0 -42
  204. package/src/components/ui/primitives/switch.tsx +0 -29
  205. package/src/components/ui/primitives/tooltip.tsx +0 -57
  206. package/src/components/ui/scene-loader.tsx +0 -73
  207. package/src/components/viewer/floorplan-compass-button.tsx +0 -67
  208. package/src/components/viewer/floorplan-preview-geometry.test.ts +0 -107
  209. package/src/components/viewer/floorplan-preview-geometry.ts +0 -281
  210. package/src/components/viewer/floorplan-preview-navigation.test.ts +0 -43
  211. package/src/components/viewer/floorplan-preview-navigation.ts +0 -62
  212. package/src/components/viewer/floorplan-preview-visibility.test.ts +0 -35
  213. package/src/components/viewer/floorplan-preview-visibility.ts +0 -19
  214. package/src/components/viewer/floorplan-preview.tsx +0 -1065
  215. package/src/components/viewer/render-settings-menu.tsx +0 -294
  216. package/src/components/viewer/sky-control.tsx +0 -710
  217. package/src/components/viewer/use-viewer-camera-navigation-sync.ts +0 -140
  218. package/src/components/viewer/use-viewer-ui-sounds.test.ts +0 -15
  219. package/src/components/viewer/use-viewer-ui-sounds.ts +0 -46
  220. package/src/components/viewer/viewer-controls-bar.tsx +0 -496
  221. package/src/components/viewer/viewer-hover-label.tsx +0 -42
  222. package/src/components/viewer/viewer-rooms.tsx +0 -248
  223. package/src/components/viewer/viewer-scene-header.tsx +0 -286
  224. package/src/components/viewer/viewer-selection-manager.tsx +0 -124
  225. package/src/components/viewer/viewer-stage-modes.test.ts +0 -38
  226. package/src/components/viewer/viewer-stage-modes.ts +0 -49
  227. package/src/components/viewer/viewer-stage-switcher.tsx +0 -97
  228. package/src/components/viewer/viewer-stage.test.tsx +0 -47
  229. package/src/components/viewer/viewer-stage.tsx +0 -221
  230. package/src/components/walkthrough-hud.tsx +0 -193
  231. package/src/hooks/use-mobile.ts +0 -19
  232. package/src/i18n/level-name.ts +0 -39
  233. package/src/i18n/scene-theme-name.ts +0 -16
  234. package/src/lib/below-grade.ts +0 -133
  235. package/src/lib/camera-pose.test.ts +0 -237
  236. package/src/lib/camera-pose.ts +0 -172
  237. package/src/lib/floorplan/floorplan-extension.test.ts +0 -42
  238. package/src/lib/floorplan/floorplan-readonly.test.ts +0 -47
  239. package/src/lib/floorplan/floorplan-readonly.ts +0 -95
  240. package/src/lib/floorplan/marks.test.ts +0 -213
  241. package/src/lib/floorplan/marks.ts +0 -238
  242. package/src/lib/measurements.ts +0 -8
  243. package/src/lib/node-display-label.ts +0 -37
  244. package/src/lib/room-assembly-overlay.test.ts +0 -275
  245. package/src/lib/room-assembly-overlay.ts +0 -265
  246. package/src/lib/room-selection.ts +0 -417
  247. package/src/lib/scene-bounds.test.ts +0 -327
  248. package/src/lib/scene-bounds.ts +0 -233
  249. package/src/lib/typing-target.ts +0 -9
  250. package/src/lib/viewer-selection.ts +0 -595
  251. package/src/lib/zone-content.ts +0 -133
  252. package/src/store/camera-pose-store.test.ts +0 -29
  253. package/src/store/camera-pose-store.ts +0 -27
  254. package/src/store/navigation-sync-pose-store.test.ts +0 -34
  255. package/src/store/navigation-sync-pose-store.ts +0 -27
  256. package/src/store/use-audio.test.ts +0 -146
  257. package/src/store/use-audio.tsx +0 -169
  258. package/src/store/use-first-person-hud.ts +0 -40
  259. package/src/store/use-follow-pascal.test.ts +0 -62
  260. package/src/store/use-follow-pascal.ts +0 -53
@@ -2,7 +2,11 @@ import type {
2
2
  AnyNode,
3
3
  AnyNodeId,
4
4
  ConstructionDrawingType,
5
+ FloorplanAnnotationRole,
5
6
  FloorplanGeometry,
7
+ FloorplanMetricNotation,
8
+ FloorplanSchedule,
9
+ FloorplanWallDimensionFaces,
6
10
  GeometryContext,
7
11
  NodeDefinition,
8
12
  SceneApi,
@@ -11,57 +15,8 @@ import type { ComponentType } from 'react'
11
15
  import type { WallSelectionDimension } from '../room-push-dimensions'
12
16
 
13
17
  export const FLOORPLAN_NODE_EXTENSION_KEY = 'pascal:editor/floorplan'
14
- export const FLOORPLAN_GEOMETRY_METADATA_KEY = 'pascal:editor/floorplan'
15
- export const FLOORPLAN_CONTEXT_EXTENSION_KEY = 'pascal:editor/floorplan'
16
18
 
17
- export type FloorplanRenderPurpose = 'edit' | 'document'
18
- export type FloorplanMetricNotation = 'meters' | 'millimeters'
19
19
  export type FloorplanToolMode = 'default' | 'expert'
20
- /**
21
- * Display → Measure walls: which finished faces wall dimensions measure to —
22
- * the interior faces (ID, the room sizes), the exterior faces (OD, the
23
- * outside size) or both. Read by a selected wall's temporary dimensions in 2D
24
- * and 3D and by the Expert plan's automatic dimension strings.
25
- */
26
- export type FloorplanWallDimensionFaces = 'interior' | 'exterior' | 'both'
27
- export const DEFAULT_FLOORPLAN_WALL_DIMENSION_FACES: FloorplanWallDimensionFaces = 'both'
28
-
29
- export function normalizeFloorplanWallDimensionFaces(value: unknown): FloorplanWallDimensionFaces {
30
- return value === 'interior' || value === 'exterior'
31
- ? value
32
- : DEFAULT_FLOORPLAN_WALL_DIMENSION_FACES
33
- }
34
- export type FloorplanAnnotationRole =
35
- | 'automatic-dimension'
36
- | 'contextual-dimension'
37
- | 'manual-dimension'
38
- | 'measurement'
39
- | 'opening-mark'
40
- | 'structural-grid'
41
- | 'column-center'
42
- | 'room-label'
43
- /** A room's finish / ceiling-height lines — detail under the name, off in the clean plan. */
44
- | 'room-detail'
45
- /** The roof plan proper: outline, ridges, hips, slope arrows. Off over a floor plan unless asked. */
46
- | 'roof-plan'
47
- | 'roof-pitch'
48
- | 'stair-annotation'
49
-
50
- export type FloorplanSchedule = {
51
- id: string
52
- title: string
53
- columns: ReadonlyArray<{
54
- key: string
55
- label: string
56
- weight?: number
57
- }>
58
- rows: ReadonlyArray<{
59
- id: string
60
- cells: Readonly<Record<string, string>>
61
- }>
62
- issues?: readonly string[]
63
- }
64
-
65
20
  export type FloorplanToolContext = {
66
21
  sceneApi: SceneApi
67
22
  activeLevelId: AnyNodeId | null
@@ -124,7 +79,6 @@ export type FloorplanNodeExtension<N extends AnyNode = AnyNode> = {
124
79
  /** A drafted sheet's schedule: marks match the sheet's tags. */
125
80
  drafting?: boolean
126
81
  }) => FloorplanSchedule | null
127
- linkedLevelIds?: (node: N) => readonly AnyNodeId[]
128
82
  resolveForDrawing?: (args: {
129
83
  node: N
130
84
  nodes: Record<string, AnyNode>
@@ -132,38 +86,6 @@ export type FloorplanNodeExtension<N extends AnyNode = AnyNode> = {
132
86
  }) => AnyNode | null
133
87
  }
134
88
 
135
- type FloorplanGeometryMetadata = {
136
- annotationRole?: FloorplanAnnotationRole
137
- annotationObstacle?: 'bounds' | 'outline'
138
- renderPass?: 'overlay'
139
- /**
140
- * Annotation text only: the size to print at, in paper points, instead of
141
- * the size its role implies. Lets a sheet set a room tag's name larger than
142
- * its number without inventing a role per size.
143
- */
144
- textSizePt?: number
145
- }
146
-
147
- type FloorplanContextExtension = {
148
- automaticDimensions: boolean
149
- purpose: FloorplanRenderPurpose
150
- /**
151
- * Sheet drafting (the Sheets plan viewports): kinds draw the permit-set
152
- * convention — fixtures as labelled linework, furniture as light outlines,
153
- * no raster sprites. Only `collectSheetGeometry` sets it; the editor and the
154
- * read-only viewer never do, so their plans keep today's look.
155
- */
156
- drafting: boolean
157
- /**
158
- * The editor canvas draws room labels as screen pills over the plan
159
- * (`RoomLabels2D`), so zones skip their drawn tags and wash there. Exports,
160
- * sheets and the read-only viewer keep the drawn tags.
161
- */
162
- roomLabelOverlay: boolean
163
- metricNotation: FloorplanMetricNotation
164
- wallDimensionFaces: FloorplanWallDimensionFaces
165
- }
166
-
167
89
  export function getFloorplanNodeExtension(
168
90
  definition: NodeDefinition<any> | undefined,
169
91
  ): FloorplanNodeExtension | undefined {
@@ -171,78 +93,3 @@ export function getFloorplanNodeExtension(
171
93
  | FloorplanNodeExtension
172
94
  | undefined
173
95
  }
174
-
175
- export function floorplanGeometryMetadata(
176
- values: FloorplanGeometryMetadata,
177
- ): Readonly<Record<string, unknown>> {
178
- return { [FLOORPLAN_GEOMETRY_METADATA_KEY]: values }
179
- }
180
-
181
- export function withFloorplanGeometryMetadata<T extends FloorplanGeometry | null>(
182
- geometry: T,
183
- values: FloorplanGeometryMetadata,
184
- ): T {
185
- if (!geometry) return geometry
186
- const existing = readFloorplanGeometryMetadata(geometry)
187
- return {
188
- ...geometry,
189
- metadata: floorplanGeometryMetadata({ ...existing, ...values }),
190
- } as T
191
- }
192
-
193
- export function readFloorplanGeometryMetadata(geometry: unknown): FloorplanGeometryMetadata {
194
- const metadata = (geometry as { metadata?: Readonly<Record<string, unknown>> } | null)?.metadata
195
- const value = metadata?.[FLOORPLAN_GEOMETRY_METADATA_KEY]
196
- return value && typeof value === 'object' && !Array.isArray(value)
197
- ? (value as FloorplanGeometryMetadata)
198
- : {}
199
- }
200
-
201
- export function createFloorplanContextExtensions(
202
- values: Partial<FloorplanContextExtension>,
203
- ): Readonly<Record<string, unknown>> {
204
- return {
205
- [FLOORPLAN_CONTEXT_EXTENSION_KEY]: {
206
- automaticDimensions: values.automaticDimensions !== false,
207
- purpose: values.purpose === 'document' ? 'document' : 'edit',
208
- drafting: values.drafting === true,
209
- roomLabelOverlay: values.roomLabelOverlay === true,
210
- metricNotation: values.metricNotation === 'millimeters' ? 'millimeters' : 'meters',
211
- wallDimensionFaces: normalizeFloorplanWallDimensionFaces(values.wallDimensionFaces),
212
- } satisfies FloorplanContextExtension,
213
- }
214
- }
215
-
216
- export function readFloorplanContext(ctx: GeometryContext): FloorplanContextExtension {
217
- const value = ctx.extensions?.[FLOORPLAN_CONTEXT_EXTENSION_KEY]
218
- if (value && typeof value === 'object' && !Array.isArray(value)) {
219
- const extension = value as Partial<FloorplanContextExtension>
220
- return {
221
- automaticDimensions: extension.automaticDimensions !== false,
222
- purpose: extension.purpose === 'document' ? 'document' : 'edit',
223
- drafting: extension.drafting === true,
224
- roomLabelOverlay: extension.roomLabelOverlay === true,
225
- metricNotation: extension.metricNotation === 'millimeters' ? 'millimeters' : 'meters',
226
- wallDimensionFaces: normalizeFloorplanWallDimensionFaces(extension.wallDimensionFaces),
227
- }
228
- }
229
- return {
230
- automaticDimensions: true,
231
- purpose: 'edit',
232
- drafting: false,
233
- roomLabelOverlay: false,
234
- metricNotation: 'meters',
235
- wallDimensionFaces: DEFAULT_FLOORPLAN_WALL_DIMENSION_FACES,
236
- }
237
- }
238
-
239
- export function readFloorplanMetricNotationOverride(
240
- ctx: GeometryContext,
241
- ): FloorplanMetricNotation | undefined {
242
- const value = ctx.extensions?.[FLOORPLAN_CONTEXT_EXTENSION_KEY]
243
- if (!value || typeof value !== 'object' || Array.isArray(value)) return undefined
244
- const metricNotation = (value as { metricNotation?: unknown }).metricNotation
245
- return metricNotation === 'meters' || metricNotation === 'millimeters'
246
- ? metricNotation
247
- : undefined
248
- }
@@ -1,8 +1,9 @@
1
+ import type { FloorplanAnnotationRole } from '@pascal-app/core'
1
2
  import {
2
3
  type FloorplanAnnotationVisibility,
3
4
  revealFloorplanAnnotationRole,
4
5
  } from './annotation-visibility'
5
- import type { FloorplanAnnotationRole, FloorplanToolMode } from './floorplan-extension'
6
+ import type { FloorplanToolMode } from './floorplan-extension'
6
7
 
7
8
  export const FLOORPLAN_MODES = ['default', 'expert'] as const
8
9
 
@@ -1,7 +1,7 @@
1
1
  import { describe, expect, test } from 'bun:test'
2
2
  import type { FloorplanGeometry } from '@pascal-app/core'
3
+ import { floorplanGeometryMetadata } from '@pascal-app/core'
3
4
  import PDFDocument from 'pdfkit'
4
- import { floorplanGeometryMetadata } from './floorplan-extension'
5
5
  import { FloorplanPdfDocument, loadFloorplanPdfFonts } from './floorplan-pdfkit-document'
6
6
  import { renderFloorplanGeometryToPdfKit } from './floorplan-pdfkit-renderer'
7
7
 
@@ -1,16 +1,18 @@
1
- import { type FloorplanGeometry, type FloorplanPoint, loadAssetUrl } from '@pascal-app/core'
1
+ import {
2
+ type FloorplanGeometry,
3
+ type FloorplanPoint,
4
+ loadAssetUrl,
5
+ readFloorplanGeometryMetadata,
6
+ } from '@pascal-app/core'
2
7
  import {
3
8
  type ArchitecturalDimensionLayout,
4
9
  computeArchitecturalDimensionLayout,
5
- } from '../../components/editor-2d/renderers/floorplan-dimension-renderer'
6
- import {
7
10
  documentCircleGeometryAttrs,
8
11
  documentRectGeometryAttrs,
9
12
  resolveDocumentAnnotationGroupChildren,
10
- } from '../../components/editor-2d/renderers/floorplan-geometry-renderer'
11
- import { resolveFloorplanLabelAngle } from '../../components/editor-2d/renderers/floorplan-label-angle'
13
+ resolveFloorplanLabelAngle,
14
+ } from '@pascal-app/viewer/ui'
12
15
  import type { FloorplanExportBounds } from './floorplan-export'
13
- import { readFloorplanGeometryMetadata } from './floorplan-extension'
14
16
  import type { FloorplanPdfBaseline, FloorplanPdfDocument } from './floorplan-pdfkit-document'
15
17
 
16
18
  const DIMENSION_LINE_WIDTH_PT = 0.5
@@ -6,12 +6,11 @@ import {
6
6
  loadPlugin,
7
7
  nodeRegistry,
8
8
  } from '@pascal-app/core'
9
+ import { FloorplanPreview } from '@pascal-app/viewer/ui'
9
10
  import { renderToStaticMarkup } from 'react-dom/server'
10
11
  import { z } from 'zod'
11
- import { FloorplanPreview } from '../../components/viewer/floorplan-preview'
12
12
  import { DEFAULT_FLOORPLAN_ANNOTATION_VISIBILITY } from './annotation-visibility'
13
13
  import { collectFloorplanGeometry, floorplanExportInstalledPlugins } from './floorplan-export'
14
- import { FLOORPLAN_NODE_EXTENSION_KEY } from './floorplan-extension'
15
14
 
16
15
  // Plugin API v1, no-install case: a plugin kind's floor-plan output appears in
17
16
  // the read-only preview and the PDF export only while the project has the
@@ -31,7 +30,7 @@ const bed = {
31
30
  visible: true,
32
31
  metadata: {},
33
32
  } as unknown as AnyNode
34
- // Lives on the upper level but draws on this one through `linkedLevelIds`.
33
+ // Lives on the upper level but draws on this one through `floorplanLinkedLevelIds`.
35
34
  const upper = LevelNode.parse({ id: 'level_plugin_upper', level: 1, children: ['fxshaft_plan'] })
36
35
  const shaft = {
37
36
  object: 'node',
@@ -70,7 +69,7 @@ beforeEach(async () => {
70
69
  category: 'structure',
71
70
  defaults: () => ({}),
72
71
  capabilities: {},
73
- extensions: { [FLOORPLAN_NODE_EXTENSION_KEY]: { linkedLevelIds: () => [level.id] } },
72
+ floorplanLinkedLevelIds: () => [level.id],
74
73
  floorplan: () => ({ kind: 'rect', x: 3, y: 0, width: 1, height: 1 }),
75
74
  } as unknown as AnyNodeDefinition,
76
75
  ],
@@ -1,68 +1,5 @@
1
- import type { Point2D } from '@pascal-app/core'
2
- import { getWallFaceOffsets, type WallJustification } from '@pascal-app/core'
3
- import type { FloorplanLineSegment, FloorplanSelectionBounds } from './types'
4
-
5
- // Baseline rotation (deg) that orients the plan-local scene "north up" on
6
- // screen. The on-screen floor-plan scene `<g>` is rotated by
7
- // `FLOORPLAN_VIEW_ROTATION_DEG + userRotation - buildingRotation`; PDF export
8
- // uses the same user rotation so its orientation matches the live plan.
9
- //
10
- // North is world −Z: with a 0 baseline a rotation-0 reference image (top =
11
- // −Z) reads upright in the north-aligned view, and "align north" maps to a
12
- // 3D camera azimuth of 0. The old 90° baseline made north world −X, so
13
- // north-up floorplan scans displayed sideways whenever the compass claimed
14
- // the view was aligned.
15
- export const FLOORPLAN_VIEW_ROTATION_DEG = 0
16
-
17
- export function clampPlanValue(value: number, min: number, max: number) {
18
- return Math.min(Math.max(value, min), max)
19
- }
20
-
21
- export function rotatePlanVector(x: number, y: number, rotation: number): [number, number] {
22
- const cos = Math.cos(rotation)
23
- const sin = Math.sin(rotation)
24
- return [x * cos + y * sin, -x * sin + y * cos]
25
- }
26
-
27
- // Converts a world X/Z point into the floor-plan-local (building-local)
28
- // frame used by the SVG scene `<g>` and every stored node position. The
29
- // inverse of `floorplanLocalToWorldPoint`. Shared so the floor-plan panel
30
- // and the 2D move overlay resolve the same frame — feeding a world-space
31
- // `original` into a local-space cursor solver lands the drop off by the
32
- // building's world X/Z (worse for an off-origin building).
33
- export function worldToFloorplanLocalPoint(
34
- worldX: number,
35
- worldZ: number,
36
- buildingPosition: readonly [number, number, number],
37
- buildingRotationY: number,
38
- ): Point2D {
39
- const dx = worldX - buildingPosition[0]
40
- const dz = worldZ - buildingPosition[2]
41
- const cos = Math.cos(buildingRotationY)
42
- const sin = Math.sin(buildingRotationY)
43
-
44
- return {
45
- x: dx * cos - dz * sin,
46
- y: dx * sin + dz * cos,
47
- }
48
- }
49
-
50
- // Inverse of `worldToFloorplanLocalPoint`: floor-plan-local X/Y → world X/Z.
51
- export function floorplanLocalToWorldPoint(
52
- point: Point2D | [number, number],
53
- buildingPosition: readonly [number, number, number],
54
- buildingRotationY: number,
55
- ): { x: number; z: number } {
56
- const localX = Array.isArray(point) ? point[0] : point.x
57
- const localY = Array.isArray(point) ? point[1] : point.y
58
- const cos = Math.cos(buildingRotationY)
59
- const sin = Math.sin(buildingRotationY)
60
-
61
- return {
62
- x: buildingPosition[0] + localX * cos + localY * sin,
63
- z: buildingPosition[2] - localX * sin + localY * cos,
64
- }
65
- }
1
+ import { clampPlanValue, type Point2D, rotatePlanVector } from '@pascal-app/core'
2
+ import type { FloorplanSelectionBounds } from './types'
66
3
 
67
4
  export function getRotatedRectanglePolygon(
68
5
  center: Point2D,
@@ -88,53 +25,6 @@ export function getRotatedRectanglePolygon(
88
25
  })
89
26
  }
90
27
 
91
- export function interpolatePlanPoint(start: Point2D, end: Point2D, t: number): Point2D {
92
- return {
93
- x: start.x + (end.x - start.x) * t,
94
- y: start.y + (end.y - start.y) * t,
95
- }
96
- }
97
-
98
- export function getPlanPointDistance(start: Point2D, end: Point2D): number {
99
- return Math.hypot(end.x - start.x, end.y - start.y)
100
- }
101
-
102
- export function movePlanPointTowards(start: Point2D, end: Point2D, distance: number): Point2D {
103
- const totalDistance = getPlanPointDistance(start, end)
104
- if (totalDistance <= Number.EPSILON || distance <= 0) {
105
- return start
106
- }
107
-
108
- return interpolatePlanPoint(start, end, Math.min(1, distance / totalDistance))
109
- }
110
-
111
- export function getThickPlanLinePolygon(
112
- line: FloorplanLineSegment,
113
- thickness: number,
114
- justification?: WallJustification,
115
- ): Point2D[] {
116
- const dx = line.end.x - line.start.x
117
- const dy = line.end.y - line.start.y
118
- const length = Math.hypot(dx, dy)
119
-
120
- if (length <= Number.EPSILON || thickness <= 0) {
121
- return [line.start, line.end, line.end, line.start]
122
- }
123
-
124
- const { a, b } = getWallFaceOffsets({ thickness, justification })
125
- const normalX = (-dy / length) * a
126
- const normalY = (dx / length) * a
127
-
128
- const backX = (-dy / length) * -b
129
- const backY = (dx / length) * -b
130
- return [
131
- { x: line.start.x + normalX, y: line.start.y + normalY },
132
- { x: line.end.x + normalX, y: line.end.y + normalY },
133
- { x: line.end.x - backX, y: line.end.y - backY },
134
- { x: line.start.x - backX, y: line.start.y - backY },
135
- ]
136
- }
137
-
138
28
  export function getFloorplanSelectionBounds(
139
29
  start: [number, number],
140
30
  end: [number, number],
@@ -6,23 +6,14 @@ export {
6
6
  type FloorplanAlignmentResult,
7
7
  } from './apply-alignment'
8
8
  export {
9
- clampPlanValue,
10
9
  doesPolygonIntersectSelectionBounds,
11
- FLOORPLAN_VIEW_ROTATION_DEG,
12
- floorplanLocalToWorldPoint,
13
10
  getDistanceToWallSegment,
14
11
  getFloorplanSelectionBounds,
15
- getPlanPointDistance,
16
12
  getRotatedRectanglePolygon,
17
- getThickPlanLinePolygon,
18
- interpolatePlanPoint,
19
13
  isPointInsidePolygon,
20
14
  isPointInsidePolygonWithHoles,
21
15
  isPointInsideSelectionBounds,
22
- movePlanPointTowards,
23
16
  pointMatchesWallPlanPoint,
24
- rotatePlanVector,
25
- worldToFloorplanLocalPoint,
26
17
  } from './geometry'
27
18
  export {
28
19
  buildFloorplanItemEntry,
@@ -6,9 +6,10 @@ import {
6
6
  getWallLocalFaceZ,
7
7
  type ItemNode,
8
8
  type LevelNode,
9
+ rotatePlanVector,
9
10
  useLiveTransforms,
10
11
  } from '@pascal-app/core'
11
- import { getRotatedRectanglePolygon, rotatePlanVector } from './geometry'
12
+ import { getRotatedRectanglePolygon } from './geometry'
12
13
  import type { FloorplanItemEntry, FloorplanNodeTransform, LevelDescendantMap } from './types'
13
14
 
14
15
  export function collectLevelDescendants(
@@ -1,8 +1,11 @@
1
1
  import type { AnyNode, AnyNodeId, DoorNode, WallNode, WindowNode, ZoneNode } from '@pascal-app/core'
2
- import { deriveZoneQuantityReport, resolveHostedOpeningFrameDepth } from '@pascal-app/core'
2
+ import {
3
+ deriveZoneQuantityReport,
4
+ type FloorplanSchedule,
5
+ resolveHostedOpeningFrameDepth,
6
+ resolveMarkDetail,
7
+ } from '@pascal-app/core'
3
8
  import { collectFloorplanSchedules } from './floorplan-export'
4
- import type { FloorplanSchedule } from './floorplan-extension'
5
- import { resolveMarkDetail } from './marks'
6
9
 
7
10
  /**
8
11
  * Construction-document schedule DATA — WS3.
@@ -30,7 +30,11 @@ import type {
30
30
  FloorplanGeometry,
31
31
  LiveNodeOverrides,
32
32
  } from '@pascal-app/core'
33
- import { nodeRegistry, resolveBuildingForLevel } from '@pascal-app/core'
33
+ import {
34
+ type FloorplanMetricNotation,
35
+ nodeRegistry,
36
+ resolveBuildingForLevel,
37
+ } from '@pascal-app/core'
34
38
  import {
35
39
  buildContext,
36
40
  collectFloorplanLinkedLevelNodes,
@@ -52,14 +56,12 @@ import {
52
56
  resolveFloorplanExportRotationDeg,
53
57
  resolveFloorplanExportViewState,
54
58
  } from './floorplan-export'
55
- import type { FloorplanMetricNotation } from './floorplan-extension'
56
59
  import { createFloorplanPdfDocument } from './floorplan-pdfkit-document'
57
60
  import { renderFloorplanGeometryToPdfKit } from './floorplan-pdfkit-renderer'
58
61
 
59
62
  /** PDF user-space units per inch. */
60
63
  export const POINTS_PER_INCH = 72
61
64
 
62
- export type { FloorplanSchedule } from './floorplan-extension'
63
65
  /**
64
66
  * The schedules the kinds on a level contribute
65
67
  * (`def.extensions['pascal:editor/floorplan'].schedule`). Re-exported here so
@@ -316,3 +318,5 @@ async function drawPlate(
316
318
  },
317
319
  )
318
320
  }
321
+
322
+ export type { FloorplanSchedule } from '@pascal-app/core'
@@ -15,7 +15,9 @@ import {
15
15
  isOutdoorRoomType,
16
16
  type LevelNode,
17
17
  migrateSiteMetadata,
18
+ type RoofNode,
18
19
  type RoofSegmentNode,
20
+ roofFaceShapes,
19
21
  type SceneSnapshot,
20
22
  type SiteNode,
21
23
  siteFrame,
@@ -75,7 +77,8 @@ export function findLowestLevel(
75
77
  /**
76
78
  * The roof's outline on the lot — every roof segment's plan rectangle out to
77
79
  * its deck's reach at its eaves and rakes, through the segment's, the roof's
78
- * and the building's turns, unioned into the outer ring(s). Dashed on the site plan: what the eye sees
80
+ * and the building's turns, and every face of another kind (`capabilities.roofs`)
81
+ * by its own outline, unioned into the outer ring(s). Dashed on the site plan: what the eye sees
79
82
  * from above is the roof, and the setback is measured to the wall under it.
80
83
  */
81
84
  export function roofOutlineRings(
@@ -93,6 +96,9 @@ export function roofOutlineRings(
93
96
  }
94
97
  if (roofs.size === 0) return []
95
98
  const rects: Pt[][] = []
99
+ for (const roof of roofs.values())
100
+ for (const face of roofFaceShapes(roof as RoofNode, scene.nodes))
101
+ rects.push(face.outline.map(([x, z]) => toSite(x, z)))
96
102
  for (const node of Object.values(scene.nodes)) {
97
103
  if (node.type !== 'roof-segment') continue
98
104
  const roof = roofs.get(String((node as { parentId?: unknown }).parentId))
@@ -7,8 +7,8 @@ import {
7
7
  resumeSceneHistory,
8
8
  useScene,
9
9
  } from '@pascal-app/core'
10
+ import { FloorplanGeometryRenderer } from '@pascal-app/viewer/ui'
10
11
  import { type PointerEvent as ReactPointerEvent, useCallback, useMemo, useRef } from 'react'
11
- import { FloorplanGeometryRenderer } from '../../../components/editor-2d/renderers/floorplan-geometry-renderer'
12
12
  import { clientToPlan } from '../plan-coords'
13
13
  import { buildSitePlanDrawing } from './build-site-plan-drawing'
14
14
 
@@ -1,5 +1,5 @@
1
1
  import type { WallMode } from '@pascal-app/viewer'
2
- import type { RoomKey } from './room-selection'
2
+ import type { RoomKey } from '@pascal-app/viewer/ui'
3
3
 
4
4
  /**
5
5
  * Follow Pascal changes how the building is shown so the build it follows is in view: the walls cut
@@ -32,6 +32,7 @@ import {
32
32
  type ViewerPresentationContribution,
33
33
  viewerPresentationRegistry,
34
34
  } from '@pascal-app/viewer'
35
+ import { nodeDisplayLabel } from '@pascal-app/viewer/ui'
35
36
  import type { Object3D } from 'three'
36
37
  import * as THREE from 'three'
37
38
  import {
@@ -42,7 +43,6 @@ import {
42
43
  import { createExportTextureUtils, type ExportTextureUtils } from './export-texture-utils'
43
44
  import { cloneExportUserData } from './export-user-data'
44
45
  import { isIfcRolePart } from './ifc-parts'
45
- import { nodeDisplayLabel } from './node-display-label'
46
46
  import {
47
47
  type CompressedTextureDecompressor,
48
48
  decompressCanonicalNormalMaps,
@@ -309,7 +309,7 @@ export function resolveActivePaintMaterialFromSelection(params: {
309
309
  ) {
310
310
  const roofNode = selectedNode as RoofNode
311
311
  const fallbackSegment = (roofNode.children ?? [])
312
- .map((id: AnyNodeId) => nodes[id as AnyNodeId] as RoofSegmentNode | undefined)
312
+ .map((id) => nodes[id as AnyNodeId] as RoofSegmentNode | undefined)
313
313
  .find(
314
314
  (segment: RoofSegmentNode | undefined) =>
315
315
  segment?.type === 'roof-segment' &&
@@ -17,11 +17,12 @@ import {
17
17
  import {
18
18
  MEASUREMENT_ACTIVE_COLOR,
19
19
  MEASUREMENT_DANGLING_COLOR,
20
+ MEASUREMENT_FLOORPLAN_COLOR,
20
21
  MEASUREMENT_PERSISTENT_COLOR,
22
+ measurementFloorplanPresentationColor,
21
23
  measurementPresentationColor,
22
24
  } from '@pascal-app/viewer'
23
25
  import { measurementHint, parseMeasurement } from '../index'
24
- import { MEASUREMENT_FLOORPLAN_COLOR, measurementFloorplanPresentationColor } from './measurements'
25
26
 
26
27
  describe('measurement presentation', () => {
27
28
  test('uses black at rest, indigo while active, and red for dangling references', () => {
@@ -15,6 +15,7 @@ import {
15
15
  type ZoneNode,
16
16
  } from '@pascal-app/core'
17
17
  import { useViewer } from '@pascal-app/viewer'
18
+ import { RoomSelectionIndex, resolveRoomHit } from '@pascal-app/viewer/ui'
18
19
  import { deleteConfirmationContent } from '../components/editor/delete-confirmation-dialog'
19
20
  import { resolveFloorRegionRoom } from '../components/editor/floor-region-controls'
20
21
  import { MEZZANINE_GESTURE_HINTS, mezzanineGesture } from '../components/ui/helpers/helper-manager'
@@ -23,7 +24,6 @@ import {
23
24
  mezzanineElevationBounds,
24
25
  ROOM_ELEVATION_DRAG_LABEL,
25
26
  } from './room-handle-drag'
26
- import { RoomSelectionIndex, resolveRoomHit } from './room-selection'
27
27
  import { applyRoomPlan } from './room-structure-commands'
28
28
  import { ROOM_MOVE_DRAG_LABEL } from './room-transform-session'
29
29
  import { zoneAtLevelPoint } from './units'
@@ -1,6 +1,6 @@
1
+ import { isTypingTarget } from '@pascal-app/viewer'
1
2
  import { create } from 'zustand'
2
3
  import type { ActivePaintMaterial } from './material-paint'
3
- import { isTypingTarget } from './typing-target'
4
4
 
5
5
  /**
6
6
  * What a paint click does: paint the whole surface under it, draw part of a
@@ -18,6 +18,7 @@ import {
18
18
  } from '@pascal-app/core'
19
19
  import { sceneViewBounds, sceneViewPose } from '@pascal-app/core/agent-operations'
20
20
  import { retractNodes, useViewer } from '@pascal-app/viewer'
21
+ import { cameraPoseStore, useFollowPascal } from '@pascal-app/viewer/ui'
21
22
  import { type Object3D, Vector2, Vector3 } from 'three'
22
23
  import {
23
24
  resolveRoofSegmentSelectionTarget,
@@ -25,9 +26,7 @@ import {
25
26
  } from '../../components/editor/selection-manager'
26
27
  import { getEditorThreeContext } from '../../components/editor/three-context-bridge'
27
28
  import { resolveEditorRoomHit } from '../../hooks/use-selected-room'
28
- import { cameraPoseStore } from '../../store/camera-pose-store'
29
29
  import useEditor, { getActiveContinuationContext } from '../../store/use-editor'
30
- import useFollowPascal from '../../store/use-follow-pascal'
31
30
  import useInteractionScope from '../../store/use-interaction-scope'
32
31
  import {
33
32
  type BubbleTarget,