@volter/editor-core 0.5.57

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 (719) hide show
  1. package/BUNDLED_NOTICES +1527 -0
  2. package/LICENSE +686 -0
  3. package/LICENSE-APACHE +202 -0
  4. package/NOTICE +18 -0
  5. package/README.md +24 -0
  6. package/dist/build/chunk-JS4D4XZ3.js +175 -0
  7. package/dist/build/chunk-JS4D4XZ3.js.map +7 -0
  8. package/dist/build/vite-plugin-product-contributions.js +100 -0
  9. package/dist/build/vite-plugin-product-contributions.js.map +7 -0
  10. package/dist/build/vite-plugin-shared-react.js +25 -0
  11. package/dist/build/vite-plugin-shared-react.js.map +7 -0
  12. package/dist/build/vite-plugin-shared-three.js +86 -0
  13. package/dist/build/vite-plugin-shared-three.js.map +7 -0
  14. package/dist/server/chunk-KMJC7AGO.js +98 -0
  15. package/dist/server/chunk-KMJC7AGO.js.map +7 -0
  16. package/dist/server/chunk-PSILUMGS.js +46 -0
  17. package/dist/server/chunk-PSILUMGS.js.map +7 -0
  18. package/dist/server/frame-proxy.js +255 -0
  19. package/dist/server/frame-proxy.js.map +7 -0
  20. package/dist/server/open-browser.js +53 -0
  21. package/dist/server/open-browser.js.map +7 -0
  22. package/dist/server/process-shutdown.js +127 -0
  23. package/dist/server/process-shutdown.js.map +7 -0
  24. package/dist/server/session-registry.js +141 -0
  25. package/dist/server/session-registry.js.map +7 -0
  26. package/dist/server/spawn-opener.js +11 -0
  27. package/dist/server/spawn-opener.js.map +7 -0
  28. package/dist/server/worktree-identity.js +11 -0
  29. package/dist/server/worktree-identity.js.map +7 -0
  30. package/dist-server/packaged.mjs +88816 -0
  31. package/package.json +118 -0
  32. package/scripts/build-plugins.mjs +14 -0
  33. package/scripts/build-server.mjs +26 -0
  34. package/scripts/build-session.mjs +9 -0
  35. package/server/account-credentials.ts +60 -0
  36. package/server/account-service.ts +1434 -0
  37. package/server/adapter-region-includes.ts +47 -0
  38. package/server/asset-catalog-v2.ts +175 -0
  39. package/server/asset-history-snapshots.ts +196 -0
  40. package/server/asset-ledger-store.ts +195 -0
  41. package/server/asset-library-routes.ts +1595 -0
  42. package/server/blender-wasm-artifact.ts +430 -0
  43. package/server/boot-timings.ts +106 -0
  44. package/server/canonical-path.ts +50 -0
  45. package/server/checkout-workspace-preflight.ts +349 -0
  46. package/server/cloud-asset-catalog.ts +158 -0
  47. package/server/coding-inference-launch.ts +237 -0
  48. package/server/collaboration-account-client.ts +202 -0
  49. package/server/collaboration-attribution.ts +122 -0
  50. package/server/collaboration-session.ts +934 -0
  51. package/server/comfyui-bridge.ts +248 -0
  52. package/server/console-ledger.ts +499 -0
  53. package/server/creation-site-transform.ts +304 -0
  54. package/server/creation-site-write.ts +648 -0
  55. package/server/data-file-serialize.ts +158 -0
  56. package/server/editor-brand-html.ts +72 -0
  57. package/server/editor-control-socket.ts +366 -0
  58. package/server/editor-server-options.ts +190 -0
  59. package/server/editor-server.ts +1483 -0
  60. package/server/editor-sse.ts +352 -0
  61. package/server/engine-provenance.ts +169 -0
  62. package/server/engine-source-restart.ts +117 -0
  63. package/server/frame-bridge.ts +115 -0
  64. package/server/frame-proxy.ts +490 -0
  65. package/server/frame-workbench.ts +259 -0
  66. package/server/frontend-handoff.ts +229 -0
  67. package/server/game-globals-shadow.ts +113 -0
  68. package/server/gameplay-session-retention.ts +149 -0
  69. package/server/gameplay-sessions.ts +123 -0
  70. package/server/generation-jobs.ts +201 -0
  71. package/server/generation-reconciler.ts +137 -0
  72. package/server/generative-execution-context.ts +59 -0
  73. package/server/git-workflow.ts +612 -0
  74. package/server/harness-chat-caller.ts +36 -0
  75. package/server/harness-chat-service.ts +1681 -0
  76. package/server/idle-shutdown.ts +170 -0
  77. package/server/js-profiling-policy.ts +52 -0
  78. package/server/launcher-settings.ts +84 -0
  79. package/server/local-asset-catalog.ts +410 -0
  80. package/server/managed-account-defaults.ts +22 -0
  81. package/server/mock-control-plane.ts +540 -0
  82. package/server/model-import-conversion.ts +345 -0
  83. package/server/native-credential-store.ts +162 -0
  84. package/server/open-browser.ts +118 -0
  85. package/server/packaged.ts +1192 -0
  86. package/server/play-stall.ts +126 -0
  87. package/server/process-shutdown.ts +218 -0
  88. package/server/product-presets.ts +55 -0
  89. package/server/project-build-artifact.ts +95 -0
  90. package/server/project-components.ts +100 -0
  91. package/server/project-dependency-invalidation.ts +114 -0
  92. package/server/project-file-scan.ts +235 -0
  93. package/server/project-hmr-files.ts +215 -0
  94. package/server/project-install-roots.ts +210 -0
  95. package/server/project-kinds.ts +71 -0
  96. package/server/project-mcp-servers.ts +82 -0
  97. package/server/project-module-freshness.ts +109 -0
  98. package/server/project-module-instance.ts +375 -0
  99. package/server/project-optimize-deps-entries.ts +827 -0
  100. package/server/project-output-writer.ts +679 -0
  101. package/server/project-package-origin.ts +63 -0
  102. package/server/project-root-surface.ts +831 -0
  103. package/server/project-scratch-path.ts +47 -0
  104. package/server/project-script-hmr.ts +619 -0
  105. package/server/project-serving-plugins.ts +236 -0
  106. package/server/project-tools.ts +653 -0
  107. package/server/project-validation.ts +250 -0
  108. package/server/project-verbs.ts +127 -0
  109. package/server/project-view.ts +52 -0
  110. package/server/project-watch.ts +1134 -0
  111. package/server/project-work-coordinator.ts +288 -0
  112. package/server/provider-credentials.ts +331 -0
  113. package/server/recent-projects-store.ts +98 -0
  114. package/server/redact-secrets.ts +71 -0
  115. package/server/repository-presence.ts +267 -0
  116. package/server/routes/account.ts +357 -0
  117. package/server/routes/agents.ts +60 -0
  118. package/server/routes/assets.ts +154 -0
  119. package/server/routes/build.ts +13 -0
  120. package/server/routes/collaboration.ts +595 -0
  121. package/server/routes/configurations.ts +419 -0
  122. package/server/routes/context.ts +264 -0
  123. package/server/routes/control-plane.ts +1811 -0
  124. package/server/routes/logs.ts +272 -0
  125. package/server/routes/project-identity.ts +302 -0
  126. package/server/routes/project-open.ts +429 -0
  127. package/server/routes/project-source.ts +686 -0
  128. package/server/routes/project-state.ts +383 -0
  129. package/server/routes/relay.ts +1029 -0
  130. package/server/routes/route-helpers.ts +29 -0
  131. package/server/routes/served-modules.ts +138 -0
  132. package/server/routes/session-tabs.ts +196 -0
  133. package/server/routes/settings.ts +121 -0
  134. package/server/routes/share-control.ts +486 -0
  135. package/server/routes/themes.ts +116 -0
  136. package/server/routes/tools.ts +230 -0
  137. package/server/routes/worktrees.ts +595 -0
  138. package/server/scoped-game-css.ts +461 -0
  139. package/server/server-utils.ts +1194 -0
  140. package/server/session-product.ts +112 -0
  141. package/server/session-registry.ts +230 -0
  142. package/server/share-claims.ts +138 -0
  143. package/server/share-host.ts +526 -0
  144. package/server/share-session-gateway.ts +1362 -0
  145. package/server/share-tunnel.ts +123 -0
  146. package/server/spawn-opener.ts +74 -0
  147. package/server/support/play/log-format.ts +76 -0
  148. package/server/support/play/session-record.ts +199 -0
  149. package/server/support/project/build-discipline.ts +718 -0
  150. package/server/support/project/inspection-node.ts +119 -0
  151. package/server/support/project/log-naming.ts +54 -0
  152. package/server/support/project/provenance.ts +290 -0
  153. package/server/support/project/run-name.ts +18 -0
  154. package/server/support/project/session-journal.ts +830 -0
  155. package/server/support/project/shared.ts +327 -0
  156. package/server/tab-bootstrap.ts +62 -0
  157. package/server/tab-heartbeat.ts +477 -0
  158. package/server/tab-lifecycle.ts +550 -0
  159. package/server/tab-presence.ts +1508 -0
  160. package/server/team-agent-mirror.ts +95 -0
  161. package/server/twin-auth.ts +138 -0
  162. package/server/vendored-lock-recorder.ts +968 -0
  163. package/server/worktree-identity.ts +121 -0
  164. package/server/worktree-management.ts +398 -0
  165. package/server/worktree-retention.d.mts +13 -0
  166. package/server/worktree-retention.mjs +205 -0
  167. package/src/EditorContext.tsx +169 -0
  168. package/src/account.ts +333 -0
  169. package/src/action-registry.ts +532 -0
  170. package/src/active-product.ts +74 -0
  171. package/src/active-project.ts +155 -0
  172. package/src/adapter-editor-config.ts +25 -0
  173. package/src/adapter-observation.ts +49 -0
  174. package/src/animation/stage-transport.ts +379 -0
  175. package/src/animation/three-clips-subject.ts +172 -0
  176. package/src/api/asset-library-wire.ts +45 -0
  177. package/src/api/assets.ts +365 -0
  178. package/src/api/base.ts +10 -0
  179. package/src/api/build.ts +99 -0
  180. package/src/api/git-wire.ts +56 -0
  181. package/src/api/logs.ts +92 -0
  182. package/src/api/project-identity.ts +74 -0
  183. package/src/api/project-open.ts +355 -0
  184. package/src/api/project-source.ts +162 -0
  185. package/src/api/project-state.ts +107 -0
  186. package/src/api/relay.ts +268 -0
  187. package/src/api/settings.ts +36 -0
  188. package/src/api/themes.ts +45 -0
  189. package/src/api/worktrees.ts +257 -0
  190. package/src/asset-compare-core.ts +171 -0
  191. package/src/asset-compare.ts +294 -0
  192. package/src/asset-editor-context.tsx +100 -0
  193. package/src/asset-events.ts +97 -0
  194. package/src/asset-inspector-actions.ts +87 -0
  195. package/src/asset-preview-framing.ts +357 -0
  196. package/src/asset-preview.ts +2802 -0
  197. package/src/asset-selection-viewer-registry.ts +113 -0
  198. package/src/asset-selection.ts +133 -0
  199. package/src/asset-workflow/asset-capabilities.ts +344 -0
  200. package/src/asset-workflow/asset-import-jobs.ts +106 -0
  201. package/src/asset-workflow/asset-ledger-backend.ts +126 -0
  202. package/src/asset-workflow/asset-ledger.ts +156 -0
  203. package/src/asset-workflow/asset-materialization-report.ts +140 -0
  204. package/src/asset-workflow/asset-pack-manifest.ts +320 -0
  205. package/src/asset-workflow/asset-types.ts +142 -0
  206. package/src/asset-workflow/asset-workflow-quality.ts +61 -0
  207. package/src/asset-workflow/audio-preview-player.ts +193 -0
  208. package/src/asset-workflow/audio-waveform.ts +22 -0
  209. package/src/asset-workflow/cloud-asset-client.ts +263 -0
  210. package/src/asset-workflow/folder-preview.ts +345 -0
  211. package/src/asset-workflow/hosted-asset-materialization.ts +236 -0
  212. package/src/asset-workflow/image-view-scale.ts +32 -0
  213. package/src/asset-workflow/import-contract.ts +124 -0
  214. package/src/asset-workflow/ledger-write-lock.ts +244 -0
  215. package/src/asset-workflow/model-inspection.ts +818 -0
  216. package/src/asset-workflow/pixi-spritesheet.ts +197 -0
  217. package/src/asset-workflow/preview-resource-lifetime.ts +44 -0
  218. package/src/asset-workflow/project-asset-commands.ts +23 -0
  219. package/src/asset-workflow/project-asset-health.ts +139 -0
  220. package/src/asset-workflow/project-asset-operations.ts +154 -0
  221. package/src/asset-workflow/project-asset-roots.ts +68 -0
  222. package/src/asset-workflow/project-content.ts +288 -0
  223. package/src/asset-workflow/project-source-index.ts +550 -0
  224. package/src/asset-workflow/thumbnail-system.ts +256 -0
  225. package/src/authoring/active-adapter.ts +199 -0
  226. package/src/authoring/active-systems.ts +422 -0
  227. package/src/authoring/adapter-key.ts +18 -0
  228. package/src/authoring/authoring-asset-url.ts +27 -0
  229. package/src/authoring/bootstrap-state.ts +49 -0
  230. package/src/authoring/boundary-authoring-adapter.ts +184 -0
  231. package/src/authoring/breakpoint-state.ts +43 -0
  232. package/src/authoring/canvas-scene-guides.ts +76 -0
  233. package/src/authoring/component-instance-root.ts +171 -0
  234. package/src/authoring/composite-authoring-adapter.ts +2110 -0
  235. package/src/authoring/consumer-actions.ts +520 -0
  236. package/src/authoring/css-numeric-style.ts +97 -0
  237. package/src/authoring/design-time-layers.ts +849 -0
  238. package/src/authoring/design-time-mount-registry.ts +235 -0
  239. package/src/authoring/design-time-settle.ts +343 -0
  240. package/src/authoring/edit-mode-authoring.ts +619 -0
  241. package/src/authoring/eyedropper-session.ts +60 -0
  242. package/src/authoring/instance-source-menu-register.ts +13 -0
  243. package/src/authoring/instance-source-menu.ts +135 -0
  244. package/src/authoring/layered-pick.ts +183 -0
  245. package/src/authoring/live-gesture-lock.ts +50 -0
  246. package/src/authoring/live-object-transform.ts +62 -0
  247. package/src/authoring/mount-failure-report.ts +154 -0
  248. package/src/authoring/mounted-root-subjects.ts +144 -0
  249. package/src/authoring/no-authoring-adapter.ts +55 -0
  250. package/src/authoring/null-inspection-subjects.tsx +75 -0
  251. package/src/authoring/object3d-document-persistence.ts +106 -0
  252. package/src/authoring/object3d-document-session-registry.ts +120 -0
  253. package/src/authoring/object3d-document-session.ts +1326 -0
  254. package/src/authoring/object3d-gesture-controller.ts +113 -0
  255. package/src/authoring/panel-authoring.ts +121 -0
  256. package/src/authoring/prefab-instance-inspector-section.tsx +237 -0
  257. package/src/authoring/prefab-instance-section-model.ts +55 -0
  258. package/src/authoring/project-authoring-session.ts +105 -0
  259. package/src/authoring/provenance.ts +99 -0
  260. package/src/authoring/quarks-particle-systems.ts +19 -0
  261. package/src/authoring/react-canvas-navigation.ts +255 -0
  262. package/src/authoring/react-design-canvas-style.ts +20 -0
  263. package/src/authoring/react-story-board.ts +937 -0
  264. package/src/authoring/selection-scope.ts +195 -0
  265. package/src/authoring/shell-document-ops.ts +169 -0
  266. package/src/authoring/shell-object3d-document-write-policy.ts +108 -0
  267. package/src/authoring/shell-viewport-policy.ts +48 -0
  268. package/src/authoring/source-object3d-authoring-adapter.ts +526 -0
  269. package/src/authoring/stories-scope.ts +35 -0
  270. package/src/authoring/story-board-chrome-fit.ts +107 -0
  271. package/src/authoring/story-board-presentation.ts +111 -0
  272. package/src/authoring/three-projection-core.ts +226 -0
  273. package/src/authoring/viewport-pick-context.ts +40 -0
  274. package/src/authoring/viewport-raycast.ts +240 -0
  275. package/src/authoring/viewport-tool-context.ts +73 -0
  276. package/src/authoring/world-canvas-viewport-state.ts +35 -0
  277. package/src/authoring/world-hidden-viewport.ts +152 -0
  278. package/src/authoring/world-pan-state.ts +198 -0
  279. package/src/authoring/world-session-state.ts +101 -0
  280. package/src/authoring/write-pipe.ts +173 -0
  281. package/src/availability-tick.ts +66 -0
  282. package/src/bitmap-label.ts +120 -0
  283. package/src/blender-tab-metrics.ts +161 -0
  284. package/src/board-open-actions.ts +20 -0
  285. package/src/boot-routing.ts +391 -0
  286. package/src/build-identity.ts +15 -0
  287. package/src/bytes-codec.ts +62 -0
  288. package/src/camera-authoring.ts +175 -0
  289. package/src/cancellation-reason.ts +58 -0
  290. package/src/canvas-preview-frames.ts +482 -0
  291. package/src/capture-camera-pose.ts +77 -0
  292. package/src/chrome-registry.ts +159 -0
  293. package/src/chrome-slot-registry.ts +91 -0
  294. package/src/collaboration-client.ts +264 -0
  295. package/src/collaboration-presence.ts +41 -0
  296. package/src/command-dispatch.ts +19 -0
  297. package/src/command-listener.ts +2743 -0
  298. package/src/command-registry.ts +70 -0
  299. package/src/component-board-registry.ts +205 -0
  300. package/src/component-states-registry.ts +200 -0
  301. package/src/components/AgentPresentationNotice.tsx +75 -0
  302. package/src/components/AlignToolbar.tsx +204 -0
  303. package/src/components/AppRoot.tsx +394 -0
  304. package/src/components/ApplicationMenus.tsx +415 -0
  305. package/src/components/AssetBrowser.tsx +2843 -0
  306. package/src/components/AssetEditorShell.tsx +216 -0
  307. package/src/components/AssetInspectorToolSection.tsx +124 -0
  308. package/src/components/BoardRulers.tsx +354 -0
  309. package/src/components/CameraInfo.tsx +81 -0
  310. package/src/components/CanvasSceneViewport.tsx +556 -0
  311. package/src/components/CapabilityCoverageSection.tsx +185 -0
  312. package/src/components/CenterDocuments.tsx +22 -0
  313. package/src/components/ChromeSlot.tsx +20 -0
  314. package/src/components/CodeView.tsx +470 -0
  315. package/src/components/CollaborationHeaderControl.css +74 -0
  316. package/src/components/CompactInspectorCard.tsx +190 -0
  317. package/src/components/CompactInspectorShell.tsx +39 -0
  318. package/src/components/ConsolePanel.css +55 -0
  319. package/src/components/ConsolePanel.tsx +270 -0
  320. package/src/components/DefaultEditorLayout.tsx +106 -0
  321. package/src/components/DocumentHeaderStrip.tsx +96 -0
  322. package/src/components/DocumentShelfRail.tsx +45 -0
  323. package/src/components/DocumentThumbnail.tsx +345 -0
  324. package/src/components/EditorLeaseGuard.tsx +372 -0
  325. package/src/components/ErrorBanner.tsx +123 -0
  326. package/src/components/FolderPreviewTile.tsx +159 -0
  327. package/src/components/GameHierarchy.tsx +3842 -0
  328. package/src/components/GameplaySessionTimeline.tsx +295 -0
  329. package/src/components/InspectionProjection.tsx +968 -0
  330. package/src/components/Inspector.tsx +233 -0
  331. package/src/components/InspectorCanvasPreview.tsx +35 -0
  332. package/src/components/InspectorFieldsSection.tsx +290 -0
  333. package/src/components/InspectorObjectPreview.tsx +57 -0
  334. package/src/components/InspectorStoriesSection.tsx +92 -0
  335. package/src/components/InspectorToolSection.tsx +96 -0
  336. package/src/components/InspectorTransformSection.tsx +245 -0
  337. package/src/components/LightExplorerPanel.tsx +433 -0
  338. package/src/components/MediaProperties.tsx +145 -0
  339. package/src/components/NonThreeAuthoringBootstrap.tsx +19 -0
  340. package/src/components/Object3DDocumentToolbar.css +100 -0
  341. package/src/components/Object3DDocumentToolbar.tsx +454 -0
  342. package/src/components/Object3DDocumentViewport.tsx +58 -0
  343. package/src/components/ProjectHeader.css +617 -0
  344. package/src/components/ProjectHeader.tsx +328 -0
  345. package/src/components/ProjectLayout.tsx +249 -0
  346. package/src/components/ReactCanvasControls.tsx +284 -0
  347. package/src/components/RootSelectionOverlay.tsx +3162 -0
  348. package/src/components/RootTextEditor.tsx +79 -0
  349. package/src/components/SaveStatus.tsx +70 -0
  350. package/src/components/StageHost.tsx +1954 -0
  351. package/src/components/StageOverlays.tsx +21 -0
  352. package/src/components/StartupErrorScreen.tsx +76 -0
  353. package/src/components/StartupLoadingScreen.tsx +65 -0
  354. package/src/components/StatsOverlay.tsx +78 -0
  355. package/src/components/SurfaceStateOverlay.tsx +24 -0
  356. package/src/components/ToolContributionSurfaces.tsx +65 -0
  357. package/src/components/ToolHost.tsx +370 -0
  358. package/src/components/ToolObject3DPreview.tsx +39 -0
  359. package/src/components/Toolbar.tsx +595 -0
  360. package/src/components/TransientHint.tsx +44 -0
  361. package/src/components/TransportStrip.tsx +174 -0
  362. package/src/components/VersionControlSection.tsx +470 -0
  363. package/src/components/VgaiLogo.css +83 -0
  364. package/src/components/VgaiLogo.tsx +35 -0
  365. package/src/components/ViewportControlsHint.tsx +60 -0
  366. package/src/components/ViewportFurniture.tsx +401 -0
  367. package/src/components/ViewportOverlay.tsx +145 -0
  368. package/src/components/ViewportOverlaysMenu.tsx +153 -0
  369. package/src/components/ViewportShadingMenu.tsx +300 -0
  370. package/src/components/ViewportViewMenu.tsx +101 -0
  371. package/src/components/WorkspaceDocumentSurface.tsx +204 -0
  372. package/src/components/WorkspaceUtilitySurface.tsx +22 -0
  373. package/src/components/WorktreeSwitcher.css +239 -0
  374. package/src/components/WorktreeSwitcher.tsx +890 -0
  375. package/src/components/account-documents.tsx +1162 -0
  376. package/src/components/asset-documents.tsx +812 -0
  377. package/src/components/asset-editor-persistence.ts +216 -0
  378. package/src/components/asset-selection-section.tsx +535 -0
  379. package/src/components/asset-thumbnails.tsx +312 -0
  380. package/src/components/asset-viewers/AudioViewer.tsx +201 -0
  381. package/src/components/asset-viewers/EntityModelDocument.tsx +122 -0
  382. package/src/components/asset-viewers/EnvironmentAssetDocument.tsx +440 -0
  383. package/src/components/asset-viewers/GenericJsonViewer.tsx +102 -0
  384. package/src/components/asset-viewers/ImageViewer.tsx +300 -0
  385. package/src/components/asset-viewers/JsonAssetDocument.tsx +93 -0
  386. package/src/components/asset-viewers/LiveModuleDocument.tsx +417 -0
  387. package/src/components/asset-viewers/LutAssetDocument.tsx +444 -0
  388. package/src/components/asset-viewers/ModelAssetDocument.tsx +105 -0
  389. package/src/components/asset-viewers/Object3DPreview.tsx +359 -0
  390. package/src/components/asset-viewers/OnlineAssetDetail.tsx +421 -0
  391. package/src/components/asset-viewers/PasteboardModuleDocument.tsx +67 -0
  392. package/src/components/asset-viewers/QuarksAssetDocument.tsx +526 -0
  393. package/src/components/asset-viewers/ShaderAssetDocument.tsx +743 -0
  394. package/src/components/asset-viewers/SourceAssetViewer.tsx +281 -0
  395. package/src/components/asset-viewers/SpritesheetSpriteView.tsx +102 -0
  396. package/src/components/asset-viewers/VideoViewer.tsx +101 -0
  397. package/src/components/asset-viewers/shader-source.ts +144 -0
  398. package/src/components/asset-workflow.css +731 -0
  399. package/src/components/board-guides.ts +150 -0
  400. package/src/components/compact-inspector.css +539 -0
  401. package/src/components/core-utilities.tsx +90 -0
  402. package/src/components/editor-notifications.css +40 -0
  403. package/src/components/engine-workspace.css +274 -0
  404. package/src/components/inspector-preview-section.tsx +238 -0
  405. package/src/components/inspector-property-grouping.ts +64 -0
  406. package/src/components/inspector-revert-label.ts +20 -0
  407. package/src/components/inspector-selection.ts +42 -0
  408. package/src/components/inspector-stories-gating.ts +171 -0
  409. package/src/components/inspector-transform-subject.ts +11 -0
  410. package/src/components/inspector-transform.ts +75 -0
  411. package/src/components/kind-documents.tsx +500 -0
  412. package/src/components/palette-action-publisher.tsx +140 -0
  413. package/src/components/primitives/DraftColorInput.tsx +74 -0
  414. package/src/components/product-shell.css +1829 -0
  415. package/src/components/project-tool-documents.tsx +410 -0
  416. package/src/components/scene-documents.tsx +223 -0
  417. package/src/components/stage-keyboard.tsx +37 -0
  418. package/src/components/stage-overlay-set.tsx +107 -0
  419. package/src/components/stage-presence-markers.ts +478 -0
  420. package/src/components/standard-viewport-dressing.ts +417 -0
  421. package/src/components/status-contributions.tsx +403 -0
  422. package/src/components/tool-documents.tsx +309 -0
  423. package/src/components/tool-schema-form.tsx +262 -0
  424. package/src/components/use-after-paint.ts +41 -0
  425. package/src/components/use-project-image-assets.ts +86 -0
  426. package/src/components/viewport-header-controls.css +90 -0
  427. package/src/components/viewport-surface-status.tsx +55 -0
  428. package/src/components/workspace-history.ts +32 -0
  429. package/src/components/workspace-static-panel-registry.tsx +152 -0
  430. package/src/components/workspace-surfaces.css +621 -0
  431. package/src/components/world-documents.tsx +586 -0
  432. package/src/components/world-overlay-gestures.ts +1694 -0
  433. package/src/composite-screenshot.ts +1641 -0
  434. package/src/console-sync.ts +131 -0
  435. package/src/constraint-helper.ts +338 -0
  436. package/src/content-entry-source-registry.ts +184 -0
  437. package/src/coverage/authoring-seam-evidence.ts +300 -0
  438. package/src/coverage/canvas-reveal.ts +192 -0
  439. package/src/coverage/design-time-surfaces.ts +101 -0
  440. package/src/coverage/live-seam-evidence.ts +11 -0
  441. package/src/coverage/ontology-invariants.ts +466 -0
  442. package/src/coverage/session-vitals.ts +501 -0
  443. package/src/coverage/system-seam-evidence.ts +72 -0
  444. package/src/crash-null-boundary.ts +36 -0
  445. package/src/creation-site-edit.ts +1479 -0
  446. package/src/creation-site-registry.ts +160 -0
  447. package/src/delegate-harness-registry.ts +143 -0
  448. package/src/document-context-registry.ts +177 -0
  449. package/src/document-open-registry.ts +200 -0
  450. package/src/document-preview-source.ts +20 -0
  451. package/src/document-renderer-session.ts +138 -0
  452. package/src/editor-api.ts +46 -0
  453. package/src/editor-chrome-capture.ts +139 -0
  454. package/src/editor-commands.ts +164 -0
  455. package/src/editor-console.ts +563 -0
  456. package/src/editor-current-view.ts +82 -0
  457. package/src/editor-document-probe.ts +881 -0
  458. package/src/editor-git-client.ts +115 -0
  459. package/src/editor-host-door.ts +462 -0
  460. package/src/editor-hotkeys.ts +842 -0
  461. package/src/editor-lease-view.ts +39 -0
  462. package/src/editor-lease.ts +415 -0
  463. package/src/editor-mode.ts +19 -0
  464. package/src/editor-notifications.ts +140 -0
  465. package/src/editor-presence.ts +563 -0
  466. package/src/editor-presentation-activity.ts +50 -0
  467. package/src/editor-presentation-notice.ts +42 -0
  468. package/src/editor-runtime.tsx +145 -0
  469. package/src/editor-server-response.ts +86 -0
  470. package/src/editor-session-attribution.ts +75 -0
  471. package/src/editor-session-mode.ts +54 -0
  472. package/src/editor-shell-store.ts +1304 -0
  473. package/src/editor-state-facets.ts +74 -0
  474. package/src/editor-styles.css +33 -0
  475. package/src/editor-view-presentation.ts +810 -0
  476. package/src/editor-viewport.ts +5302 -0
  477. package/src/entity-lod.ts +31 -0
  478. package/src/entity-object.ts +91 -0
  479. package/src/files/file-provider.ts +62 -0
  480. package/src/files/project-files.ts +264 -0
  481. package/src/finders/index.ts +136 -0
  482. package/src/finders/scenes-from-entrypoint-selection.ts +387 -0
  483. package/src/frame/bridge.tsx +1408 -0
  484. package/src/frame/product.ts +77 -0
  485. package/src/gameplay-dom-recording.ts +319 -0
  486. package/src/gameplay-export-state.ts +14 -0
  487. package/src/gameplay-replay.ts +417 -0
  488. package/src/gameplay-session-time.ts +9 -0
  489. package/src/gameplay-sessions.ts +204 -0
  490. package/src/harness-chat-types.ts +253 -0
  491. package/src/hierarchy-component-marks.ts +298 -0
  492. package/src/hierarchy-drop.ts +91 -0
  493. package/src/hierarchy-expansion-state.ts +80 -0
  494. package/src/hierarchy-header-slot.ts +52 -0
  495. package/src/hierarchy-internals.ts +197 -0
  496. package/src/hierarchy-kind-icon.ts +217 -0
  497. package/src/hierarchy-mark-reader.ts +73 -0
  498. package/src/hierarchy-menu-registry.ts +67 -0
  499. package/src/hierarchy-node-rows.ts +307 -0
  500. package/src/hierarchy-panel-view.ts +280 -0
  501. package/src/hierarchy-projection.ts +76 -0
  502. package/src/hierarchy-row-cache.ts +243 -0
  503. package/src/hierarchy-row-model.ts +308 -0
  504. package/src/hierarchy-rows.ts +11 -0
  505. package/src/hierarchy-walk.ts +86 -0
  506. package/src/history/editor-session.ts +25 -0
  507. package/src/history/history-commands.ts +147 -0
  508. package/src/history/history-delegate.ts +163 -0
  509. package/src/history/history-limit-notices.ts +43 -0
  510. package/src/history/history-service.ts +1173 -0
  511. package/src/history/persistence-coordinator.ts +35 -0
  512. package/src/history/project-file-history.ts +386 -0
  513. package/src/history/project-root-history-backends.ts +139 -0
  514. package/src/history/resource-registry.ts +209 -0
  515. package/src/history/snapshot-store.ts +103 -0
  516. package/src/history/source-history-backend.ts +546 -0
  517. package/src/history/types.ts +124 -0
  518. package/src/hmr-registration-group.ts +67 -0
  519. package/src/hmr-stable-react-context.ts +23 -0
  520. package/src/hotkeys.ts +188 -0
  521. package/src/inference-diagnostics.ts +69 -0
  522. package/src/initial-project.ts +80 -0
  523. package/src/inspection/active-subject.ts +578 -0
  524. package/src/inspection/active-surface.ts +142 -0
  525. package/src/inspection/compose.ts +1064 -0
  526. package/src/inspection/display.ts +170 -0
  527. package/src/inspection/document-subject.ts +109 -0
  528. package/src/inspection/game-subject.ts +85 -0
  529. package/src/inspection/model.ts +542 -0
  530. package/src/inspection/null-subject.ts +115 -0
  531. package/src/inspection/serialize.ts +357 -0
  532. package/src/inspection/use-active-inspection.ts +180 -0
  533. package/src/inspector-presentation.ts +201 -0
  534. package/src/inspector-section-registry.ts +221 -0
  535. package/src/instance-source-actions.ts +163 -0
  536. package/src/instanced-presentation.ts +164 -0
  537. package/src/js-heap.ts +71 -0
  538. package/src/key-actions.ts +91 -0
  539. package/src/keymap-presets.ts +401 -0
  540. package/src/layout-policy.ts +31 -0
  541. package/src/learn-links.ts +73 -0
  542. package/src/light-explorer-model.ts +134 -0
  543. package/src/live-canvas-frame.ts +55 -0
  544. package/src/live-document.ts +279 -0
  545. package/src/live-module-source.ts +230 -0
  546. package/src/live-session-registry.ts +220 -0
  547. package/src/live-transition.ts +633 -0
  548. package/src/manifest-project.ts +107 -0
  549. package/src/model-thumbnail.ts +523 -0
  550. package/src/native-selection-style.ts +202 -0
  551. package/src/object3d-document-write-policy.ts +137 -0
  552. package/src/packaged-runtime.ts +108 -0
  553. package/src/palettes/maya.palette.json +57 -0
  554. package/src/palettes/substance.palette.json +57 -0
  555. package/src/pasteboard-module.ts +81 -0
  556. package/src/performance-profiler.ts +367 -0
  557. package/src/performance-sources.ts +69 -0
  558. package/src/play-boot-phase.ts +145 -0
  559. package/src/presentation-surface.ts +248 -0
  560. package/src/project-adapter.ts +1143 -0
  561. package/src/project-asset-refresh.ts +26 -0
  562. package/src/project-declaration-refresh.ts +31 -0
  563. package/src/project-local-state.ts +118 -0
  564. package/src/project-manager.ts +243 -0
  565. package/src/project-module-changes.ts +163 -0
  566. package/src/project-module-split.ts +266 -0
  567. package/src/project-provenance.ts +115 -0
  568. package/src/project-ready.ts +42 -0
  569. package/src/project-session-reset.ts +67 -0
  570. package/src/project-shape.ts +68 -0
  571. package/src/project-tool-discovery.ts +66 -0
  572. package/src/project-tools.ts +107 -0
  573. package/src/project-work-types.ts +149 -0
  574. package/src/projection/three.ts +898 -0
  575. package/src/projection/types.ts +44 -0
  576. package/src/readiness.ts +113 -0
  577. package/src/reflection-probe-helper.ts +142 -0
  578. package/src/reported-play-state.ts +90 -0
  579. package/src/resolve-relative-specifier.ts +33 -0
  580. package/src/scene-document-plan.ts +315 -0
  581. package/src/scene-framing.ts +315 -0
  582. package/src/scene-live-open.ts +210 -0
  583. package/src/scene-view-fog.ts +89 -0
  584. package/src/scoped-game-css.ts +152 -0
  585. package/src/session-orphan-record.ts +193 -0
  586. package/src/session-tombstone.ts +126 -0
  587. package/src/settings/settings-provider.ts +82 -0
  588. package/src/settings-store.ts +345 -0
  589. package/src/shared-view-restore.ts +42 -0
  590. package/src/shell-store-door.ts +45 -0
  591. package/src/source-conflict.ts +122 -0
  592. package/src/spatial-handle-visuals.ts +332 -0
  593. package/src/stage-context.ts +341 -0
  594. package/src/stage-store-registry.ts +63 -0
  595. package/src/stale-chunk-recovery.ts +34 -0
  596. package/src/state-report-deferral.ts +73 -0
  597. package/src/storage/host-files-storage.ts +97 -0
  598. package/src/storage/http-storage.ts +174 -0
  599. package/src/storage/index.ts +75 -0
  600. package/src/storage/mem-storage.ts +149 -0
  601. package/src/storage/path-lock.ts +44 -0
  602. package/src/storage/paths.ts +26 -0
  603. package/src/storage/types.ts +116 -0
  604. package/src/stories/StoryComponentThumbnail.tsx +184 -0
  605. package/src/stories/StoryPreviewMount.tsx +306 -0
  606. package/src/stories/component-content-source.tsx +106 -0
  607. package/src/stories/component-states-source.ts +78 -0
  608. package/src/stories/compose-project-stories.ts +255 -0
  609. package/src/stories/pixi-story-model.ts +30 -0
  610. package/src/stories/prefabs-finder.ts +54 -0
  611. package/src/stories/prefabs-from-stories.ts +182 -0
  612. package/src/stories/project-story-discovery.ts +78 -0
  613. package/src/stories/project-story-regions.ts +24 -0
  614. package/src/stories/story-actions.ts +54 -0
  615. package/src/stories/story-capture-command.ts +124 -0
  616. package/src/stories/story-capture.ts +584 -0
  617. package/src/stories/story-declared-medium.ts +126 -0
  618. package/src/stories/story-discovery.ts +176 -0
  619. package/src/stories/story-document-openers.ts +36 -0
  620. package/src/stories/story-dom-runtime.ts +78 -0
  621. package/src/stories/story-grouping.ts +111 -0
  622. package/src/stories/story-lane.ts +88 -0
  623. package/src/stories/story-mount-turn.ts +27 -0
  624. package/src/stories/story-opener.ts +260 -0
  625. package/src/stories/story-pixi-preview.ts +408 -0
  626. package/src/stories/story-presentation.ts +215 -0
  627. package/src/stories/story-registry.ts +517 -0
  628. package/src/stories/story-three-preview.ts +807 -0
  629. package/src/stories/three-story-model.ts +96 -0
  630. package/src/story-three-preview-runtime.ts +56 -0
  631. package/src/surface-keyboard.ts +112 -0
  632. package/src/surface-state.ts +124 -0
  633. package/src/tab-bootstrap.js +628 -0
  634. package/src/tab-census.ts +198 -0
  635. package/src/tab-lifecycle-client.ts +196 -0
  636. package/src/theme-library.ts +844 -0
  637. package/src/theme-preference.ts +378 -0
  638. package/src/theme.css +3437 -0
  639. package/src/three-viewport/bone-selection-highlight.ts +119 -0
  640. package/src/three-viewport/camera-fit.ts +41 -0
  641. package/src/three-viewport/interactive-renderer.ts +132 -0
  642. package/src/three-viewport/selection-brackets.ts +310 -0
  643. package/src/three-viewport/selection-outline.ts +183 -0
  644. package/src/three-viewport/skeleton-helper.ts +61 -0
  645. package/src/three-viewport/source-color.ts +167 -0
  646. package/src/three-viewport/studio-environment.ts +96 -0
  647. package/src/three-viewport-presentation.ts +23 -0
  648. package/src/tool-contribution-play.ts +74 -0
  649. package/src/tool-loader.ts +1798 -0
  650. package/src/transform-mode-request.ts +57 -0
  651. package/src/transient-hint.ts +78 -0
  652. package/src/trigger-volume-helper.ts +116 -0
  653. package/src/ui-source/adapter-region-includes.ts +241 -0
  654. package/src/ui-source/ensure-import.ts +132 -0
  655. package/src/ui-source/file-region-resolver.ts +302 -0
  656. package/src/ui-source/inspect.ts +775 -0
  657. package/src/ui-source/oid-transform.ts +1845 -0
  658. package/src/ui-source/plan-csf-story.ts +196 -0
  659. package/src/ui-source/plan-extract-component.ts +421 -0
  660. package/src/ui-source/plan-fork-component.ts +621 -0
  661. package/src/ui-source/plan-named-style.ts +95 -0
  662. package/src/ui-source/plan-source-edit.ts +353 -0
  663. package/src/ui-source/r3f-contract-resolver.ts +327 -0
  664. package/src/ui-source/r3f-diagnostic-index.ts +165 -0
  665. package/src/ui-source/r3f-environment-binding.ts +133 -0
  666. package/src/ui-source/r3f-joint-binding.ts +251 -0
  667. package/src/ui-source/r3f-lod-binding.ts +91 -0
  668. package/src/ui-source/r3f-particle-binding.ts +235 -0
  669. package/src/ui-source/r3f-physics-binding.ts +483 -0
  670. package/src/ui-source/r3f-project-contracts.ts +444 -0
  671. package/src/ui-source/relative-import-specifier.ts +34 -0
  672. package/src/ui-source/reparent-guard.ts +544 -0
  673. package/src/ui-source/source-edit-request.ts +97 -0
  674. package/src/ui-source/source-write-backend.ts +618 -0
  675. package/src/ui-source/syntactic-prop-specs.ts +296 -0
  676. package/src/ui-source/tier-source-write-backend.ts +279 -0
  677. package/src/ui-source/ts-ast.ts +171 -0
  678. package/src/ui-source/utility-class-support.ts +169 -0
  679. package/src/ui-source/write-component-default.ts +133 -0
  680. package/src/ui-source/writer.ts +1989 -0
  681. package/src/viewport-activation-timings.ts +840 -0
  682. package/src/viewport-authoring-policy.ts +186 -0
  683. package/src/viewport-controls-hint.ts +57 -0
  684. package/src/viewport-door.ts +237 -0
  685. package/src/viewport-shading-boundary.ts +12 -0
  686. package/src/vite-error-surface.ts +141 -0
  687. package/src/wait-until.ts +37 -0
  688. package/src/workspace-areas.ts +156 -0
  689. package/src/workspace-aux-commands.ts +11 -0
  690. package/src/workspace-available-documents.ts +127 -0
  691. package/src/workspace-core-utilities.ts +31 -0
  692. package/src/workspace-document-ids.ts +59 -0
  693. package/src/workspace-document-registry.ts +612 -0
  694. package/src/workspace-document-restore.ts +145 -0
  695. package/src/workspace-host-commands.ts +141 -0
  696. package/src/workspace-persistence-gate.ts +40 -0
  697. package/src/workspace-play-utilities.ts +44 -0
  698. package/src/workspace-presets.ts +425 -0
  699. package/src/workspace-regions.ts +294 -0
  700. package/src/workspace-state-persistence.ts +536 -0
  701. package/src/workspace-static-panels.ts +73 -0
  702. package/src/workspace-status-registry.ts +121 -0
  703. package/src/workspace-style.ts +239 -0
  704. package/src/workspace-utility-commands.ts +74 -0
  705. package/src/workspace-utility-registry.ts +263 -0
  706. package/src/workspace-viewport-rect.ts +97 -0
  707. package/src/world-adoption.ts +115 -0
  708. package/src/world-document-routing.ts +104 -0
  709. package/vite-plugin-creation-site-write.ts +184 -0
  710. package/vite-plugin-creation-site.ts +80 -0
  711. package/vite-plugin-game-static.ts +303 -0
  712. package/vite-plugin-module-doorways.ts +336 -0
  713. package/vite-plugin-product-contributions.ts +197 -0
  714. package/vite-plugin-project-game-static.ts +125 -0
  715. package/vite-plugin-project-jsx-js.ts +65 -0
  716. package/vite-plugin-project-root-absolute-assets.ts +359 -0
  717. package/vite-plugin-shared-react.ts +420 -0
  718. package/vite-plugin-shared-three.ts +203 -0
  719. package/vite-plugin-ui-oid.ts +2106 -0
@@ -0,0 +1,526 @@
1
+ /**
2
+ * Read-only authoring projection for a native Three.js document graph.
3
+ *
4
+ * The native Object3D tree is truth. The shared three projector
5
+ * (`../projection/three.ts`) walks it under the document-path identity and owns
6
+ * the index; the shared collapse view (`three-projection-core.ts`) turns that
7
+ * index into rows. This CONFIGURATION supplies the two axes — document-path
8
+ * identity, no write target — plus what only a document has: its own document
9
+ * row, the model classification on it, and the read-only inspector. It never
10
+ * fabricates descriptors or a JSON mirror. Source parameters rebuild the graph
11
+ * outside this adapter.
12
+ */
13
+
14
+ import type {
15
+ AuthoringAdapter,
16
+ AuthoringCapabilities,
17
+ AuthoringProvenance,
18
+ HierarchyProvider,
19
+ InspectorProvider,
20
+ PropertyDescriptor,
21
+ SelectionProvider,
22
+ Transform,
23
+ TransformProvider,
24
+ } from '@volter/editor-project/adapter';
25
+ import { isEditorOwnedObject } from '@volter/editor-threejs/viewport/editor-layers';
26
+ import { object3DAuthoringSubjectOf } from '@volter/editor-threejs/adapter/object3d-authoring-subject';
27
+ import { getUserData } from '@volter/editor-threejs/ecs/user-data';
28
+ import type * as THREE from 'three';
29
+ import {
30
+ classifyModelStructure,
31
+ inspectModel,
32
+ inspectModelRig,
33
+ } from '../asset-workflow/model-inspection';
34
+ import type { EditorShellStore } from '../editor-shell-store';
35
+ import { documentPathIdentity, ThreeProjector } from '../projection/three';
36
+ import {
37
+ CollapsedHierarchyView,
38
+ readLocalTransform,
39
+ StoreSelectionAdoption,
40
+ } from './three-projection-core';
41
+
42
+ export interface SourceObject3DAuthoringOptions {
43
+ readonly documentId: string;
44
+ readonly title: string;
45
+ readonly sourcePath: string;
46
+ readonly documentKind?: 'source' | 'asset';
47
+ /** The Asset Lab's import audit on this document's inspector — see
48
+ * `ToolObject3DAuthoringProps.audit`. Default on. */
49
+ readonly audit?: boolean;
50
+ /** Authored content roots when the scene also contains a document-owned
51
+ * presentation container. Omitted preserves the native projection roots. */
52
+ readonly hierarchyRoots?: readonly THREE.Object3D[];
53
+ readonly provenance?: AuthoringProvenance;
54
+ readonly modelSource?:
55
+ | { readonly kind: 'project-file'; readonly path: string }
56
+ | { readonly kind: 'entity'; readonly entityId: string };
57
+ }
58
+
59
+ /** `node()` runs on every hierarchy render; classifying a whole graph there
60
+ * would walk it each time. Keyed by the root object, so a rebuilt graph is a
61
+ * fresh entry and a disposed one is collected with it. */
62
+ const documentTypeLabelByRoot = new WeakMap<THREE.Object3D, string>();
63
+
64
+ function classifyDocumentRoot(root: THREE.Object3D): string {
65
+ let splat = false;
66
+ root.traverse((object) => {
67
+ if (getUserData(object, 'gaussianSplat')) splat = true;
68
+ });
69
+ if (splat) return 'Gaussian splat';
70
+ const inspection = inspectModel(root);
71
+ const rig = inspectModelRig(root);
72
+ return {
73
+ static: 'Static model',
74
+ animated: 'Animated model',
75
+ rigged: 'Rigged model',
76
+ skinned: 'Skinned model',
77
+ }[classifyModelStructure(inspection, rig)];
78
+ }
79
+
80
+ function materialOf(object: THREE.Object3D): THREE.Material | null {
81
+ const material = (object as THREE.Mesh).material;
82
+ if (Array.isArray(material)) return material[0] ?? null;
83
+ return material ?? null;
84
+ }
85
+
86
+ function colorOf(material: THREE.Material | null): THREE.Color | null {
87
+ const candidate = material as (THREE.Material & { color?: THREE.Color }) | null;
88
+ return candidate?.color ?? null;
89
+ }
90
+
91
+ export class SourceObject3DAuthoringAdapter implements AuthoringAdapter {
92
+ private readonly documentNodeId: string;
93
+ /** The shared three projector over this document's graph. */
94
+ private readonly projector: ThreeProjector;
95
+ private readonly hierarchyRootIds: readonly string[];
96
+ /** The shared collapse view over {@link projector} — see
97
+ * `three-projection-core.ts`. */
98
+ private readonly view: CollapsedHierarchyView;
99
+ /** Selection, shared with the store the viewport writes to — see
100
+ * `three-projection-core.ts`. */
101
+ private readonly selectionState: StoreSelectionAdoption;
102
+ private markedSelection = new Set<THREE.Object3D>();
103
+
104
+ readonly capabilities: AuthoringCapabilities = {
105
+ transform: false,
106
+ inspectorFields: true,
107
+ persist: false,
108
+ };
109
+
110
+ readonly provenance: AuthoringProvenance;
111
+
112
+ constructor(
113
+ private readonly store: EditorShellStore,
114
+ private readonly scene: THREE.Scene,
115
+ readonly options: SourceObject3DAuthoringOptions,
116
+ ) {
117
+ this.provenance =
118
+ options.provenance ??
119
+ (options.documentKind === 'asset'
120
+ ? {
121
+ source: 'document',
122
+ label: 'derived asset',
123
+ detail: 'Loaded from an ordinary project asset. Edit its source or import recipe.',
124
+ }
125
+ : {
126
+ source: 'source-code',
127
+ label: 'source',
128
+ detail:
129
+ 'Instantiated from project TypeScript. Edit source or exposed parameters, then rebuild.',
130
+ });
131
+ this.documentNodeId = `object3d-document:${options.documentId}`;
132
+ // The projector stamps `userData.entityId` as it walks, so EditorViewport
133
+ // and its gizmo/pick code consume the same native id.
134
+ this.projector = new ThreeProjector(documentPathIdentity(options.documentId));
135
+ this.indexGraph();
136
+ if (
137
+ options.hierarchyRoots &&
138
+ new Set(options.hierarchyRoots).size !== options.hierarchyRoots.length
139
+ ) {
140
+ throw new Error(
141
+ `Object3D document "${options.title}" declared the same hierarchy root twice.`,
142
+ );
143
+ }
144
+ const declaredRootSet = new Set(options.hierarchyRoots ?? []);
145
+ for (const root of declaredRootSet) {
146
+ let parent = root.parent;
147
+ while (parent && parent !== scene) {
148
+ if (declaredRootSet.has(parent)) {
149
+ throw new Error(
150
+ `Object3D document "${options.title}" declared nested hierarchy roots; roots must be non-overlapping.`,
151
+ );
152
+ }
153
+ parent = parent.parent;
154
+ }
155
+ }
156
+ this.hierarchyRootIds = options.hierarchyRoots
157
+ ? options.hierarchyRoots.map((object) => {
158
+ const id = this.idByObject.get(object);
159
+ if (!id) {
160
+ throw new Error(
161
+ `Object3D document "${options.title}" declared a hierarchy root outside its native graph.`,
162
+ );
163
+ }
164
+ return id;
165
+ })
166
+ : [...this.projector.rootIds];
167
+ this.view = new CollapsedHierarchyView({
168
+ projector: this.projector,
169
+ scene,
170
+ documentNodeId: this.documentNodeId,
171
+ rootIds: this.hierarchyRootIds,
172
+ });
173
+ this.selectionState = new StoreSelectionAdoption({
174
+ store,
175
+ owns: (id) => this.byId.has(id),
176
+ initial: [this.documentNodeId],
177
+ onChange: (ids) => this.syncMarkedSelection(ids),
178
+ });
179
+ }
180
+
181
+ // ------------------------------------------------ graph mutated after mount
182
+ //
183
+ // The constructor's walk is a snapshot of the graph AT MOUNT, and one class
184
+ // of document mutates its graph afterwards: the live module document
185
+ // (`components/asset-viewers/LiveModuleDocument.tsx`) keeps a stable
186
+ // container root and SWAPS ITS CHILD on every save, precisely so the
187
+ // viewport's camera survives a rebuild. Measured 2026-08-29: the viewport
188
+ // showed the rebuilt model while the hierarchy kept the mount-time walk, so
189
+ // the document row lost its child and the picker addressed a disposed
190
+ // object.
191
+ //
192
+ // The fix is `r3f-source-authoring-adapter.ts`'s, transcribed: re-index on
193
+ // the GRAPH'S OWN structural events. `parent.add(child)` dispatches
194
+ // `childadded` on the parent, so watching the scene plus every indexed
195
+ // object covers every path a subtree can enter through, and no document has
196
+ // to remember to tell this adapter anything. Editor furniture (gizmo and
197
+ // helper attachments) is filtered so selection churn does not re-index.
198
+
199
+ private disposed = false;
200
+ dispose(): void {
201
+ if (this.disposed) return;
202
+ this.disposed = true;
203
+ for (const object of this.watchedForStructure) {
204
+ object.removeEventListener('childadded', this.onStructureChanged);
205
+ object.removeEventListener('childremoved', this.onStructureChanged);
206
+ }
207
+ this.watchedForStructure = [];
208
+ }
209
+
210
+ private watchedForStructure: THREE.Object3D[] = [];
211
+ private structureReindexQueued = false;
212
+
213
+ private readonly onStructureChanged = (event: { child: THREE.Object3D }): void => {
214
+ if (isEditorOwnedObject(event.child)) return;
215
+ this.scheduleStructureReindex();
216
+ };
217
+
218
+ private indexGraph(): void {
219
+ this.projector.project(this.scene);
220
+ this.watchStructure();
221
+ }
222
+
223
+ /** (Re)attach `childadded`/`childremoved` across the indexed graph, so a
224
+ * freshly-swapped subtree is watched from the re-index that found it. */
225
+ private watchStructure(): void {
226
+ const structural = (object: THREE.Object3D) =>
227
+ object as unknown as {
228
+ addEventListener(
229
+ type: 'childadded' | 'childremoved',
230
+ listener: (event: { child: THREE.Object3D }) => void,
231
+ ): void;
232
+ removeEventListener(
233
+ type: 'childadded' | 'childremoved',
234
+ listener: (event: { child: THREE.Object3D }) => void,
235
+ ): void;
236
+ };
237
+ for (const object of this.watchedForStructure) {
238
+ structural(object).removeEventListener('childadded', this.onStructureChanged);
239
+ structural(object).removeEventListener('childremoved', this.onStructureChanged);
240
+ }
241
+ this.watchedForStructure = [];
242
+ const watch = (object: THREE.Object3D): void => {
243
+ structural(object).addEventListener('childadded', this.onStructureChanged);
244
+ structural(object).addEventListener('childremoved', this.onStructureChanged);
245
+ this.watchedForStructure.push(object);
246
+ };
247
+ watch(this.scene);
248
+ for (const [, object] of this.byId) watch(object);
249
+ }
250
+
251
+ /** One re-index per mutation burst: a swap is remove-then-add, and a
252
+ * microtask runs after the whole subtree is in the graph. */
253
+ private scheduleStructureReindex(): void {
254
+ if (this.disposed || this.structureReindexQueued) return;
255
+ this.structureReindexQueued = true;
256
+ queueMicrotask(() => {
257
+ this.structureReindexQueued = false;
258
+ if (this.disposed) return;
259
+ this.indexGraph();
260
+ if (this.store.scene !== this.scene) return;
261
+ const map = this.store.objectMap;
262
+ map.clear();
263
+ for (const [id, object] of this.byId) map.set(id, object);
264
+ // Selection can name an object the swap removed; keep it inside the
265
+ // index the hierarchy, picker and gizmo now consume.
266
+ const retained = [...this.store.selectedEntityIds].filter(
267
+ (id) => id === this.documentNodeId || this.byId.has(id),
268
+ );
269
+ if (retained.length !== this.store.selectedEntityIds.size) {
270
+ this.store.selectMultiple(retained);
271
+ }
272
+ // `subscribe` on this adapter IS the store's subscribe, so notifying the
273
+ // store is this adapter's own change signal.
274
+ this.store.notifyIngestObjectMapEdit();
275
+ });
276
+ }
277
+
278
+ private get byId(): ReadonlyMap<string, THREE.Object3D> {
279
+ return this.projector.objects;
280
+ }
281
+
282
+ private get idByObject(): ReadonlyMap<THREE.Object3D, string> {
283
+ return this.projector.idsByObject;
284
+ }
285
+
286
+ /** The document root's structural type, cached per root graph. `undefined`
287
+ * for a SOURCE document, whose root is whatever the project built and not
288
+ * a model with a structure to classify. */
289
+ private documentTypeLabel(): string | undefined {
290
+ if (this.options.documentKind !== 'asset') return undefined;
291
+ // NOT `documentRootObject` — that reads the document node's `childIds`,
292
+ // and this is called while building that node.
293
+ const root = this.scene.children.find((child) => this.idByObject.has(child)) ?? null;
294
+ if (!root) return undefined;
295
+ const cached = documentTypeLabelByRoot.get(root);
296
+ if (cached !== undefined) return cached;
297
+ const label = classifyDocumentRoot(root);
298
+ documentTypeLabelByRoot.set(root, label);
299
+ return label;
300
+ }
301
+
302
+ readonly hierarchy: HierarchyProvider = {
303
+ roots: () => [this.hierarchy.node(this.documentNodeId)!],
304
+ node: (id) => {
305
+ if (id === this.documentNodeId) {
306
+ const typeLabel = this.documentTypeLabel();
307
+ return {
308
+ id,
309
+ label: this.options.title,
310
+ secondaryLabel: this.options.sourcePath,
311
+ role: 'document',
312
+ kind: this.options.documentKind === 'asset' ? 'model-asset' : 'three-source',
313
+ // What to CALL this document's root, on the inspector's identity
314
+ // row — "Rigged model", "Gaussian splat". It is the structure of
315
+ // the graph this adapter is projecting, so the adapter is the only
316
+ // thing that can answer it; the classification is cached per root
317
+ // because `node()` is called on every hierarchy render.
318
+ ...(typeLabel ? { typeLabel } : {}),
319
+ parentId: null,
320
+ childIds: this.view.rootIds(),
321
+ };
322
+ }
323
+ const object = this.byId.get(id);
324
+ return object ? this.view.node(object) : null;
325
+ },
326
+ object3D: (id) => this.byId.get(id) ?? null,
327
+ idForObject3D: (object) => this.idByObject.get(object) ?? null,
328
+ };
329
+
330
+ readonly selection: SelectionProvider = {
331
+ get: () => this.selectionState.current(),
332
+ // The document row is selectable and is NOT one of this projection's
333
+ // objects, which is why it survives this filter and never reaches the store.
334
+ set: (ids) =>
335
+ this.selectionState.publish(
336
+ ids.filter((id) => id === this.documentNodeId || this.byId.has(id)),
337
+ ),
338
+ };
339
+
340
+ /**
341
+ * THE REASON THIS PROJECTION REFUSES, spelled once because it is PRINTED:
342
+ * it lands in the tooltip of every generic shell control that asks this
343
+ * adapter whether it may write.
344
+ */
345
+ private static readonly READ_ONLY_REASON =
346
+ 'This document shows what the module builds; its properties are read-only here. Edit the module.';
347
+
348
+ /**
349
+ * READ-ONLY, AND IT SAYS SO NOW. Every write door on this adapter is a
350
+ * no-op and always was — `transforms.beginEdit`/`apply`/`endEdit` below and
351
+ * `inspector.set` further down all return `undefined` — but it declared no
352
+ * `editability`, which is the seam the shell asks BEFORE drawing a control
353
+ * (`InspectorProvider.editability`'s own contract names "hierarchy eye/lock
354
+ * controls"). Its default is `{ writable: true }`, so the shell believed
355
+ * this projection and drew a live control over a surface that discards it.
356
+ *
357
+ * MEASURED 2026-09-19 in a cold models scaffold, which is what bought this:
358
+ * the Outliner's EYE on a Model document lit, kept its `Hide` tooltip and
359
+ * its `aria-pressed="false"`, and left the frame hash byte-identical —
360
+ * `GameHierarchy.tsx` gates it on `visibleKnown && (editability?.writable ??
361
+ * true)`, and `visible` is knowable here (it reads `object.visible`) even
362
+ * though it is `readonly: true` in the very descriptor list below.
363
+ *
364
+ * `transforms` DELIBERATELY DOES NOT GET ONE, and that is a measurement
365
+ * rather than an oversight. Its write doors are no-ops too, so the honest
366
+ * answer is the same — but declaring it bought nothing and cost a mark:
367
+ * `transform-mode-request.ts`, the one place that would have NAMED the
368
+ * refusal, reads `store.selectedEntityIds` off the SHELL store while a
369
+ * document stage keeps its selection in its own, so it returns before it
370
+ * can speak and the host's Move/Rotate/Scale stayed silent either way —
371
+ * while `GameHierarchy`'s `hierarchy-transform-lock` span immediately
372
+ * appeared on every row, a glyph Blender's Outliner does not draw. Answer
373
+ * it when something acts on the answer.
374
+ */
375
+ private readonly readOnly = (): { writable: boolean; reason: string } => ({
376
+ writable: false,
377
+ reason: SourceObject3DAuthoringAdapter.READ_ONLY_REASON,
378
+ });
379
+
380
+ readonly transforms: TransformProvider = {
381
+ get: (id): Transform => readLocalTransform(this.byId.get(id) ?? null),
382
+ beginEdit: () => undefined,
383
+ apply: () => undefined,
384
+ endEdit: () => undefined,
385
+ };
386
+
387
+ readonly inspector: InspectorProvider = {
388
+ properties: (id): PropertyDescriptor[] => {
389
+ if (id === this.documentNodeId) {
390
+ // A document that declined the import audit carries its own sections;
391
+ // the name is the identity row's and the path is the hierarchy
392
+ // header's, so the loose "Properties" grid would only repeat them.
393
+ if (this.options.audit === false) return [];
394
+ return [
395
+ { path: 'name', label: 'Name', type: 'string', readonly: true },
396
+ { path: 'source.path', label: 'Source', type: 'string', readonly: true },
397
+ ];
398
+ }
399
+ const object = this.byId.get(id);
400
+ if (!object) return [];
401
+ const subject = object3DAuthoringSubjectOf(object);
402
+ if (subject?.fields) {
403
+ return subject.fields().map(({ value: _value, ...descriptor }) => descriptor);
404
+ }
405
+ const properties: PropertyDescriptor[] = [
406
+ { path: 'name', label: 'Name', type: 'string', readonly: true },
407
+ { path: 'visible', label: 'Visible', type: 'boolean', readonly: true },
408
+ { path: 'object.type', label: 'Native type', type: 'string', readonly: true },
409
+ ];
410
+ const mesh = object as THREE.Mesh;
411
+ if (mesh.isMesh && mesh.geometry) {
412
+ const position = mesh.geometry.getAttribute('position');
413
+ properties.push({
414
+ path: 'mesh.vertices',
415
+ label: 'Vertices',
416
+ type: 'number',
417
+ readonly: true,
418
+ group: 'Mesh',
419
+ });
420
+ if (position) {
421
+ properties.push({
422
+ path: 'mesh.triangles',
423
+ label: 'Triangles',
424
+ type: 'number',
425
+ readonly: true,
426
+ group: 'Mesh',
427
+ });
428
+ }
429
+ }
430
+ const material = materialOf(object);
431
+ if (material) {
432
+ properties.push({
433
+ path: 'material.type',
434
+ label: 'Material',
435
+ type: 'string',
436
+ readonly: true,
437
+ group: 'Material',
438
+ });
439
+ if (colorOf(material)) {
440
+ properties.push({
441
+ path: 'material.color',
442
+ label: 'Color',
443
+ type: 'color',
444
+ readonly: true,
445
+ group: 'Material',
446
+ });
447
+ }
448
+ }
449
+ const skinned = object as THREE.SkinnedMesh;
450
+ if (skinned.isSkinnedMesh && skinned.skeleton) {
451
+ properties.push({
452
+ path: 'skin.bones',
453
+ label: 'Bones',
454
+ type: 'number',
455
+ readonly: true,
456
+ group: 'Skin',
457
+ });
458
+ }
459
+ return properties;
460
+ },
461
+ get: (id, path) => {
462
+ if (id === this.documentNodeId) {
463
+ if (path === 'name') return this.options.title;
464
+ if (path === 'source.path') return this.options.sourcePath;
465
+ return undefined;
466
+ }
467
+ const object = this.byId.get(id);
468
+ if (!object) return undefined;
469
+ const subject = object3DAuthoringSubjectOf(object);
470
+ const subjectField = subject?.fields?.().find((field) => field.path === path);
471
+ if (subjectField) return subjectField.value();
472
+ if (path === 'name') return object.name || object.type;
473
+ if (path === 'visible') return object.visible;
474
+ if (path === 'object.type') return object.type;
475
+ const mesh = object as THREE.Mesh;
476
+ if (path === 'mesh.vertices') return mesh.geometry?.getAttribute('position')?.count ?? 0;
477
+ if (path === 'mesh.triangles') {
478
+ const geometry = mesh.geometry;
479
+ return (geometry?.index?.count ?? geometry?.getAttribute('position')?.count ?? 0) / 3;
480
+ }
481
+ const material = materialOf(object);
482
+ if (path === 'material.type') return material?.type;
483
+ if (path === 'material.color') {
484
+ const color = colorOf(material);
485
+ return color ? `#${color.getHexString()}` : undefined;
486
+ }
487
+ if (path === 'skin.bones') return (object as THREE.SkinnedMesh).skeleton?.bones.length ?? 0;
488
+ return undefined;
489
+ },
490
+ set: () => undefined,
491
+ // See {@link readOnly}: `set` above writes nothing, so no generic surface
492
+ // may draw a live control over one of these values.
493
+ editability: () => this.readOnly(),
494
+ };
495
+
496
+ subscribe(listener: () => void): () => void {
497
+ return this.store.subscribe(listener);
498
+ }
499
+
500
+ get documentId(): string {
501
+ return this.documentNodeId;
502
+ }
503
+
504
+ get documentRootObject(): THREE.Object3D | null {
505
+ const rootId = this.hierarchy.node(this.documentNodeId)?.childIds[0];
506
+ return rootId ? (this.byId.get(rootId) ?? null) : null;
507
+ }
508
+
509
+ private syncMarkedSelection(ids: readonly string[]): void {
510
+ const next = new Set(
511
+ ids
512
+ .map((id) => this.byId.get(id) ?? null)
513
+ .filter((object): object is THREE.Object3D => object !== null)
514
+ .filter((object) => object3DAuthoringSubjectOf(object)?.selectionChanged !== undefined),
515
+ );
516
+ for (const object of this.markedSelection) {
517
+ if (!next.has(object)) object3DAuthoringSubjectOf(object)?.selectionChanged?.(false);
518
+ }
519
+ for (const object of next) {
520
+ if (!this.markedSelection.has(object)) {
521
+ object3DAuthoringSubjectOf(object)?.selectionChanged?.(true);
522
+ }
523
+ }
524
+ this.markedSelection = next;
525
+ }
526
+ }
@@ -0,0 +1,35 @@
1
+ /**
2
+ * The `StoriesProvider` node-id protocol's one reserved value.
3
+ *
4
+ * `storiesFor`/`active`/`apply` all take a node id. The EMPTY id is not a node:
5
+ * it is the WORLD-LEVEL question — "list YOUR stories", asked with no node in
6
+ * hand. A world-level provider (contract scenes, a react root's portable CSF)
7
+ * ignores the node id and answers its whole list; a node-scoped provider (the
8
+ * binding `component-states-registry.ts` hands an adapter) has no node here
9
+ * and answers nothing. That
10
+ * difference is the ONE derivation of "which scope is this provider?" in the
11
+ * editor — `components/inspector-stories-gating.ts`'s
12
+ * `resolveWorldStoriesInput`/`resolveNodeScopedStories` are its two readings
13
+ * and must not grow a third.
14
+ *
15
+ * Because it is a PROBE, the answer to it must be a property of the provider,
16
+ * never of session state: an implementer whose empty-id answer depends on what
17
+ * the user last clicked makes its own scope flip under the shell mid-session.
18
+ * Implementers that special-case the empty id import this constant rather than
19
+ * spelling `''`, so the protocol has one definition and the probe and the
20
+ * answer can never drift apart.
21
+ *
22
+ * It lives here (a leaf module importing nothing) rather than beside the gating
23
+ * probe because the providers in this directory answer it, and
24
+ * `components/inspector-stories-gating.ts` value-imports two of them
25
+ * (`ReactRootAuthoringAdapter`, `CompositeAuthoringAdapter`) — so a back-import
26
+ * from an adapter would be a runtime cycle.
27
+ *
28
+ * Nor does it belong in the engine beside `StoriesProvider`. `@volter/editor-project/adapter`,
29
+ * the barrel every consumer imports that type through, is deliberately
30
+ * TYPE-ONLY (P-6) and may not re-export a value; and reaching past it to
31
+ * `@volter/editor-project/adapter/authoring` (which does carry values) would publish an
32
+ * EDITOR-only protocol constant as a public engine entry point, since the
33
+ * engine's export map is the wildcard `"./*"`.
34
+ */
35
+ export const WORLD_SCOPE_NODE_ID = '';
@@ -0,0 +1,107 @@
1
+ /**
2
+ * Board chrome — frame names and group names — is CONSTANT-SIZE client-space
3
+ * furniture floating over a board that zooms underneath it (the deliberate
4
+ * Figma-style choice: names stay readable at any scale). The authored gaps
5
+ * that chrome lives in DO shrink with zoom, so below some zoom a constant
6
+ * 26px frame-name stack no longer fits a 64-authored-px row gap and paints
7
+ * over the frames of the row above.
8
+ *
9
+ * This module owns the one rule that prevents that: **chrome degrades, frames
10
+ * never move**. Given the client-space room above a row of frames, it returns
11
+ * the scale/opacity/offset the chrome must adopt so its painted box always
12
+ * ends at or below whatever sits above it. Layout stays zoom-independent.
13
+ *
14
+ * Priority: a group name is the navigation anchor at overview zoom, so it is
15
+ * served FIRST out of the available room and therefore degrades LAST; the
16
+ * frame name gets whatever is left over.
17
+ */
18
+
19
+ export const FRAME_LABEL_HEIGHT = 20;
20
+ export const FRAME_LABEL_GAP = 6;
21
+ export const GROUP_LABEL_HEIGHT = 22;
22
+ export const GROUP_LABEL_GAP = 10;
23
+
24
+ /** Client px a frame name claims above its frame's top edge at scale 1. */
25
+ export const FRAME_LABEL_STACK = FRAME_LABEL_HEIGHT + FRAME_LABEL_GAP;
26
+ /** Client px a group name claims above the frame-name stack at scale 1. */
27
+ export const GROUP_LABEL_STACK = GROUP_LABEL_HEIGHT + GROUP_LABEL_GAP;
28
+
29
+ /** Below this scale a name starts fading; below the hide scale it is dropped
30
+ * entirely, because an unreadable sliver of text is noise, not information. */
31
+ const FRAME_FADE_FROM = 0.6;
32
+ const FRAME_HIDE_BELOW = 0.4;
33
+ const GROUP_FADE_FROM = 0.7;
34
+ const GROUP_HIDE_BELOW = 0.45;
35
+
36
+ export interface ChromePlacement {
37
+ /** Uniform scale, applied with `transform-origin` at the element's bottom-left. */
38
+ readonly scale: number;
39
+ /** 0..1; 0 only when `visible` is false. */
40
+ readonly opacity: number;
41
+ /** false → do not paint (and do not accept pointer events) at all. */
42
+ readonly visible: boolean;
43
+ /** Client px to subtract from the row's top edge to get the element's `top`.
44
+ * Accounts for the element's own unscaled height, since the scale pivots on
45
+ * its bottom edge. */
46
+ readonly offset: number;
47
+ }
48
+
49
+ export interface StoryChromePlacement {
50
+ readonly frame: ChromePlacement;
51
+ /** null when the row carries no group name. */
52
+ readonly group: ChromePlacement | null;
53
+ }
54
+
55
+ function fade(scale: number, fadeFrom: number, hideBelow: number): [number, boolean] {
56
+ if (scale >= fadeFrom) return [1, true];
57
+ if (scale <= hideBelow) return [0, false];
58
+ return [(scale - hideBelow) / (fadeFrom - hideBelow), true];
59
+ }
60
+
61
+ /**
62
+ * Fit one frame row's chrome into the client-space `room` above it — the
63
+ * distance from the row's top edge to the bottom edge of the nearest frames
64
+ * above it (`Infinity` for the first row of the board, which has nothing
65
+ * above it to collide with).
66
+ *
67
+ * Invariant: the painted top of every returned placement is at or below
68
+ * `rowTop - room`, so chrome never paints over a frame that is not its own.
69
+ */
70
+ export function placeStoryChrome(room: number, withGroupLabel: boolean): StoryChromePlacement {
71
+ const usable = Math.max(0, room);
72
+ const groupScale = withGroupLabel ? Math.min(1, usable / GROUP_LABEL_STACK) : 0;
73
+ const [groupOpacity, groupVisible] = fade(groupScale, GROUP_FADE_FROM, GROUP_HIDE_BELOW);
74
+
75
+ const frameRoom = Math.max(0, usable - GROUP_LABEL_STACK * groupScale);
76
+ const frameScale = Math.min(1, frameRoom / FRAME_LABEL_STACK);
77
+ const [frameOpacity, frameVisible] = fade(frameScale, FRAME_FADE_FROM, FRAME_HIDE_BELOW);
78
+
79
+ // A dropped frame name reserves nothing, which lets the group name settle
80
+ // closer to the frames instead of floating over an empty band.
81
+ const frameConsumed = frameVisible ? FRAME_LABEL_STACK * frameScale : 0;
82
+
83
+ return {
84
+ frame: {
85
+ scale: frameScale,
86
+ opacity: frameOpacity,
87
+ visible: frameVisible,
88
+ offset: FRAME_LABEL_GAP * frameScale + FRAME_LABEL_HEIGHT,
89
+ },
90
+ group: withGroupLabel
91
+ ? {
92
+ scale: groupScale,
93
+ opacity: groupOpacity,
94
+ visible: groupVisible,
95
+ offset: frameConsumed + GROUP_LABEL_GAP * groupScale + GROUP_LABEL_HEIGHT,
96
+ }
97
+ : null,
98
+ };
99
+ }
100
+
101
+ /** Paint one chrome element at the placement this module computed. */
102
+ export function applyStoryChrome(element: HTMLElement, placement: ChromePlacement): void {
103
+ element.style.transformOrigin = '0 100%';
104
+ element.style.transform = placement.scale >= 1 ? '' : `scale(${placement.scale})`;
105
+ element.style.opacity = placement.visible ? String(placement.opacity) : '0';
106
+ element.style.display = placement.visible ? '' : 'none';
107
+ }