@weasel-js/core 1.6.1 → 1.7.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 (1005) hide show
  1. package/CHANGELOG.md +1006 -0
  2. package/README.md +28 -9
  3. package/dist/WeaselProvider.js +15 -0
  4. package/dist/WeaselProvider.js.map +1 -0
  5. package/dist/affordances/composeAffordanceLayer.js +224 -0
  6. package/dist/affordances/composeAffordanceLayer.js.map +1 -0
  7. package/dist/affordances/cornerResize.js +69 -0
  8. package/dist/affordances/cornerResize.js.map +1 -0
  9. package/dist/affordances/hitAffordanceRegions.js +138 -0
  10. package/dist/affordances/hitAffordanceRegions.js.map +1 -0
  11. package/dist/affordances/pathAnchors.js +66 -0
  12. package/dist/affordances/pathAnchors.js.map +1 -0
  13. package/dist/affordances/rotationHandle.js +103 -0
  14. package/dist/affordances/rotationHandle.js.map +1 -0
  15. package/dist/animation/behaviors/momentum.js +118 -0
  16. package/dist/animation/behaviors/momentum.js.map +1 -0
  17. package/dist/animation/colorHelpers.js +135 -0
  18. package/dist/animation/colorHelpers.js.map +1 -0
  19. package/dist/animation/colorRegistry.js +37 -0
  20. package/dist/animation/colorRegistry.js.map +1 -0
  21. package/dist/animation/index.js +20 -0
  22. package/dist/animation/loop.js +62 -0
  23. package/dist/animation/loop.js.map +1 -0
  24. package/dist/animation/observe.js +23 -0
  25. package/dist/animation/observe.js.map +1 -0
  26. package/dist/animation/poseHelpers.js +50 -0
  27. package/dist/animation/poseHelpers.js.map +1 -0
  28. package/dist/animation/reflow.js +121 -0
  29. package/dist/animation/reflow.js.map +1 -0
  30. package/dist/animation/rig/bindRig.js +74 -0
  31. package/dist/animation/rig/bindRig.js.map +1 -0
  32. package/dist/animation/rig/blendPoses.js +43 -0
  33. package/dist/animation/rig/blendPoses.js.map +1 -0
  34. package/dist/animation/rig/mirrorPose.js +19 -0
  35. package/dist/animation/rig/mirrorPose.js.map +1 -0
  36. package/dist/animation/rig/resolveSkeleton.js +33 -0
  37. package/dist/animation/rig/resolveSkeleton.js.map +1 -0
  38. package/dist/animation/rig/solveIk.js +103 -0
  39. package/dist/animation/rig/solveIk.js.map +1 -0
  40. package/dist/animation/rig/types.js +12 -0
  41. package/dist/animation/rig/types.js.map +1 -0
  42. package/dist/animation/rig/useRig.js +23 -0
  43. package/dist/animation/rig/useRig.js.map +1 -0
  44. package/dist/animation/slew.js +27 -0
  45. package/dist/animation/slew.js.map +1 -0
  46. package/dist/animation/stagger.js +138 -0
  47. package/dist/animation/stagger.js.map +1 -0
  48. package/dist/animation/timeline/booking.js +106 -0
  49. package/dist/animation/timeline/booking.js.map +1 -0
  50. package/dist/animation/timeline/createTimeline.js +116 -0
  51. package/dist/animation/timeline/createTimeline.js.map +1 -0
  52. package/dist/animation/timeline/sampleTrack.js +29 -0
  53. package/dist/animation/timeline/sampleTrack.js.map +1 -0
  54. package/dist/animation/useAnimator.js +329 -0
  55. package/dist/animation/useAnimator.js.map +1 -0
  56. package/dist/animation/wrappers/animateLifecycle.js +40 -0
  57. package/dist/animation/wrappers/animateLifecycle.js.map +1 -0
  58. package/dist/animation/wrappers/animateOnSetPose.js +44 -0
  59. package/dist/animation/wrappers/animateOnSetPose.js.map +1 -0
  60. package/dist/{autoPoseDescriptor-_XOyF7t4.d.ts → autoPoseDescriptor-BT_vp9FO.d.ts} +2 -2
  61. package/dist/{builtins-HWyuLzE-.d.ts → builtins-BSUfH8nU.d.ts} +1301 -508
  62. package/dist/canvas/Canvas.js +608 -0
  63. package/dist/canvas/Canvas.js.map +1 -0
  64. package/dist/canvas/CanvasView.js +255 -0
  65. package/dist/canvas/CanvasView.js.map +1 -0
  66. package/dist/canvas/CursorCoordsHud.js +75 -0
  67. package/dist/canvas/CursorCoordsHud.js.map +1 -0
  68. package/dist/canvas/DrawCanvas.js +67 -0
  69. package/dist/canvas/DrawCanvas.js.map +1 -0
  70. package/dist/canvas/MinimapCanvas.js +139 -0
  71. package/dist/canvas/MinimapCanvas.js.map +1 -0
  72. package/dist/canvas/ModalityHud.js +66 -0
  73. package/dist/canvas/ModalityHud.js.map +1 -0
  74. package/dist/canvas/NodeShape.js +391 -0
  75. package/dist/canvas/NodeShape.js.map +1 -0
  76. package/dist/canvas/PickHud.js +93 -0
  77. package/dist/canvas/PickHud.js.map +1 -0
  78. package/dist/canvas/SceneCanvas/ActionsProviderIfRoot.js +10 -0
  79. package/dist/canvas/SceneCanvas/ActionsProviderIfRoot.js.map +1 -0
  80. package/dist/canvas/SceneCanvas/DepRegistryProviderIfRoot.js +10 -0
  81. package/dist/canvas/SceneCanvas/DepRegistryProviderIfRoot.js.map +1 -0
  82. package/dist/canvas/SceneCanvas/PointerProviderIfRoot.js +51 -0
  83. package/dist/canvas/SceneCanvas/PointerProviderIfRoot.js.map +1 -0
  84. package/dist/canvas/SceneCanvas/contributionFrameHooks.js +42 -0
  85. package/dist/canvas/SceneCanvas/contributionFrameHooks.js.map +1 -0
  86. package/dist/canvas/SceneCanvas/defaultNodeProperties.js +549 -0
  87. package/dist/canvas/SceneCanvas/defaultNodeProperties.js.map +1 -0
  88. package/dist/canvas/SceneCanvas/defaultNodeRouting.js +26 -0
  89. package/dist/canvas/SceneCanvas/defaultNodeRouting.js.map +1 -0
  90. package/dist/canvas/SceneCanvas/dispatcherGestureBounds.js +69 -0
  91. package/dist/canvas/SceneCanvas/dispatcherGestureBounds.js.map +1 -0
  92. package/dist/canvas/SceneCanvas/features.js +97 -0
  93. package/dist/canvas/SceneCanvas/features.js.map +1 -0
  94. package/dist/canvas/SceneCanvas/poseGeometry.js +46 -0
  95. package/dist/canvas/SceneCanvas/poseGeometry.js.map +1 -0
  96. package/dist/canvas/SceneCanvas/useActionsPropResolver.js +48 -0
  97. package/dist/canvas/SceneCanvas/useActionsPropResolver.js.map +1 -0
  98. package/dist/canvas/SceneCanvas/useBuiltinShapeTools.js +70 -0
  99. package/dist/canvas/SceneCanvas/useBuiltinShapeTools.js.map +1 -0
  100. package/dist/canvas/SceneCanvas/useContributionRoles.js +75 -0
  101. package/dist/canvas/SceneCanvas/useContributionRoles.js.map +1 -0
  102. package/dist/canvas/SceneCanvas/useDispatcherOverlayLayer.js +172 -0
  103. package/dist/canvas/SceneCanvas/useDispatcherOverlayLayer.js.map +1 -0
  104. package/dist/canvas/SceneCanvas/usePreviewGhostLayer.js +69 -0
  105. package/dist/canvas/SceneCanvas/usePreviewGhostLayer.js.map +1 -0
  106. package/dist/canvas/SceneCanvas/useSceneSelectTool.js +127 -0
  107. package/dist/canvas/SceneCanvas/useSceneSelectTool.js.map +1 -0
  108. package/dist/canvas/SceneCanvas/useViewportActions.js +30 -0
  109. package/dist/canvas/SceneCanvas/useViewportActions.js.map +1 -0
  110. package/dist/canvas/SceneCanvas.js +992 -0
  111. package/dist/canvas/SceneCanvas.js.map +1 -0
  112. package/dist/canvas/SceneViewCanvas.js +54 -0
  113. package/dist/canvas/SceneViewCanvas.js.map +1 -0
  114. package/dist/canvas/accentColor.js +9 -0
  115. package/dist/canvas/accentColor.js.map +1 -0
  116. package/dist/canvas/affordanceAt.js +63 -0
  117. package/dist/canvas/affordanceAt.js.map +1 -0
  118. package/dist/canvas/buildSceneTree.js +65 -0
  119. package/dist/canvas/buildSceneTree.js.map +1 -0
  120. package/dist/canvas/canvasRenderer.js +89 -0
  121. package/dist/canvas/canvasRenderer.js.map +1 -0
  122. package/dist/canvas/colorOverrides.js +16 -0
  123. package/dist/canvas/colorOverrides.js.map +1 -0
  124. package/dist/canvas/defaultDrawOne.js +43 -0
  125. package/dist/canvas/defaultDrawOne.js.map +1 -0
  126. package/dist/canvas/deps/areaSelect.js +19 -0
  127. package/dist/canvas/deps/areaSelect.js.map +1 -0
  128. package/dist/canvas/deps/debug.js +9 -0
  129. package/dist/canvas/deps/debug.js.map +1 -0
  130. package/dist/canvas/deps/dispatcher.js +11 -0
  131. package/dist/canvas/deps/dispatcher.js.map +1 -0
  132. package/dist/canvas/deps/editAnchors.js +101 -0
  133. package/dist/canvas/deps/editAnchors.js.map +1 -0
  134. package/dist/canvas/deps/geometryProjection.js +11 -0
  135. package/dist/canvas/deps/geometryProjection.js.map +1 -0
  136. package/dist/canvas/deps/hitTestArea.js +51 -0
  137. package/dist/canvas/deps/hitTestArea.js.map +1 -0
  138. package/dist/canvas/deps/ingestion.js +31 -0
  139. package/dist/canvas/deps/ingestion.js.map +1 -0
  140. package/dist/canvas/deps/insert.js +116 -0
  141. package/dist/canvas/deps/insert.js.map +1 -0
  142. package/dist/canvas/deps/lassoSelect.js +20 -0
  143. package/dist/canvas/deps/lassoSelect.js.map +1 -0
  144. package/dist/canvas/deps/layout.js +34 -0
  145. package/dist/canvas/deps/layout.js.map +1 -0
  146. package/dist/canvas/deps/nodeAtPoint.js +19 -0
  147. package/dist/canvas/deps/nodeAtPoint.js.map +1 -0
  148. package/dist/canvas/deps/poseComposition.js +11 -0
  149. package/dist/canvas/deps/poseComposition.js.map +1 -0
  150. package/dist/canvas/deps/poseDescriptor.js +12 -0
  151. package/dist/canvas/deps/poseDescriptor.js.map +1 -0
  152. package/dist/canvas/deps/resizePolicy.js +35 -0
  153. package/dist/canvas/deps/resizePolicy.js.map +1 -0
  154. package/dist/canvas/deps/slice.js +99 -0
  155. package/dist/canvas/deps/slice.js.map +1 -0
  156. package/dist/canvas/deps/snap.js +11 -0
  157. package/dist/canvas/deps/snap.js.map +1 -0
  158. package/dist/canvas/deps/textEdit.js +21 -0
  159. package/dist/canvas/deps/textEdit.js.map +1 -0
  160. package/dist/canvas/deps/view.js +43 -0
  161. package/dist/canvas/deps/view.js.map +1 -0
  162. package/dist/canvas/derivedPath.js +47 -0
  163. package/dist/canvas/derivedPath.js.map +1 -0
  164. package/dist/canvas/drawEnvelope.js +22 -0
  165. package/dist/canvas/drawEnvelope.js.map +1 -0
  166. package/dist/canvas/getNodeAtPoint.js +18 -0
  167. package/dist/canvas/getNodeAtPoint.js.map +1 -0
  168. package/dist/canvas/hostAnchor.js +29 -0
  169. package/dist/canvas/hostAnchor.js.map +1 -0
  170. package/dist/canvas/hud.module.js +18 -0
  171. package/dist/canvas/hud.module.js.map +1 -0
  172. package/dist/canvas/insertPreviewExtent.js +103 -0
  173. package/dist/canvas/insertPreviewExtent.js.map +1 -0
  174. package/dist/canvas/kitRequirements.js +177 -0
  175. package/dist/canvas/kitRequirements.js.map +1 -0
  176. package/dist/canvas/layerOrder.js +66 -0
  177. package/dist/canvas/layerOrder.js.map +1 -0
  178. package/dist/canvas/layerSlots.js +14 -0
  179. package/dist/canvas/layerSlots.js.map +1 -0
  180. package/dist/canvas/minimapMath.js +80 -0
  181. package/dist/canvas/minimapMath.js.map +1 -0
  182. package/dist/canvas/mountedCanvases.js +20 -0
  183. package/dist/canvas/mountedCanvases.js.map +1 -0
  184. package/dist/canvas/overlayRoleStrokes.js +17 -0
  185. package/dist/canvas/overlayRoleStrokes.js.map +1 -0
  186. package/dist/canvas/paintCull.js +20 -0
  187. package/dist/canvas/paintCull.js.map +1 -0
  188. package/dist/canvas/pickWalk.js +158 -0
  189. package/dist/canvas/pickWalk.js.map +1 -0
  190. package/dist/canvas/planeClips.js +30 -0
  191. package/dist/canvas/planeClips.js.map +1 -0
  192. package/dist/canvas/poseRotation.js +35 -0
  193. package/dist/canvas/poseRotation.js.map +1 -0
  194. package/dist/canvas/rasterToPng.js +21 -0
  195. package/dist/canvas/rasterToPng.js.map +1 -0
  196. package/dist/canvas/renderDebugSnapshot.js +32 -0
  197. package/dist/canvas/renderDebugSnapshot.js.map +1 -0
  198. package/dist/canvas/renderNeeds.js +25 -0
  199. package/dist/canvas/renderNeeds.js.map +1 -0
  200. package/dist/canvas/renderSceneToPixels.js +143 -0
  201. package/dist/canvas/renderSceneToPixels.js.map +1 -0
  202. package/dist/canvas/sceneAdapter.js +270 -0
  203. package/dist/canvas/sceneAdapter.js.map +1 -0
  204. package/dist/canvas/sceneLayerPaint.js +37 -0
  205. package/dist/canvas/sceneLayerPaint.js.map +1 -0
  206. package/dist/canvas/sceneSlotWiring.js +20 -0
  207. package/dist/canvas/sceneSlotWiring.js.map +1 -0
  208. package/dist/canvas/sceneViewRender.js +72 -0
  209. package/dist/canvas/sceneViewRender.js.map +1 -0
  210. package/dist/canvas/slopsDebugLayer.js +61 -0
  211. package/dist/canvas/slopsDebugLayer.js.map +1 -0
  212. package/dist/canvas/surfaceContribution.js +15 -0
  213. package/dist/canvas/surfaceContribution.js.map +1 -0
  214. package/dist/canvas/toolPreview.js +39 -0
  215. package/dist/canvas/toolPreview.js.map +1 -0
  216. package/dist/canvas/useCanvasRenderer.js +11 -0
  217. package/dist/canvas/useCanvasRenderer.js.map +1 -0
  218. package/dist/canvas/useFrameLoop.js +60 -0
  219. package/dist/canvas/useFrameLoop.js.map +1 -0
  220. package/dist/canvas/useHostAnchor.js +71 -0
  221. package/dist/canvas/useHostAnchor.js.map +1 -0
  222. package/dist/canvas/useLateContentRedraw.js +21 -0
  223. package/dist/canvas/useLateContentRedraw.js.map +1 -0
  224. package/dist/canvas/useRedrawOn.js +21 -0
  225. package/dist/canvas/useRedrawOn.js.map +1 -0
  226. package/dist/canvas/useViewHelpers.js +120 -0
  227. package/dist/canvas/useViewHelpers.js.map +1 -0
  228. package/dist/canvas/viewInputs.js +17 -0
  229. package/dist/canvas/viewInputs.js.map +1 -0
  230. package/dist/canvas/viewRegistry.js +61 -0
  231. package/dist/canvas/viewRegistry.js.map +1 -0
  232. package/dist/canvas/wrapNodeOutput.js +14 -0
  233. package/dist/canvas/wrapNodeOutput.js.map +1 -0
  234. package/dist/clipboard.d.ts +10 -5
  235. package/dist/clipboard.js +3 -5
  236. package/dist/clone.d.ts +3 -3
  237. package/dist/clone.js +2 -5
  238. package/dist/core/adapters/arrayAdapter.js +85 -0
  239. package/dist/core/adapters/arrayAdapter.js.map +1 -0
  240. package/dist/core/adapters/useArrayAdapter.js +13 -0
  241. package/dist/core/adapters/useArrayAdapter.js.map +1 -0
  242. package/dist/core/applyOps.js +12 -0
  243. package/dist/core/applyOps.js.map +1 -0
  244. package/dist/core/device/index.js +4 -0
  245. package/dist/core/device/targets.js +17 -0
  246. package/dist/core/device/targets.js.map +1 -0
  247. package/dist/core/device/useDeviceProfile.js +75 -0
  248. package/dist/core/device/useDeviceProfile.js.map +1 -0
  249. package/dist/core/fillInPoseFrame.js +102 -0
  250. package/dist/core/fillInPoseFrame.js.map +1 -0
  251. package/dist/core/geometry/poseDescriptor.js +98 -0
  252. package/dist/core/geometry/poseDescriptor.js.map +1 -0
  253. package/dist/core/geometry/poseRotation.js +58 -0
  254. package/dist/core/geometry/poseRotation.js.map +1 -0
  255. package/dist/core/geometry/regionHit.js +102 -0
  256. package/dist/core/geometry/regionHit.js.map +1 -0
  257. package/dist/core/geometry/unionBounds.js +60 -0
  258. package/dist/core/geometry/unionBounds.js.map +1 -0
  259. package/dist/core/gradient.js +136 -0
  260. package/dist/core/gradient.js.map +1 -0
  261. package/dist/core/isPlainObject.js +11 -0
  262. package/dist/core/isPlainObject.js.map +1 -0
  263. package/dist/core/layers/render.js +150 -0
  264. package/dist/core/layers/render.js.map +1 -0
  265. package/dist/core/markerInset.js +24 -0
  266. package/dist/core/markerInset.js.map +1 -0
  267. package/dist/core/mixed.js +6 -0
  268. package/dist/core/mixed.js.map +1 -0
  269. package/dist/core/ops/arrange.js +31 -0
  270. package/dist/core/ops/arrange.js.map +1 -0
  271. package/dist/core/ops/create.js +32 -0
  272. package/dist/core/ops/create.js.map +1 -0
  273. package/dist/core/ops/createHistory.js +20 -0
  274. package/dist/core/ops/createHistory.js.map +1 -0
  275. package/dist/core/ops/delete.js +89 -0
  276. package/dist/core/ops/delete.js.map +1 -0
  277. package/dist/core/ops/registry.js +17 -0
  278. package/dist/core/ops/registry.js.map +1 -0
  279. package/dist/core/ops/reorder/algorithms.js +55 -0
  280. package/dist/core/ops/reorder/algorithms.js.map +1 -0
  281. package/dist/core/ops/reorder/index.js +140 -0
  282. package/dist/core/ops/reorder/index.js.map +1 -0
  283. package/dist/core/ops/reparent.js +52 -0
  284. package/dist/core/ops/reparent.js.map +1 -0
  285. package/dist/core/ops/select.js +34 -0
  286. package/dist/core/ops/select.js.map +1 -0
  287. package/dist/core/ops/setData.js +34 -0
  288. package/dist/core/ops/setData.js.map +1 -0
  289. package/dist/core/ops/setLayer.js +34 -0
  290. package/dist/core/ops/setLayer.js.map +1 -0
  291. package/dist/core/ops/setLayout.js +31 -0
  292. package/dist/core/ops/setLayout.js.map +1 -0
  293. package/dist/core/ops/setPath.js +57 -0
  294. package/dist/core/ops/setPath.js.map +1 -0
  295. package/dist/core/ops/setText.js +34 -0
  296. package/dist/core/ops/setText.js.map +1 -0
  297. package/dist/core/ops/slot.js +37 -0
  298. package/dist/core/ops/slot.js.map +1 -0
  299. package/dist/core/ops/transform.js +42 -0
  300. package/dist/core/ops/transform.js.map +1 -0
  301. package/dist/core/paintKinds.js +156 -0
  302. package/dist/core/paintKinds.js.map +1 -0
  303. package/dist/core/scene/NodeProperties.js +20 -0
  304. package/dist/core/scene/NodeProperties.js.map +1 -0
  305. package/dist/core/scene/NodeRouting.js +24 -0
  306. package/dist/core/scene/NodeRouting.js.map +1 -0
  307. package/dist/core/scene/arrivals.js +12 -0
  308. package/dist/core/scene/arrivals.js.map +1 -0
  309. package/dist/core/scene/composeFrame.js +29 -0
  310. package/dist/core/scene/composeFrame.js.map +1 -0
  311. package/dist/core/scene/depMemo.js +18 -0
  312. package/dist/core/scene/depMemo.js.map +1 -0
  313. package/dist/core/scene/dependents.js +66 -0
  314. package/dist/core/scene/dependents.js.map +1 -0
  315. package/dist/core/scene/derivedPath.js +31 -0
  316. package/dist/core/scene/derivedPath.js.map +1 -0
  317. package/dist/core/scene/effectivePose.js +78 -0
  318. package/dist/core/scene/effectivePose.js.map +1 -0
  319. package/dist/core/scene/kitRegistry.js +33 -0
  320. package/dist/core/scene/kitRegistry.js.map +1 -0
  321. package/dist/core/scene/layoutPass.js +96 -0
  322. package/dist/core/scene/layoutPass.js.map +1 -0
  323. package/dist/core/scene/nodeFnFields.js +83 -0
  324. package/dist/core/scene/nodeFnFields.js.map +1 -0
  325. package/dist/core/scene/nodeMemo.js +28 -0
  326. package/dist/core/scene/nodeMemo.js.map +1 -0
  327. package/dist/core/scene/poseFeed.js +87 -0
  328. package/dist/core/scene/poseFeed.js.map +1 -0
  329. package/dist/core/scene/poseOverrides.js +52 -0
  330. package/dist/core/scene/poseOverrides.js.map +1 -0
  331. package/dist/core/scene/poseSnapshot.js +54 -0
  332. package/dist/core/scene/poseSnapshot.js.map +1 -0
  333. package/dist/core/scene/scene.js +1271 -0
  334. package/dist/core/scene/scene.js.map +1 -0
  335. package/dist/core/scene/types.js +6 -0
  336. package/dist/core/scene/types.js.map +1 -0
  337. package/dist/core/scene/useScene.js +32 -0
  338. package/dist/core/scene/useScene.js.map +1 -0
  339. package/dist/core/selection/chromeState.js +31 -0
  340. package/dist/core/selection/chromeState.js.map +1 -0
  341. package/dist/core/selection/selectionTarget.js +6 -0
  342. package/dist/core/selection/selectionTarget.js.map +1 -0
  343. package/dist/core/selection/useSelection.js +71 -0
  344. package/dist/core/selection/useSelection.js.map +1 -0
  345. package/dist/core/shapeKinds.js +54 -0
  346. package/dist/core/shapeKinds.js.map +1 -0
  347. package/dist/core/strokeMarkerShapes.js +139 -0
  348. package/dist/core/strokeMarkerShapes.js.map +1 -0
  349. package/dist/core/strokeMarkers.js +28 -0
  350. package/dist/core/strokeMarkers.js.map +1 -0
  351. package/dist/core/stylus/stylus.js +39 -0
  352. package/dist/core/stylus/stylus.js.map +1 -0
  353. package/dist/core/stylus/usePointerStylus.js +51 -0
  354. package/dist/core/stylus/usePointerStylus.js.map +1 -0
  355. package/dist/core/usePaintKinds.js +17 -0
  356. package/dist/core/usePaintKinds.js.map +1 -0
  357. package/dist/core/viewport/clampView.js +24 -0
  358. package/dist/core/viewport/clampView.js.map +1 -0
  359. package/dist/core/viewport/clientToWorld.js +8 -0
  360. package/dist/core/viewport/clientToWorld.js.map +1 -0
  361. package/dist/core/viewport/createVelocityTracker.js +39 -0
  362. package/dist/core/viewport/createVelocityTracker.js.map +1 -0
  363. package/dist/core/viewport/fitToBounds.js +18 -0
  364. package/dist/core/viewport/fitToBounds.js.map +1 -0
  365. package/dist/core/viewport/fitViewToBounds.js +36 -0
  366. package/dist/core/viewport/fitViewToBounds.js.map +1 -0
  367. package/dist/core/viewport/interpolateView.js +34 -0
  368. package/dist/core/viewport/interpolateView.js.map +1 -0
  369. package/dist/core/viewport/meanScale.js +8 -0
  370. package/dist/core/viewport/meanScale.js.map +1 -0
  371. package/dist/core/viewport/parallax.js +111 -0
  372. package/dist/core/viewport/parallax.js.map +1 -0
  373. package/dist/core/viewport/pxExtent.js +42 -0
  374. package/dist/core/viewport/pxExtent.js.map +1 -0
  375. package/dist/core/viewport/sceneNodeClientRect.js +18 -0
  376. package/dist/core/viewport/sceneNodeClientRect.js.map +1 -0
  377. package/dist/core/viewport/screenSlop.js +27 -0
  378. package/dist/core/viewport/screenSlop.js.map +1 -0
  379. package/dist/core/viewport/useAutoCenter.js +32 -0
  380. package/dist/core/viewport/useAutoCenter.js.map +1 -0
  381. package/dist/core/viewport/useCanvasSize.js +29 -0
  382. package/dist/core/viewport/useCanvasSize.js.map +1 -0
  383. package/dist/core/viewport/useDecayLoop.js +63 -0
  384. package/dist/core/viewport/useDecayLoop.js.map +1 -0
  385. package/dist/core/viewport/useVelocityTracker.js +10 -0
  386. package/dist/core/viewport/useVelocityTracker.js.map +1 -0
  387. package/dist/core/viewport/useViewAnimation.js +63 -0
  388. package/dist/core/viewport/useViewAnimation.js.map +1 -0
  389. package/dist/core/viewport/view.js +37 -0
  390. package/dist/core/viewport/view.js.map +1 -0
  391. package/dist/core/viewport/viewTransform.js +11 -0
  392. package/dist/core/viewport/viewTransform.js.map +1 -0
  393. package/dist/core/viewport/viewportWorldRect.js +13 -0
  394. package/dist/core/viewport/viewportWorldRect.js.map +1 -0
  395. package/dist/core/viewport/wheelHandler.js +30 -0
  396. package/dist/core/viewport/wheelHandler.js.map +1 -0
  397. package/dist/core/viewport/zoomAt.js +22 -0
  398. package/dist/core/viewport/zoomAt.js.map +1 -0
  399. package/dist/core/viewport/zoomBounds.js +20 -0
  400. package/dist/core/viewport/zoomBounds.js.map +1 -0
  401. package/dist/{pointSnapToGrid-7mCcm6qG.d.ts → cornerHandles-CDcZOV8h.d.ts} +54 -71
  402. package/dist/debug/createDebugOverlayLayer.js +358 -0
  403. package/dist/debug/createDebugOverlayLayer.js.map +1 -0
  404. package/dist/debug/createDebugSink.js +83 -0
  405. package/dist/debug/createDebugSink.js.map +1 -0
  406. package/dist/debug/defaultTheme.js +31 -0
  407. package/dist/debug/defaultTheme.js.map +1 -0
  408. package/dist/debug/flag.js +41 -0
  409. package/dist/debug/flag.js.map +1 -0
  410. package/dist/debug/frameStats.js +16 -0
  411. package/dist/debug/frameStats.js.map +1 -0
  412. package/dist/debug/parseDebugFlags.js +32 -0
  413. package/dist/debug/parseDebugFlags.js.map +1 -0
  414. package/dist/features/chrome-caps/buildChromeCtx.js +16 -0
  415. package/dist/features/chrome-caps/buildChromeCtx.js.map +1 -0
  416. package/dist/features/chrome-caps/conditions.js +36 -0
  417. package/dist/features/chrome-caps/conditions.js.map +1 -0
  418. package/dist/features/chrome-caps/defaults.js +26 -0
  419. package/dist/features/chrome-caps/defaults.js.map +1 -0
  420. package/dist/features/chrome-caps/index.js +7 -0
  421. package/dist/features/chrome-caps/resolve.js +23 -0
  422. package/dist/features/chrome-caps/resolve.js.map +1 -0
  423. package/dist/features/chrome-caps/useHoverTracking.js +27 -0
  424. package/dist/features/chrome-caps/useHoverTracking.js.map +1 -0
  425. package/dist/features/cursor/paintedCursorLayer.js +60 -0
  426. package/dist/features/cursor/paintedCursorLayer.js.map +1 -0
  427. package/dist/features/focus/gateLayer.js +14 -0
  428. package/dist/features/focus/gateLayer.js.map +1 -0
  429. package/dist/features/focus/useCanvasFocus.js +29 -0
  430. package/dist/features/focus/useCanvasFocus.js.map +1 -0
  431. package/dist/features/groups/children.js +23 -0
  432. package/dist/features/groups/children.js.map +1 -0
  433. package/dist/features/groups/composePose.js +67 -0
  434. package/dist/features/groups/composePose.js.map +1 -0
  435. package/dist/features/groups/nestedHit.js +40 -0
  436. package/dist/features/groups/nestedHit.js.map +1 -0
  437. package/dist/features/groups/unionOfChildren.js +15 -0
  438. package/dist/features/groups/unionOfChildren.js.map +1 -0
  439. package/dist/features/images/imageCache.js +94 -0
  440. package/dist/features/images/imageCache.js.map +1 -0
  441. package/dist/features/ingestion/contentHandlers.js +37 -0
  442. package/dist/features/ingestion/contentHandlers.js.map +1 -0
  443. package/dist/features/ingestion/imageHandler.js +45 -0
  444. package/dist/features/ingestion/imageHandler.js.map +1 -0
  445. package/dist/features/ingestion/index.js +8 -0
  446. package/dist/features/ingestion/openFilePicker.js +15 -0
  447. package/dist/features/ingestion/openFilePicker.js.map +1 -0
  448. package/dist/features/ingestion/registerKitHandlers.js +26 -0
  449. package/dist/features/ingestion/registerKitHandlers.js.map +1 -0
  450. package/dist/features/ingestion/svgHandler.js +58 -0
  451. package/dist/features/ingestion/svgHandler.js.map +1 -0
  452. package/dist/features/ingestion/weaselJsonHandler.js +39 -0
  453. package/dist/features/ingestion/weaselJsonHandler.js.map +1 -0
  454. package/dist/features/longPress/longPressFeedback.js +96 -0
  455. package/dist/features/longPress/longPressFeedback.js.map +1 -0
  456. package/dist/features/meshPaint/bake.js +79 -0
  457. package/dist/features/meshPaint/bake.js.map +1 -0
  458. package/dist/features/meshPaint/bakeCache.js +59 -0
  459. package/dist/features/meshPaint/bakeCache.js.map +1 -0
  460. package/dist/features/meshPaint/handles.js +86 -0
  461. package/dist/features/meshPaint/handles.js.map +1 -0
  462. package/dist/features/meshPaint/lazyKind.js +1298 -0
  463. package/dist/features/meshPaint/lazyKind.js.map +1 -0
  464. package/dist/features/meshPaint/meshPaint.js +236 -0
  465. package/dist/features/meshPaint/meshPaint.js.map +1 -0
  466. package/dist/features/meshPaint/meshShader.js +6 -0
  467. package/dist/features/meshPaint/meshShader.js.map +1 -0
  468. package/dist/features/meshPaint/register.js +7 -0
  469. package/dist/features/meshPaint/register.js.map +1 -0
  470. package/dist/features/meshPaint/surface.js +110 -0
  471. package/dist/features/meshPaint/surface.js.map +1 -0
  472. package/dist/features/minimap/actions.js +53 -0
  473. package/dist/features/minimap/actions.js.map +1 -0
  474. package/dist/features/minimap/createMinimapContribution.js +96 -0
  475. package/dist/features/minimap/createMinimapContribution.js.map +1 -0
  476. package/dist/features/minimap/layers.js +103 -0
  477. package/dist/features/minimap/layers.js.map +1 -0
  478. package/dist/features/modes/modeLayers.js +113 -0
  479. package/dist/features/modes/modeLayers.js.map +1 -0
  480. package/dist/features/overlays/useNodeOverlayFrame.js +103 -0
  481. package/dist/features/overlays/useNodeOverlayFrame.js.map +1 -0
  482. package/dist/features/parallax/createParallaxLayer.js +26 -0
  483. package/dist/features/parallax/createParallaxLayer.js.map +1 -0
  484. package/dist/features/parallax/createParallaxPlane.js +26 -0
  485. package/dist/features/parallax/createParallaxPlane.js.map +1 -0
  486. package/dist/features/paths/anchorEdits.js +156 -0
  487. package/dist/features/paths/anchorEdits.js.map +1 -0
  488. package/dist/features/paths/anchors.js +154 -0
  489. package/dist/features/paths/anchors.js.map +1 -0
  490. package/dist/features/paths/booleans.js +2 -0
  491. package/dist/features/paths/index.js +15 -0
  492. package/dist/features/paths/markerCommands.js +116 -0
  493. package/dist/features/paths/markerCommands.js.map +1 -0
  494. package/dist/features/paths/markerSites.js +59 -0
  495. package/dist/features/paths/markerSites.js.map +1 -0
  496. package/dist/features/paths/markers.js +95 -0
  497. package/dist/features/paths/markers.js.map +1 -0
  498. package/dist/features/paths/nearestAnchor.js +36 -0
  499. package/dist/features/paths/nearestAnchor.js.map +1 -0
  500. package/dist/features/paths/originProjection.js +16 -0
  501. package/dist/features/paths/originProjection.js.map +1 -0
  502. package/dist/features/paths/pathEditingOverlayLayer.js +137 -0
  503. package/dist/features/paths/pathEditingOverlayLayer.js.map +1 -0
  504. package/dist/features/paths/pathInWorld.js +41 -0
  505. package/dist/features/paths/pathInWorld.js.map +1 -0
  506. package/dist/features/paths/pathLayer.js +44 -0
  507. package/dist/features/paths/pathLayer.js.map +1 -0
  508. package/dist/features/paths/penPreviewLayer.js +220 -0
  509. package/dist/features/paths/penPreviewLayer.js.map +1 -0
  510. package/dist/features/paths/poseDescriptor.js +44 -0
  511. package/dist/features/paths/poseDescriptor.js.map +1 -0
  512. package/dist/features/paths/tessellate/stroke.js +230 -0
  513. package/dist/features/paths/tessellate/stroke.js.map +1 -0
  514. package/dist/features/patterns/index.js +23 -0
  515. package/dist/features/patterns/index.js.map +1 -0
  516. package/dist/features/patterns/patterns-builtin.js +38 -0
  517. package/dist/features/patterns/patterns-builtin.js.map +1 -0
  518. package/dist/features/patterns/resolveSpec.js +57 -0
  519. package/dist/features/patterns/resolveSpec.js.map +1 -0
  520. package/dist/features/patterns/tileGeometry.js +158 -0
  521. package/dist/features/patterns/tileGeometry.js.map +1 -0
  522. package/dist/features/pointer/PointerContext.js +45 -0
  523. package/dist/features/pointer/PointerContext.js.map +1 -0
  524. package/dist/features/poseRun/usePoseRun.js +70 -0
  525. package/dist/features/poseRun/usePoseRun.js.map +1 -0
  526. package/dist/features/selection/SelectionContext.js +46 -0
  527. package/dist/features/selection/SelectionContext.js.map +1 -0
  528. package/dist/features/selection/overlay.js +442 -0
  529. package/dist/features/selection/overlay.js.map +1 -0
  530. package/dist/features/simulation/createSimulation.js +61 -0
  531. package/dist/features/simulation/createSimulation.js.map +1 -0
  532. package/dist/features/simulation/types.js +6 -0
  533. package/dist/features/simulation/types.js.map +1 -0
  534. package/dist/features/simulation/useSimulation.js +74 -0
  535. package/dist/features/simulation/useSimulation.js.map +1 -0
  536. package/dist/features/text/domRuns.js +258 -0
  537. package/dist/features/text/domRuns.js.map +1 -0
  538. package/dist/features/text/fitTextPose.js +38 -0
  539. package/dist/features/text/fitTextPose.js.map +1 -0
  540. package/dist/features/text/hitTest.js +45 -0
  541. package/dist/features/text/hitTest.js.map +1 -0
  542. package/dist/features/text/renderLabel.js +14 -0
  543. package/dist/features/text/renderLabel.js.map +1 -0
  544. package/dist/features/text/runs/effectiveRangeStyle.js +66 -0
  545. package/dist/features/text/runs/effectiveRangeStyle.js.map +1 -0
  546. package/dist/features/text/runs/flagRange.js +53 -0
  547. package/dist/features/text/runs/flagRange.js.map +1 -0
  548. package/dist/features/text/runs/rangeStyle.js +135 -0
  549. package/dist/features/text/runs/rangeStyle.js.map +1 -0
  550. package/dist/features/text/textCommand.js +59 -0
  551. package/dist/features/text/textCommand.js.map +1 -0
  552. package/dist/features/text/textLayer.js +35 -0
  553. package/dist/features/text/textLayer.js.map +1 -0
  554. package/dist/features/text/textToPath.js +181 -0
  555. package/dist/features/text/textToPath.js.map +1 -0
  556. package/dist/features/text/useSceneTextEdit.js +138 -0
  557. package/dist/features/text/useSceneTextEdit.js.map +1 -0
  558. package/dist/features/text/useTextEdit.js +465 -0
  559. package/dist/features/text/useTextEdit.js.map +1 -0
  560. package/dist/features/tiling/createTiledLayer.js +63 -0
  561. package/dist/features/tiling/createTiledLayer.js.map +1 -0
  562. package/dist/features/tiling/tiledProject.js +14 -0
  563. package/dist/features/tiling/tiledProject.js.map +1 -0
  564. package/dist/features/viewports/viewResolver.js +59 -0
  565. package/dist/features/viewports/viewResolver.js.map +1 -0
  566. package/dist/features/viewports/viewportLayer.js +58 -0
  567. package/dist/features/viewports/viewportLayer.js.map +1 -0
  568. package/dist/icons/ArrowIcon.js +23 -0
  569. package/dist/icons/ArrowIcon.js.map +1 -0
  570. package/dist/icons/EllipseIcon.js +21 -0
  571. package/dist/icons/EllipseIcon.js.map +1 -0
  572. package/dist/icons/EyedropperIcon.js +49 -0
  573. package/dist/icons/EyedropperIcon.js.map +1 -0
  574. package/dist/icons/HandIcon.js +59 -0
  575. package/dist/icons/HandIcon.js.map +1 -0
  576. package/dist/icons/ImageIcon.js +34 -0
  577. package/dist/icons/ImageIcon.js.map +1 -0
  578. package/dist/icons/LassoIcon.js +22 -0
  579. package/dist/icons/LassoIcon.js.map +1 -0
  580. package/dist/icons/LineIcon.js +22 -0
  581. package/dist/icons/LineIcon.js.map +1 -0
  582. package/dist/icons/PenIcon.js +36 -0
  583. package/dist/icons/PenIcon.js.map +1 -0
  584. package/dist/icons/PencilIcon.js +25 -0
  585. package/dist/icons/PencilIcon.js.map +1 -0
  586. package/dist/icons/PolygonIcon.js +19 -0
  587. package/dist/icons/PolygonIcon.js.map +1 -0
  588. package/dist/icons/RectIcon.js +37 -0
  589. package/dist/icons/RectIcon.js.map +1 -0
  590. package/dist/icons/SelectIcon.js +20 -0
  591. package/dist/icons/SelectIcon.js.map +1 -0
  592. package/dist/icons/StarIcon.js +19 -0
  593. package/dist/icons/StarIcon.js.map +1 -0
  594. package/dist/icons/TextIcon.js +19 -0
  595. package/dist/icons/TextIcon.js.map +1 -0
  596. package/dist/icons/UnknownIcon.js +33 -0
  597. package/dist/icons/UnknownIcon.js.map +1 -0
  598. package/dist/icons/_base.js +12 -0
  599. package/dist/icons/_base.js.map +1 -0
  600. package/dist/index.css +2 -86
  601. package/dist/index.d.ts +2349 -2609
  602. package/dist/index.js +312 -13
  603. package/dist/input/keyState.js +76 -0
  604. package/dist/input/keyState.js.map +1 -0
  605. package/dist/input/useKeyState.js +22 -0
  606. package/dist/input/useKeyState.js.map +1 -0
  607. package/dist/interactions/actions/actionShortcuts.js +32 -0
  608. package/dist/interactions/actions/actionShortcuts.js.map +1 -0
  609. package/dist/interactions/actions/align/align.js +81 -0
  610. package/dist/interactions/actions/align/align.js.map +1 -0
  611. package/dist/interactions/actions/booleans/booleans.js +120 -0
  612. package/dist/interactions/actions/booleans/booleans.js.map +1 -0
  613. package/dist/interactions/actions/booleans/useBooleans.js +20 -0
  614. package/dist/interactions/actions/booleans/useBooleans.js.map +1 -0
  615. package/dist/interactions/actions/booleans/useBooleansAdapter.js +9 -0
  616. package/dist/interactions/actions/booleans/useBooleansAdapter.js.map +1 -0
  617. package/dist/interactions/actions/clipboard/clipboardOps.js +94 -0
  618. package/dist/interactions/actions/clipboard/clipboardOps.js.map +1 -0
  619. package/dist/interactions/actions/clipboard/materializePaste.js +25 -0
  620. package/dist/interactions/actions/clipboard/materializePaste.js.map +1 -0
  621. package/dist/interactions/actions/clipboard/wireFormat.js +43 -0
  622. package/dist/interactions/actions/clipboard/wireFormat.js.map +1 -0
  623. package/dist/interactions/actions/clone/behaviors/cloneByAltDrag.js +26 -0
  624. package/dist/interactions/actions/clone/behaviors/cloneByAltDrag.js.map +1 -0
  625. package/dist/interactions/actions/defaultCommitAdapter.js +42 -0
  626. package/dist/interactions/actions/defaultCommitAdapter.js.map +1 -0
  627. package/dist/interactions/actions/defaults/align.js +71 -0
  628. package/dist/interactions/actions/defaults/align.js.map +1 -0
  629. package/dist/interactions/actions/defaults/anchorEditing.js +235 -0
  630. package/dist/interactions/actions/defaults/anchorEditing.js.map +1 -0
  631. package/dist/interactions/actions/defaults/areaSelect.js +75 -0
  632. package/dist/interactions/actions/defaults/areaSelect.js.map +1 -0
  633. package/dist/interactions/actions/defaults/booleans.js +52 -0
  634. package/dist/interactions/actions/defaults/booleans.js.map +1 -0
  635. package/dist/interactions/actions/defaults/cancelGesture.js +24 -0
  636. package/dist/interactions/actions/defaults/cancelGesture.js.map +1 -0
  637. package/dist/interactions/actions/defaults/clearSelection.js +19 -0
  638. package/dist/interactions/actions/defaults/clearSelection.js.map +1 -0
  639. package/dist/interactions/actions/defaults/clipboard.js +78 -0
  640. package/dist/interactions/actions/defaults/clipboard.js.map +1 -0
  641. package/dist/interactions/actions/defaults/clone.js +96 -0
  642. package/dist/interactions/actions/defaults/clone.js.map +1 -0
  643. package/dist/interactions/actions/defaults/createOutlines.js +47 -0
  644. package/dist/interactions/actions/defaults/createOutlines.js.map +1 -0
  645. package/dist/interactions/actions/defaults/createPaintAction.js +85 -0
  646. package/dist/interactions/actions/defaults/createPaintAction.js.map +1 -0
  647. package/dist/interactions/actions/defaults/delete.js +61 -0
  648. package/dist/interactions/actions/defaults/delete.js.map +1 -0
  649. package/dist/interactions/actions/defaults/distribute.js +66 -0
  650. package/dist/interactions/actions/defaults/distribute.js.map +1 -0
  651. package/dist/interactions/actions/defaults/duplicate.js +83 -0
  652. package/dist/interactions/actions/defaults/duplicate.js.map +1 -0
  653. package/dist/interactions/actions/defaults/editAnchors.js +100 -0
  654. package/dist/interactions/actions/defaults/editAnchors.js.map +1 -0
  655. package/dist/interactions/actions/defaults/enterPathEdit.js +29 -0
  656. package/dist/interactions/actions/defaults/enterPathEdit.js.map +1 -0
  657. package/dist/interactions/actions/defaults/enterTextEdit.js +20 -0
  658. package/dist/interactions/actions/defaults/enterTextEdit.js.map +1 -0
  659. package/dist/interactions/actions/defaults/escape.js +26 -0
  660. package/dist/interactions/actions/defaults/escape.js.map +1 -0
  661. package/dist/interactions/actions/defaults/exitPathEdit.js +22 -0
  662. package/dist/interactions/actions/defaults/exitPathEdit.js.map +1 -0
  663. package/dist/interactions/actions/defaults/flip.js +119 -0
  664. package/dist/interactions/actions/defaults/flip.js.map +1 -0
  665. package/dist/interactions/actions/defaults/freshNodeId.js +10 -0
  666. package/dist/interactions/actions/defaults/freshNodeId.js.map +1 -0
  667. package/dist/interactions/actions/defaults/group.js +131 -0
  668. package/dist/interactions/actions/defaults/group.js.map +1 -0
  669. package/dist/interactions/actions/defaults/icons/actionGlyphIcons.js +40 -0
  670. package/dist/interactions/actions/defaults/icons/actionGlyphIcons.js.map +1 -0
  671. package/dist/interactions/actions/defaults/icons/actionGlyphs.js +10 -0
  672. package/dist/interactions/actions/defaults/icons/actionGlyphs.js.map +1 -0
  673. package/dist/interactions/actions/defaults/icons/alignIcons.js +173 -0
  674. package/dist/interactions/actions/defaults/icons/alignIcons.js.map +1 -0
  675. package/dist/interactions/actions/defaults/icons/booleanIcons.js +171 -0
  676. package/dist/interactions/actions/defaults/icons/booleanIcons.js.map +1 -0
  677. package/dist/interactions/actions/defaults/icons/distributeIcons.js +63 -0
  678. package/dist/interactions/actions/defaults/icons/distributeIcons.js.map +1 -0
  679. package/dist/interactions/actions/defaults/icons/editIcons.js +280 -0
  680. package/dist/interactions/actions/defaults/icons/editIcons.js.map +1 -0
  681. package/dist/interactions/actions/defaults/icons/outlineIcons.js +53 -0
  682. package/dist/interactions/actions/defaults/icons/outlineIcons.js.map +1 -0
  683. package/dist/interactions/actions/defaults/ingest.js +58 -0
  684. package/dist/interactions/actions/defaults/ingest.js.map +1 -0
  685. package/dist/interactions/actions/defaults/insert.js +288 -0
  686. package/dist/interactions/actions/defaults/insert.js.map +1 -0
  687. package/dist/interactions/actions/defaults/insertPathAnchor.js +50 -0
  688. package/dist/interactions/actions/defaults/insertPathAnchor.js.map +1 -0
  689. package/dist/interactions/actions/defaults/lassoSelect.js +156 -0
  690. package/dist/interactions/actions/defaults/lassoSelect.js.map +1 -0
  691. package/dist/interactions/actions/defaults/move.js +656 -0
  692. package/dist/interactions/actions/defaults/move.js.map +1 -0
  693. package/dist/interactions/actions/defaults/nudge.js +110 -0
  694. package/dist/interactions/actions/defaults/nudge.js.map +1 -0
  695. package/dist/interactions/actions/defaults/pinchZoom.js +63 -0
  696. package/dist/interactions/actions/defaults/pinchZoom.js.map +1 -0
  697. package/dist/interactions/actions/defaults/reorder.js +143 -0
  698. package/dist/interactions/actions/defaults/reorder.js.map +1 -0
  699. package/dist/interactions/actions/defaults/requiresSelection.js +10 -0
  700. package/dist/interactions/actions/defaults/requiresSelection.js.map +1 -0
  701. package/dist/interactions/actions/defaults/resize.js +332 -0
  702. package/dist/interactions/actions/defaults/resize.js.map +1 -0
  703. package/dist/interactions/actions/defaults/rotate.js +181 -0
  704. package/dist/interactions/actions/defaults/rotate.js.map +1 -0
  705. package/dist/interactions/actions/defaults/selectAll.js +27 -0
  706. package/dist/interactions/actions/defaults/selectAll.js.map +1 -0
  707. package/dist/interactions/actions/defaults/setFill.js +27 -0
  708. package/dist/interactions/actions/defaults/setFill.js.map +1 -0
  709. package/dist/interactions/actions/defaults/setFillOpacity.js +15 -0
  710. package/dist/interactions/actions/defaults/setFillOpacity.js.map +1 -0
  711. package/dist/interactions/actions/defaults/setStroke.js +36 -0
  712. package/dist/interactions/actions/defaults/setStroke.js.map +1 -0
  713. package/dist/interactions/actions/defaults/setStrokeOpacity.js +21 -0
  714. package/dist/interactions/actions/defaults/setStrokeOpacity.js.map +1 -0
  715. package/dist/interactions/actions/defaults/slice.js +39 -0
  716. package/dist/interactions/actions/defaults/slice.js.map +1 -0
  717. package/dist/interactions/actions/defaults/sliceOps.js +60 -0
  718. package/dist/interactions/actions/defaults/sliceOps.js.map +1 -0
  719. package/dist/interactions/actions/defaults/toolActivate.js +35 -0
  720. package/dist/interactions/actions/defaults/toolActivate.js.map +1 -0
  721. package/dist/interactions/actions/defaults/toolResetToDefault.js +26 -0
  722. package/dist/interactions/actions/defaults/toolResetToDefault.js.map +1 -0
  723. package/dist/interactions/actions/defaults/undoRedo.js +51 -0
  724. package/dist/interactions/actions/defaults/undoRedo.js.map +1 -0
  725. package/dist/interactions/actions/defaults/viewportDragPan.js +88 -0
  726. package/dist/interactions/actions/defaults/viewportDragPan.js.map +1 -0
  727. package/dist/interactions/actions/defaults/viewportWheelPan.js +57 -0
  728. package/dist/interactions/actions/defaults/viewportWheelPan.js.map +1 -0
  729. package/dist/interactions/actions/defaults/viewportZoom.js +143 -0
  730. package/dist/interactions/actions/defaults/viewportZoom.js.map +1 -0
  731. package/dist/interactions/actions/distribute/distribute.js +42 -0
  732. package/dist/interactions/actions/distribute/distribute.js.map +1 -0
  733. package/dist/interactions/actions/distribute/plan.js +29 -0
  734. package/dist/interactions/actions/distribute/plan.js.map +1 -0
  735. package/dist/interactions/actions/edit-anchors/geometry.js +61 -0
  736. package/dist/interactions/actions/edit-anchors/geometry.js.map +1 -0
  737. package/dist/interactions/actions/edit-anchors/handles.js +43 -0
  738. package/dist/interactions/actions/edit-anchors/handles.js.map +1 -0
  739. package/dist/interactions/actions/flip/helpers.js +35 -0
  740. package/dist/interactions/actions/flip/helpers.js.map +1 -0
  741. package/dist/interactions/actions/geometryProjection.js +18 -0
  742. package/dist/interactions/actions/geometryProjection.js.map +1 -0
  743. package/dist/interactions/actions/gestureLifecycle.js +44 -0
  744. package/dist/interactions/actions/gestureLifecycle.js.map +1 -0
  745. package/dist/interactions/actions/lasso-select/behaviors/selectFromLasso.js +39 -0
  746. package/dist/interactions/actions/lasso-select/behaviors/selectFromLasso.js.map +1 -0
  747. package/dist/interactions/actions/move/behaviors/snapBackOrDelete.js +36 -0
  748. package/dist/interactions/actions/move/behaviors/snapBackOrDelete.js.map +1 -0
  749. package/dist/interactions/actions/move/behaviors/snapToContainer.js +67 -0
  750. package/dist/interactions/actions/move/behaviors/snapToContainer.js.map +1 -0
  751. package/dist/interactions/actions/move/gestureAdapter.js +37 -0
  752. package/dist/interactions/actions/move/gestureAdapter.js.map +1 -0
  753. package/dist/interactions/actions/outlines/createOutlines.js +84 -0
  754. package/dist/interactions/actions/outlines/createOutlines.js.map +1 -0
  755. package/dist/interactions/actions/outlines/useCreateOutlinesAdapter.js +9 -0
  756. package/dist/interactions/actions/outlines/useCreateOutlinesAdapter.js.map +1 -0
  757. package/dist/interactions/actions/planeInput.js +168 -0
  758. package/dist/interactions/actions/planeInput.js.map +1 -0
  759. package/dist/interactions/actions/poseDescriptorDep.js +9 -0
  760. package/dist/interactions/actions/poseDescriptorDep.js.map +1 -0
  761. package/dist/interactions/actions/poseFrame.js +38 -0
  762. package/dist/interactions/actions/poseFrame.js.map +1 -0
  763. package/dist/interactions/actions/previewOverrides.js +25 -0
  764. package/dist/interactions/actions/previewOverrides.js.map +1 -0
  765. package/dist/interactions/actions/resize/autoPoseDescriptor.js +32 -0
  766. package/dist/interactions/actions/resize/autoPoseDescriptor.js.map +1 -0
  767. package/dist/interactions/actions/resize/behaviors/clampMinSize.js +18 -0
  768. package/dist/interactions/actions/resize/behaviors/clampMinSize.js.map +1 -0
  769. package/dist/interactions/actions/resize/behaviors/index.js +8 -0
  770. package/dist/interactions/actions/resize/behaviors/index.js.map +1 -0
  771. package/dist/interactions/actions/resize/behaviors/lockAspect.js +24 -0
  772. package/dist/interactions/actions/resize/behaviors/lockAspect.js.map +1 -0
  773. package/dist/interactions/actions/resize/cornerHandles.js +72 -0
  774. package/dist/interactions/actions/resize/cornerHandles.js.map +1 -0
  775. package/dist/interactions/actions/resolveOverlays.js +60 -0
  776. package/dist/interactions/actions/resolveOverlays.js.map +1 -0
  777. package/dist/interactions/actions/resolvePreviews.js +61 -0
  778. package/dist/interactions/actions/resolvePreviews.js.map +1 -0
  779. package/dist/interactions/actions/rotate/geometry.js +46 -0
  780. package/dist/interactions/actions/rotate/geometry.js.map +1 -0
  781. package/dist/interactions/actions/rotate/handle.js +27 -0
  782. package/dist/interactions/actions/rotate/handle.js.map +1 -0
  783. package/dist/interactions/actions/spatialReference.js +42 -0
  784. package/dist/interactions/actions/spatialReference.js.map +1 -0
  785. package/dist/interactions/actions/useStandardActions.js +142 -0
  786. package/dist/interactions/actions/useStandardActions.js.map +1 -0
  787. package/dist/interactions/gestures/dragGesture/dragGesture.js +111 -0
  788. package/dist/interactions/gestures/dragGesture/dragGesture.js.map +1 -0
  789. package/dist/interactions/gestures/dragRadial/dragRadial.js +117 -0
  790. package/dist/interactions/gestures/dragRadial/dragRadial.js.map +1 -0
  791. package/dist/interactions/gestures/dragRect/dragRect.js +164 -0
  792. package/dist/interactions/gestures/dragRect/dragRect.js.map +1 -0
  793. package/dist/interactions/gestures/handleDrag/handleDrag.js +46 -0
  794. package/dist/interactions/gestures/handleDrag/handleDrag.js.map +1 -0
  795. package/dist/interactions/gestures/pointerDrag/pointerDrag.js +118 -0
  796. package/dist/interactions/gestures/pointerDrag/pointerDrag.js.map +1 -0
  797. package/dist/interactions/gestures/shared/originProjection.js +42 -0
  798. package/dist/interactions/gestures/shared/originProjection.js.map +1 -0
  799. package/dist/interactions/gestures/shared/screenTolerance.js +21 -0
  800. package/dist/interactions/gestures/shared/screenTolerance.js.map +1 -0
  801. package/dist/interactions/gestures/shared/snap.js +24 -0
  802. package/dist/interactions/gestures/shared/snap.js.map +1 -0
  803. package/dist/interactions/gestures/thresholdDrag/thresholdDrag.js +30 -0
  804. package/dist/interactions/gestures/thresholdDrag/thresholdDrag.js.map +1 -0
  805. package/dist/layout/arrivals.js +36 -0
  806. package/dist/layout/arrivals.js.map +1 -0
  807. package/dist/{math-MCQcf_gc.d.ts → math-CUMxmZzn.d.ts} +8 -116
  808. package/dist/math.d.ts +4 -5
  809. package/dist/math.js +6 -4
  810. package/dist/mesh.d.ts +268 -0
  811. package/dist/mesh.js +7 -0
  812. package/dist/move.d.ts +7 -48
  813. package/dist/move.js +3 -142
  814. package/dist/originProjection-BSn4xiEy.d.ts +57 -0
  815. package/dist/patterns-builtin.js +3 -3
  816. package/dist/{poseDescriptor-rZa9W5hJ.d.ts → poseDescriptor-CjSXMf8X.d.ts} +3 -3
  817. package/dist/registerProgram-ateHDGjw.d.ts +193 -0
  818. package/dist/renderer/DrawCommand.js +6 -0
  819. package/dist/renderer/DrawCommand.js.map +1 -0
  820. package/dist/renderer/WeaselRenderer.js +328 -0
  821. package/dist/renderer/WeaselRenderer.js.map +1 -0
  822. package/dist/renderer/cache/GLImageCache.js +64 -0
  823. package/dist/renderer/cache/GLImageCache.js.map +1 -0
  824. package/dist/renderer/cache/GLMeshCache.js +102 -0
  825. package/dist/renderer/cache/GLMeshCache.js.map +1 -0
  826. package/dist/renderer/cache/GLTextureCache.js +51 -0
  827. package/dist/renderer/cache/GLTextureCache.js.map +1 -0
  828. package/dist/renderer/cache/GradientRampAtlas.js +82 -0
  829. package/dist/renderer/cache/GradientRampAtlas.js.map +1 -0
  830. package/dist/renderer/cache/cache.js +13 -0
  831. package/dist/renderer/cache/cache.js.map +1 -0
  832. package/dist/renderer/cache/markerCommandCache.js +59 -0
  833. package/dist/renderer/cache/markerCommandCache.js.map +1 -0
  834. package/dist/renderer/cache/outlineMeshCache.js +15 -0
  835. package/dist/renderer/cache/outlineMeshCache.js.map +1 -0
  836. package/dist/renderer/cache/outlineStrokeMeshCache.js +31 -0
  837. package/dist/renderer/cache/outlineStrokeMeshCache.js.map +1 -0
  838. package/dist/renderer/cache/strokeMeshCache.js +44 -0
  839. package/dist/renderer/cache/strokeMeshCache.js.map +1 -0
  840. package/dist/renderer/cullDrawCommands.js +89 -0
  841. package/dist/renderer/cullDrawCommands.js.map +1 -0
  842. package/dist/renderer/draw.js +1109 -0
  843. package/dist/renderer/draw.js.map +1 -0
  844. package/dist/renderer/drawBatch.js +168 -0
  845. package/dist/renderer/drawBatch.js.map +1 -0
  846. package/dist/renderer/effects/EffectTargets.js +45 -0
  847. package/dist/renderer/effects/EffectTargets.js.map +1 -0
  848. package/dist/renderer/effects/builtins.js +31 -0
  849. package/dist/renderer/effects/builtins.js.map +1 -0
  850. package/dist/renderer/effects/composite.js +9 -0
  851. package/dist/renderer/effects/composite.js.map +1 -0
  852. package/dist/renderer/effects/effectPrelude.js +10 -0
  853. package/dist/renderer/effects/effectPrelude.js.map +1 -0
  854. package/dist/renderer/effects/types.js +10 -0
  855. package/dist/renderer/effects/types.js.map +1 -0
  856. package/dist/renderer/index.js +19 -0
  857. package/dist/renderer/math/color.js +341 -0
  858. package/dist/renderer/math/color.js.map +1 -0
  859. package/dist/renderer/math/mat3.js +71 -0
  860. package/dist/renderer/math/mat3.js.map +1 -0
  861. package/dist/renderer/math/patternSpace.js +22 -0
  862. package/dist/renderer/math/patternSpace.js.map +1 -0
  863. package/dist/renderer/math/viewToMat3.js +19 -0
  864. package/dist/renderer/math/viewToMat3.js.map +1 -0
  865. package/dist/renderer/paintResources.js +18 -0
  866. package/dist/renderer/paintResources.js.map +1 -0
  867. package/dist/renderer/paintScratch.js +37 -0
  868. package/dist/renderer/paintScratch.js.map +1 -0
  869. package/dist/renderer/shaders/ShaderProgram.js +74 -0
  870. package/dist/renderer/shaders/ShaderProgram.js.map +1 -0
  871. package/dist/renderer/shaders/batchFill.js +118 -0
  872. package/dist/renderer/shaders/batchFill.js.map +1 -0
  873. package/dist/renderer/shaders/customPrelude.js +34 -0
  874. package/dist/renderer/shaders/customPrelude.js.map +1 -0
  875. package/dist/renderer/shaders/extractUniformNames.js +184 -0
  876. package/dist/renderer/shaders/extractUniformNames.js.map +1 -0
  877. package/dist/renderer/shaders/glyphPaint.js +61 -0
  878. package/dist/renderer/shaders/glyphPaint.js.map +1 -0
  879. package/dist/renderer/shaders/gradFill.js +30 -0
  880. package/dist/renderer/shaders/gradFill.js.map +1 -0
  881. package/dist/renderer/shaders/imageFill.js +14 -0
  882. package/dist/renderer/shaders/imageFill.js.map +1 -0
  883. package/dist/renderer/shaders/pathFill.js +13 -0
  884. package/dist/renderer/shaders/pathFill.js.map +1 -0
  885. package/dist/renderer/shaders/patternFill.js +24 -0
  886. package/dist/renderer/shaders/patternFill.js.map +1 -0
  887. package/dist/renderer/shaders/registerProgram.js +18 -0
  888. package/dist/renderer/shaders/registerProgram.js.map +1 -0
  889. package/dist/renderer/spriteSheet.js +14 -0
  890. package/dist/renderer/spriteSheet.js.map +1 -0
  891. package/dist/renderer/state/GroupState.js +77 -0
  892. package/dist/renderer/state/GroupState.js.map +1 -0
  893. package/dist/renderer/syntheticItalic.js +6 -0
  894. package/dist/renderer/syntheticItalic.js.map +1 -0
  895. package/dist/renderer/textures/registerTexture.js +14 -0
  896. package/dist/renderer/textures/registerTexture.js.map +1 -0
  897. package/dist/renderer.d.ts +18 -20
  898. package/dist/renderer.js +18 -13
  899. package/dist/resize.d.ts +10 -46
  900. package/dist/resize.js +7 -5
  901. package/dist/routing.d.ts +1 -1
  902. package/dist/routing.js +2 -3
  903. package/dist/scheduling/useVisibleRaf.js +69 -0
  904. package/dist/scheduling/useVisibleRaf.js.map +1 -0
  905. package/dist/test-hook/createTestHook.js +39 -0
  906. package/dist/test-hook/createTestHook.js.map +1 -0
  907. package/dist/test-hook/install.js +12 -0
  908. package/dist/test-hook/install.js.map +1 -0
  909. package/dist/test-seams-fYf6m5pu.d.ts +356 -0
  910. package/dist/test-seams.d.ts +6 -0
  911. package/dist/test-seams.js +3 -0
  912. package/dist/tools/builtin/ellipse/useEllipseTool.js +33 -0
  913. package/dist/tools/builtin/ellipse/useEllipseTool.js.map +1 -0
  914. package/dist/tools/builtin/eyedropper/useEyedropperTool.js +55 -0
  915. package/dist/tools/builtin/eyedropper/useEyedropperTool.js.map +1 -0
  916. package/dist/tools/builtin/hand/dragPanContribution.js +17 -0
  917. package/dist/tools/builtin/hand/dragPanContribution.js.map +1 -0
  918. package/dist/tools/builtin/hand/useHandTool.js +31 -0
  919. package/dist/tools/builtin/hand/useHandTool.js.map +1 -0
  920. package/dist/tools/builtin/image/useImageTool.js +41 -0
  921. package/dist/tools/builtin/image/useImageTool.js.map +1 -0
  922. package/dist/tools/builtin/lasso/useLassoTool.js +42 -0
  923. package/dist/tools/builtin/lasso/useLassoTool.js.map +1 -0
  924. package/dist/tools/builtin/line/useLineTool.js +33 -0
  925. package/dist/tools/builtin/line/useLineTool.js.map +1 -0
  926. package/dist/tools/builtin/pen/usePenTool.js +414 -0
  927. package/dist/tools/builtin/pen/usePenTool.js.map +1 -0
  928. package/dist/tools/builtin/pencil/usePencilTool.js +36 -0
  929. package/dist/tools/builtin/pencil/usePencilTool.js.map +1 -0
  930. package/dist/tools/builtin/pickTopMostHit.js +45 -0
  931. package/dist/tools/builtin/pickTopMostHit.js.map +1 -0
  932. package/dist/tools/builtin/polygon/usePolygonTool.js +81 -0
  933. package/dist/tools/builtin/polygon/usePolygonTool.js.map +1 -0
  934. package/dist/tools/builtin/rect/useRectTool.js +32 -0
  935. package/dist/tools/builtin/rect/useRectTool.js.map +1 -0
  936. package/dist/tools/builtin/select/selectionContributions.js +109 -0
  937. package/dist/tools/builtin/select/selectionContributions.js.map +1 -0
  938. package/dist/tools/builtin/select/useSelectTool.js +162 -0
  939. package/dist/tools/builtin/select/useSelectTool.js.map +1 -0
  940. package/dist/tools/builtin/shared/insertToolOptions.js +8 -0
  941. package/dist/tools/builtin/shared/insertToolOptions.js.map +1 -0
  942. package/dist/tools/builtin/slice/useSliceTool.js +263 -0
  943. package/dist/tools/builtin/slice/useSliceTool.js.map +1 -0
  944. package/dist/tools/builtin/star/useStarTool.js +82 -0
  945. package/dist/tools/builtin/star/useStarTool.js.map +1 -0
  946. package/dist/tools/builtin/text/useTextTool.js +177 -0
  947. package/dist/tools/builtin/text/useTextTool.js.map +1 -0
  948. package/dist/tools/overlayBinding.js +8 -0
  949. package/dist/tools/overlayBinding.js.map +1 -0
  950. package/dist/tools/prefs.js +47 -0
  951. package/dist/tools/prefs.js.map +1 -0
  952. package/dist/tools/useKeybindings.js +66 -0
  953. package/dist/tools/useKeybindings.js.map +1 -0
  954. package/dist/{types-CxC8P6W0.d.ts → types-CA54-mAZ.d.ts} +188 -17
  955. package/dist/{types-D_74YlWs.d.ts → types-DSjd6W3n.d.ts} +35 -12
  956. package/dist/util/color.js +26 -0
  957. package/dist/util/color.js.map +1 -0
  958. package/dist/util/constrainTo45.js +17 -0
  959. package/dist/util/constrainTo45.js.map +1 -0
  960. package/dist/util/paint.js +72 -0
  961. package/dist/util/paint.js.map +1 -0
  962. package/dist/version.js +6 -0
  963. package/dist/version.js.map +1 -0
  964. package/package.json +31 -18
  965. package/dist/chunk-44EWMJV2.js +0 -128
  966. package/dist/chunk-44EWMJV2.js.map +0 -1
  967. package/dist/chunk-4RJP2N2L.js +0 -143
  968. package/dist/chunk-4RJP2N2L.js.map +0 -1
  969. package/dist/chunk-BJN5ZRIJ.js +0 -167
  970. package/dist/chunk-BJN5ZRIJ.js.map +0 -1
  971. package/dist/chunk-D4AAWR64.js +0 -28
  972. package/dist/chunk-D4AAWR64.js.map +0 -1
  973. package/dist/chunk-DOBSZOPR.js +0 -29
  974. package/dist/chunk-DOBSZOPR.js.map +0 -1
  975. package/dist/chunk-H6N2JSZ3.js +0 -248
  976. package/dist/chunk-H6N2JSZ3.js.map +0 -1
  977. package/dist/chunk-HPFJUUTF.js +0 -167
  978. package/dist/chunk-HPFJUUTF.js.map +0 -1
  979. package/dist/chunk-L5YNZYEG.js +0 -648
  980. package/dist/chunk-L5YNZYEG.js.map +0 -1
  981. package/dist/chunk-MZAIDI6D.js +0 -32492
  982. package/dist/chunk-MZAIDI6D.js.map +0 -1
  983. package/dist/chunk-PNNZSYRD.js +0 -318
  984. package/dist/chunk-PNNZSYRD.js.map +0 -1
  985. package/dist/chunk-RMR4QMM6.js +0 -250
  986. package/dist/chunk-RMR4QMM6.js.map +0 -1
  987. package/dist/clipboard.js.map +0 -1
  988. package/dist/clone.js.map +0 -1
  989. package/dist/grid-BXdz8GF2.d.ts +0 -158
  990. package/dist/index.css.map +0 -1
  991. package/dist/index.js.map +0 -1
  992. package/dist/insert.d.ts +0 -37
  993. package/dist/insert.js +0 -81
  994. package/dist/insert.js.map +0 -1
  995. package/dist/math.js.map +0 -1
  996. package/dist/move.js.map +0 -1
  997. package/dist/options-CzjxFoYZ.d.ts +0 -67
  998. package/dist/path-JEV2c5If.d.ts +0 -48
  999. package/dist/patterns-builtin.js.map +0 -1
  1000. package/dist/renderer.css +0 -86
  1001. package/dist/renderer.css.map +0 -1
  1002. package/dist/renderer.js.map +0 -1
  1003. package/dist/resize.js.map +0 -1
  1004. package/dist/routing.js.map +0 -1
  1005. package/dist/types-D2tTKEU0.d.ts +0 -18
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SceneCanvas.js","names":["useTools","clientToWorldHelper","DEFAULT_ALLOWED_CAPABILITIES","_Fragment","clientToWorld","useTools$1","DEFAULT_ALLOWED_CAPABILITIES$1","DEFAULT_HANDLE_SIZE","HANDLE_BASE_PX","IS_DEV","COORD_TRACE_LIMIT","coordTrace","COORD_DEV","recordCoordTrace","entry","mergeLayersWithDefaults","defaults","defaultDrawOne","defaultPaintBounds","targetSizesPx","targetScale","user","result","scene","paintBoundsFor","NON_SHAPE_BUILTIN_TOOLS","BUILTIN_TOOL_IDS","KIT_SHAPE_KINDS","canvasDebug","debug","_slops","rest","EMPTY_ID_SET","EMPTY_ANCHOR_SELECTION","isToolsApi","tools","SceneCanvasInner","sceneInput","selectToolOpts","selectionProp","toolsProp","viewDescriptors","getFocusedProp","props","descriptor","poseDescriptor","AUTO_POSE_DESCRIPTOR","deviceProfile","useDeviceProfile","device","chromeSizes","useMemo","isSerialized","s","bakedScene","useState","sceneFromJSON","viewProp","onViewChangeProp","redrawOnProp","restProps","getActiveMode","modes","getActiveModeFor","redrawOn","internalCanvasRef","useRef","canvasApiRef","canvasReady","setCanvasReady","dlog","consumerHandlers","ingestion","useEffect","disposers","acquireKitContentHandlers","h","registerContentHandler","d","animator","useLateContentRedraw","useCallback","currentViewRef","normalizeView","defaultView","useInsertionEffect","api","v","handleViewChange","cameraAnimator","useAnimator","viewChannel","viewAnimation","useViewAnimationOn","notifyViewChange","animatedZoom","viewport","viewportZoomProp","resolvedViewportZoom","base","derivedSelectionOptions","selectionOptions","internalSelection","useSelection","baseSelection","baseAdapterMethods","readOnlyAdapterMethods","selection","selectable","noopSet","currentSelection","selectionKinds","out","id","node","describeKind","pose","pathEditingId","setPathEditingId","pathEditingIdRef","useLatest","anchorEditingAllowedRef","effectivePathEditingId","allowed","selectedAnchorsRef","anchorMarqueeRef","editAnchorsExternalState","next","rect","selectToolWithDefaults","selectionRef","kindClassifier","effective","routing","inferredNodeRouting","registry","createNodeRouting","k","data","kindOfNode","composedAlphaFor","composeAlphaFor","alphaFor","surfaceViewRegistry","useOptionalViewRegistry","layerPaintRef","sceneLayerGate","createSceneLayerGate","layerIsPainted","layerId","viewLayerGate","layerVisibility","layerOrder","framed","poseComposition","adapter","useSceneAdapter","insertTool","internalSelect","internalPickEvery","internalPickBest","internalBoundsOf","internalBoundsOfPose","internalPlaneOfNode","internalMoveOptions","useSceneSelectTool","planeOfNodeRef","getNodeAtPoint","makeGetNodeAtPoint","isPointerInteractive","hit","wx","wy","view","featuresKey","features","hasViewport","enabled","resolveFeatures","inertiaEnabled","inertiaObj","handToolInertia","handTool","useHandTool","baseRequestedTools","defaultTools","KNOWN_BUILTIN_IDS","toolsPatchExtras","trueIds","value","wants","shapeTools","useBuiltinShapeTools","toolOptions","defaultLongPressFeedback","createLongPressFeedbackContribution","feedbackOpt","longPress","pressFeedback","mergedAmbient","ambient","internalRegistry","toolsPatch","toolsTakeover","internalTools","initialActiveTool","liveToolsRef","getActiveModeRef","isToolEligible","getMode","caps","toolId","c","selectionMoveOptions","rotateOptions","featureContributions","selectionTransformContribution","selectionMoveContribution","standardActionsExclude","include","featureActionIds","bound","b","KIT_STANDARD_ACTION_IDS","onToolsCreatedRef","onToolsCreated","onDoubleClickRef","onDoubleClick","getNodeAtPointRef","onDoubleClickObserver","cb","world","mergedLayers","layers","resolvedActions","actions","merged","getActionRef","dispatcherRef","createDispatcher","dispatcher","gestureSource","createGestureSource","createDispatcherPreviewSources","sceneSlot","slot","wireSceneSlotToScene","previewLayer","usePreviewGhostLayer","dispatcherOverlay","useDispatcherOverlayLayer","getNodeAtPointRefForHover","getHover","useHoverTracking","canvas","target","clientX","clientY","origin","x","y","clientToWorld","reg","r","chromeVisibility","selectionForCapsRef","getFocusedPropRef","effectiveChromeVisibility","never","chromeVisibilityRef","deviceProfileRef","resizablePredRef","buildRuleCtxFor","sel","inputs","modeInfo","ctx","buildChromeCtx","resizablePred","selectionResizable","viewZoom","currentRuleInputs","buildCurrentRuleCtx","anchorEditingAllowed","chromeCaps","resolveVisibility","getIsVisibleForCanvas","wantsPen","penPreviewLayer","createPenPreviewLayer","sceneRefForOverlay","slopsOn","selectionOverlayCfg","badgeOf","rotationBadgeOf","rotationBadge","chromeAffordancesRef","slopsLayer","createSlopsDebugLayer","livePathFor","touched","source","previews","previewIds","owns","pid","p","pathFromPlane","resolveEditablePathOf","pathEditingOverlayLayer","createPathEditingOverlayLayer","plane","rectFromPlane","getSuppressedSelectionIds","selectionOverlayLayer","selCfg","cfg","callerSuppress","getSuppressedIds","own","caller","createSelectionOverlayLayer","wiredLayers","actionsRegistryRef","ingestionClipboardReviver","ingestionClipboardEnabled","ingestionClipboard","ingestImpl","items","input","itemsFromFiles","point","addedViews","setAddedViews","addView","list","outer","dims","mergedRef","extended","ref","viewInputs","Canvas","testHookSceneRef","testHookSelectionRef","testHookRef","installTestHookIfRequested","DeviceProfileProvider","ViewInputsProvider","Fragment","PointerProviderIfRoot","PointerPublisher","StandardActionsRegistrar","GestureDispatcherMounter","enableGestureDispatcher","enableKeybindings","ToolKeybindingsMounter","CanvasView","i","contributionEntries","children","useKeybindings","useContributionRoles","canvasApi","versionCheck","longPressOpts","useActionsRegistry","depRegistry","useDepRegistry","viewRegistry","entriesById","m","tool","contributions","pickEveryRef","pickEvery","pickBestRef","pickBest","kindOfNodeRef","depRegistryRef","planeOfNode","getAnchorState","anchorStateFrom","path","affordances","chromeAffordances","handleHitRadius","affordanceAt","boundsOf","viewRef","buildAffordanceAt","EMPTY_CHROME_STATE","classifyTarget","buildClassifyTarget","ids","clientToWorld$1","canvasRef","affordanceWithLayers","extra","worldPoint","claim","requestRedraw","paintedCursor","longPressState","createLongPressStore","views","useGestureDispatcher","useDepSource","a","decayLoop","useDecayLoop","useViewDepSource","onViewChange","viewportRecenter","el","useStandardActions","excludeActions","pointer","usePointerContext","useViewportActions","viewportPanEnabled","viewportZoom","viewportPinchZoom","useAreaSelectDepSource","alphaOf","useNodeAtPointDepSource","useLayoutDepSource","layouts","layoutDropTarget","reflowTransition","useLayoutArrivals","useInsertDepSource","insertNodeFactories","useSliceDepSource","useSnapDepSource","snapPoint","useDebugDepSource","useIngestionDepSource","ingestionResolveSrc","ingestionSvg","useLassoSelectDepSource","useTextEditDepSource","useEditAnchorsDepSource","useDispatcherDepSource","usePoseDescriptorDepSource","usePoseCompositionDepSource","useActionsPropResolver","resizeOptions","ResizePolicyRegistrar","geometryProjection","GeometryProjectionRegistrar","useResizePolicy","resizePolicyOptions","options","useGeometryProjection","projection","SceneCanvasInnerForwardRef","forwardRef","SceneCanvasWrapper","InputScope","ViewRegistryProvider","SceneCanvas","SCENE_CANVAS_FEATURES","rotateAroundAABBCenter"],"sources":["../../src/canvas/SceneCanvas.tsx"],"sourcesContent":["/**\n * `<SceneCanvas>` — `<Canvas>` wired to a `Scene` primitive.\n *\n * Synthesizes a `MoveAdapter & ResizeAdapter & RotateAdapter & AreaSelectAdapter`\n * from the passed `scene` (via `sceneToAdapter`) and an internal `useTools`.\n * Bare, it only renders: behavior comes from the `features` presets\n * (`canvas/SceneCanvas/features.ts`), each of which registers its own actions,\n * tools, ambient bindings and chrome.\n *\n * If a consumer needs custom tools (e.g. `select` + `insert`), they can pass\n * `tools={useTools(...)}` directly and SceneCanvas forwards it as-is — the\n * internal tool registry is ignored in that case.\n *\n * Cascade: `Scene` stores absolute poses, so dragging a container has to\n * translate its descendants in the live overlay and again at commit. The move\n * action walks `scene.childrenOf` for both — see `cascadeIds` in\n * `interactions/actions/defaults/move.ts`.\n */\nimport { forwardRef, useCallback, useEffect, useInsertionEffect, useMemo, useRef, useState } from 'react';\nimport { dwarn } from '../debug';\nimport type React from 'react';\nimport type { ReactNode } from 'react';\nimport type { ActionsProp } from '@weasel-js/routing';\nimport type { Action } from '@weasel-js/routing';\nimport { useStandardActions } from 'interactions/actions/useStandardActions';\nimport type { DrawCommand, ShaderProgramHandle } from '../renderer';\nimport { defaultDrawOne, defaultPaintBounds, paintBoundsFor } from './defaultDrawOne';\nimport type { FillStyle } from '@weasel-js/paint';\nimport { useLateContentRedraw } from './useLateContentRedraw';\nimport { Canvas } from './Canvas';\nimport type { CanvasProps, LayersMap, SceneSlotConfig, SelectionOverlaySlotConfig } from './Canvas';\nimport { wireSceneSlotToScene, composeAlphaFor } from './sceneSlotWiring';\nimport type { CanvasExtensionApi, CanvasViewHandle, SceneCanvasApi } from './canvasExtension';\nimport type { Animator } from '../animation/types';\nimport { useAnimator } from '../animation/useAnimator';\nimport { useViewAnimationOn } from 'core/viewport/useViewAnimation';\nimport type { ViewAnimationApi } from 'core/viewport/useViewAnimation';\nimport { useSceneAdapter, type SceneToAdapterOptions } from './sceneAdapter';\nimport type { LayoutDropTargetMode, ReflowTransition } from '../layout/types';\nimport { useDecayLoop, type PanBounds } from 'core/viewport/useDecayLoop';\nimport type { WheelPanOptions } from 'interactions/actions/defaults/viewportWheelPan';\nimport { normalizeView, viewZoom, type View } from 'core/viewport/view';\nimport type { Node, Scene, SerializedScene } from 'core/scene/types';\nimport type { NodeId } from 'core/scene/types';\nimport { sceneFromJSON } from 'core/scene/scene';\nimport { useSelection, type SelectionApi, type UseSelectionOptions } from 'core/selection/useSelection';\nimport { usePublishSelection } from 'features/selection/SelectionContext';\nimport type { Bounds } from 'tools/builtin/select';\nimport { useTools } from '../tools/overlayBinding';\nimport { type ToolsApi } from '../tools/overlayBinding';\nimport { useKeybindings } from 'tools/useKeybindings';\nimport type { AnyTool, Contribution } from '../tools/overlayBinding';\nimport type { UseMoveOptions } from 'interactions/actions/move/options';\nimport type { UseResizeOptions } from 'interactions/actions/resize/options';\nimport type { UseRotateOptions } from 'interactions/actions/rotate/options';\nimport type { SnapStrategy } from 'interactions/gestures/types';\nimport { dlog } from '../debug/flag';\nimport type { DebugConfig } from '../debug/types';\nimport { DeviceProfileProvider, useDeviceProfile } from '../core/device/useDeviceProfile';\nimport { ViewRegistryProvider, useOptionalViewRegistry } from './viewRegistry';\nimport { createSceneLayerGate, type ViewLayerPaint } from './sceneLayerPaint';\nimport { ViewInputsProvider, type SurfaceViewInputs, type ViewRuleInputs } from './viewInputs';\nimport { CanvasView, type CanvasViewProps } from './CanvasView';\nimport type { DeviceProfile } from '../core/device/types';\nimport { HANDLE_BASE_PX, targetSizesPx } from '../core/device/targets';\nimport { InputScope, type Yoke } from '@weasel-js/routing/react';\nimport { useContributionRoles, contributionEntries, type VersionCheck } from './SceneCanvas/useContributionRoles';\nimport type { SurfaceContribution } from './surfaceContribution';\nimport { useDepSource } from '@weasel-js/routing/react';\nimport { usePointerContext } from 'features/pointer/PointerContext';\nimport { PointerProviderIfRoot, PointerPublisher } from './SceneCanvas/PointerProviderIfRoot';\nimport { useSceneSelectTool } from './SceneCanvas/useSceneSelectTool';\nimport { selectionMoveContribution, selectionTransformContribution } from 'tools/builtin/select';\nimport {\n resolveFeatures,\n featureActionIds,\n type Feature,\n} from './SceneCanvas/features';\nimport { KIT_STANDARD_ACTION_IDS } from 'interactions/actions/useStandardActions';\nexport type { Feature } from './SceneCanvas/features';\nexport { SCENE_CANVAS_FEATURES } from './SceneCanvas/features';\nimport { useHandTool } from 'tools/builtin/hand';\nimport { usePreviewGhostLayer } from './SceneCanvas/usePreviewGhostLayer';\nimport { useDispatcherOverlayLayer } from './SceneCanvas/useDispatcherOverlayLayer';\nimport { createGestureSource, createDispatcherPreviewSources } from './SceneCanvas/dispatcherGestureBounds';\nimport type { PickView } from './SceneCanvas/useSceneSelectTool';\nimport type { GesturePreviewSource } from './gestureBounds';\nimport { createPenPreviewLayer } from 'features/paths/penPreviewLayer';\nimport { createPathEditingOverlayLayer } from 'features/paths/pathEditingOverlayLayer';\nimport { pathFromPlane } from './planeClips';\nimport { rectFromPlane } from 'core/viewport/parallax';\nimport { createSlopsDebugLayer } from './slopsDebugLayer';\nimport type { PenScratch } from 'tools/builtin/pen';\nimport type { Tool } from '../tools/overlayBinding';\nimport { useBuiltinShapeTools, type BuiltinToolOptions } from './SceneCanvas/useBuiltinShapeTools';\nimport { KIT_SHAPE_KINDS } from 'core/shapeKinds';\nimport type { BuiltinShapeToolId } from 'core/shapeKinds';\nexport type { BuiltinToolOptions } from './SceneCanvas/useBuiltinShapeTools';\nimport {\n useViewDepSource,\n useAreaSelectDepSource,\n useNodeAtPointDepSource,\n useDebugDepSource,\n useInsertDepSource,\n useSliceDepSource,\n useSnapDepSource,\n useLassoSelectDepSource,\n useTextEditDepSource,\n useEditAnchorsDepSource,\n useDispatcherDepSource,\n usePoseDescriptorDepSource,\n usePoseCompositionDepSource,\n useResizePolicy,\n resizePolicyOptions,\n useLayoutDepSource,\n useGeometryProjection,\n useIngestionDepSource,\n type InsertNodeFactory,\n} from './deps';\nimport { useLayoutArrivals } from '../layout/arrivals';\nimport {\n acquireKitContentHandlers,\n registerContentHandler,\n itemsFromFiles,\n type ContentHandlerEntry,\n type IngestItem,\n} from 'features/ingestion';\nimport type { GeometryProjection } from 'interactions/actions/geometryProjection';\nimport type { ClipboardIngestCtx, SvgIngestOptions } from 'interactions/actions/depSchema';\nimport type { InsertAdapter } from 'core/adapters/types';\nimport { resolveEditablePathOf } from './deps/editAnchors';\nimport type { PolygonPath } from '@weasel-js/geom';\nimport { useActionsPropResolver } from './SceneCanvas/useActionsPropResolver';\nimport { useViewportActions } from './SceneCanvas/useViewportActions';\nimport type { ViewportZoomAnimateOptions, ViewportZoomOptions } from 'interactions/actions/defaults/viewportZoom';\nimport type { PinchZoomOptions } from 'interactions/actions/defaults/pinchZoom';\nimport { useGestureDispatcher } from '@weasel-js/routing/react';\nimport { createDispatcher, createLongPressStore, type Dispatcher } from '@weasel-js/routing';\nimport { createLongPressFeedbackContribution } from '../features/longPress/longPressFeedback';\nimport type { ActionsRegistry } from '@weasel-js/routing';\nimport { useActionsRegistry } from '@weasel-js/routing/react';\nimport { buildAffordanceAt, buildClassifyTarget, anchorStateFrom, chromeAffordances } from './affordanceAt';\nimport type { Affordance } from 'affordances/types';\nimport { EMPTY_CHROME_STATE } from 'core/selection/chromeState';\nimport { clientToWorld as clientToWorldHelper } from 'core/viewport/clientToWorld';\nimport type { Op } from 'core/ops/types';\nimport { useDepRegistry } from '@weasel-js/routing/react';\nimport { useLatest } from '@weasel-js/react';\nimport { createNodeRouting, type NodeRoutingEntry } from '../core/scene/NodeRouting';\nimport { inferredNodeRouting } from './SceneCanvas/defaultNodeRouting';\nimport { installTestHookIfRequested } from '../test-hook/install';\nimport type { WeaselTestHook } from '../test-hook/types';\nimport {\n createSelectionOverlayLayer,\n rotationBadgeOf,\n} from 'features/selection/overlay';\nimport { getActiveModeFor, type ModeRegistry } from '@weasel-js/modes';\nimport { makeGetNodeAtPoint } from './getNodeAtPoint';\nimport {\n buildChromeCtx,\n never,\n resolveVisibility,\n useHoverTracking,\n DEFAULT_ALLOWED_CAPABILITIES,\n} from 'features/chrome-caps';\nimport type { RuleCtx } from 'features/chrome-caps';\nimport { AUTO_POSE_DESCRIPTOR } from 'interactions/actions/resize/autoPoseDescriptor';\nimport type { PoseDescriptor } from 'interactions/actions/resize/geometry';\nexport { rotateAroundAABBCenter } from './poseRotation';\n\n/**\n * Minimal adapter surface the legacy bridge factories need for delete /\n * duplicate / group / ungroup. Extracted from `SceneCanvasAdapter` to avoid\n * threading the full generic type through `StandardActionsRegistrar` (which is\n * non-generic). The actual adapter supplied is always a `SceneCanvasAdapter`\n * so the cast is safe.\n */\ninterface BridgeAdapter {\n applyOps(ops: Op[], label?: string): void;\n insertNode(node: { id: string; [k: string]: unknown }): void;\n removeNode(id: string): void;\n setSelection(ids: string[]): void;\n}\n\n/** Default size in CSS pixels for selection corner-handles AND their\n * hit-test radius, at `targetScale = 1`. Used by the SceneCanvas defaults;\n * consumers override via `selectTool.handleHitRadius` or\n * `layers.selectionOverlay.handles.size`.\n *\n * Deliberately unscaled: consumers reading this constant keep getting the\n * number they always got. Kit-internal use sites multiply by\n * `DeviceProfile.targetScale`. */\nexport const DEFAULT_HANDLE_SIZE = HANDLE_BASE_PX;\n\n// ---------------------------------------------------------------------------\n// Dev-only coord trace\n// ---------------------------------------------------------------------------\n\n/** Records every `clientToWorld` call so dev tools (and agents) can\n * reconcile cursor coords with computed world coords. Mirrors the\n * dispatcher's trace log. Exposed on `window.__weaselCoordLog__`. */\nexport interface CoordTraceEntry {\n ts: number;\n clientX: number;\n clientY: number;\n rect: { left: number; top: number; width: number; height: number } | null;\n view: { x: number; y: number; scaleX: number; scaleY: number } | null;\n world: { x: number; y: number };\n /** True when canvas/view weren't available and we returned identity. */\n fallback: boolean;\n}\n\n/**\n * `import.meta.env.DEV`, read through a cast rather than off a typed\n * `ImportMeta`. Core must not depend on a bundler's ambient augmentation\n * (`vite/client`) to compile — until core moved into `packages/core/`, two\n * call sites below read `import.meta.env` bare and only type-checked because\n * `apps/site/vite-env.d.ts` leaked its `/// <reference types=\"vite/client\" />`\n * into the shared root-tsconfig program. Isolating core's build surfaced it.\n * Mirrors the same cast in dispatcher.ts and buildDeps.ts.\n */\n/** `<SceneCanvas longPress>`. */\nexport interface SceneCanvasLongPress {\n /**\n * Shown while a long-press is held and some binding would fire on it.\n * Default: a ring that fills around the press point\n * (`createLongPressFeedbackContribution()`), static under\n * `prefers-reduced-motion`. `false` shows nothing; a contribution replaces\n * it, reading the `longPress` dep. Installed beside `ambient`, so under a\n * `tools` takeover add it to your own `useTools` call instead.\n */\n feedback?: boolean | SurfaceContribution;\n /** Default true. A long-press some binding handled pulses\n * `navigator.vibrate` briefly, for touch and pen, where the API exists. */\n haptics?: boolean;\n /** Hold time in ms. Default `LONG_PRESS_MS` (500). */\n duration?: number;\n}\n\nconst IS_DEV: boolean = (() => {\n try {\n return Boolean((import.meta as unknown as { env?: { DEV?: boolean } }).env?.DEV);\n } catch {\n return false;\n }\n})();\n\nconst COORD_TRACE_LIMIT = 200;\nconst coordTrace: CoordTraceEntry[] = [];\nconst COORD_DEV: boolean = IS_DEV;\nif (COORD_DEV && typeof window !== 'undefined') {\n (window as unknown as { __weaselCoordLog__: CoordTraceEntry[] }).__weaselCoordLog__ = coordTrace;\n}\nfunction recordCoordTrace(entry: CoordTraceEntry): void {\n if (!COORD_DEV) return;\n coordTrace.push(entry);\n if (coordTrace.length > COORD_TRACE_LIMIT) coordTrace.shift();\n}\n\nexport { defaultDrawOne } from './defaultDrawOne';\n\n/** `<SceneCanvas layers>`: a {@link LayersMap} whose scene slot may be partial,\n * since the defaults fill in whatever it leaves out. */\nexport type SceneCanvasLayers<TNode extends { id: string }, TPose> = LayersMap<\n TNode,\n TPose,\n Partial<SceneSlotConfig<TNode, TPose>>\n>;\n\n/** Deep-merge user-supplied `layers` with kit defaults. Slots the user\n * doesn't mention get filled with defaults; slots explicitly set to\n * `null` are dropped (the existing \"disable this slot\" convention).\n * Partial slot configs (e.g. `{ scene: { drawOne: customFn } }`) are\n * shallow-spread on top of the default slot config.\n *\n * `targetScale` comes from the resolved {@link DeviceProfile}. It is a\n * parameter rather than a read because this function is module-scope and\n * the profile is a hook value; the caller inside the component passes it. */\nexport function mergeLayersWithDefaults<TData, TLayer extends string, TPose>(\n user: SceneCanvasLayers<Node<TData, TLayer, TPose>, TPose> | undefined,\n targetScale = 1,\n): LayersMap<Node<TData, TLayer, TPose>, TPose> {\n const defaults = {\n scene: {\n drawOne: defaultDrawOne as (\n node: Node<TData, TLayer, TPose>,\n pose: TPose,\n ) => DrawCommand[],\n paintBounds: defaultPaintBounds<TData, TLayer, TPose>,\n },\n selectionOverlay: { handles: { size: targetSizesPx(targetScale).handle } },\n };\n\n if (!user) return defaults as LayersMap<Node<TData, TLayer, TPose>, TPose>;\n\n // Start from a shallow copy of the user map so unknown slots pass through.\n const result = { ...user } as LayersMap<Node<TData, TLayer, TPose>, TPose>;\n\n if (!('scene' in user)) {\n result.scene = defaults.scene;\n } else if (user.scene === null) {\n result.scene = null;\n } else {\n const scene = { ...defaults.scene, ...user.scene };\n result.scene = user.scene && 'paintBounds' in user.scene\n ? scene\n : { ...scene, paintBounds: paintBoundsFor<TData, TLayer, TPose>(scene.drawOne) };\n }\n\n if (!('selectionOverlay' in user)) {\n result.selectionOverlay = defaults.selectionOverlay;\n } else if (user.selectionOverlay === null) {\n result.selectionOverlay = null;\n } else {\n result.selectionOverlay = { ...defaults.selectionOverlay, ...user.selectionOverlay };\n }\n\n return result;\n}\n\n/** Built-in tool ids SceneCanvas knows how to mount when no `tools` prop\n * is supplied, via `defaultTools`. */\nexport type BuiltinToolId = 'select' | 'hand' | BuiltinShapeToolId;\n\n/** Built-in tool ids that aren't shape tools — the ones with no entry in\n * the `core/shapeKinds` table. */\nconst NON_SHAPE_BUILTIN_TOOLS: readonly Exclude<BuiltinToolId, BuiltinShapeToolId>[] = ['select', 'hand'];\n\n/** Every built-in tool id, shape tools included. */\nexport const BUILTIN_TOOL_IDS: readonly BuiltinToolId[] = [...NON_SHAPE_BUILTIN_TOOLS, ...KIT_SHAPE_KINDS];\n\n/** Minimal hit descriptor passed to `onDoubleClick`. Contains the fields\n * modality dispatch needs; extends as the kit's `Hit` type evolves. */\nexport interface SceneCanvasHit {\n id: string;\n kind: string;\n}\n\n/** `<SceneCanvas debug>` minus the flag only SceneCanvas reads. */\nfunction canvasDebug(debug: (DebugConfig & { slops?: boolean }) | false): DebugConfig | false {\n if (debug === false) return false;\n const { slops: _slops, ...rest } = debug;\n return rest;\n}\n\n/** Props for `<SceneCanvas>`. A scene is the only thing it needs. With nothing\n * else it renders that scene and keeps a selection no input sets; `features`\n * turns behavior on by preset, and the rest configures what those turn on. */\nexport type SceneCanvasProps<TData, TLayer extends string, TPose> =\n Omit<\n CanvasProps<Node<TData, TLayer, TPose>, TPose>,\n | 'adapter'\n | 'moveOptions' | 'resizeOptions' | 'rotateOptions'\n | 'snap' | 'pickEvery' | 'boundsOf' | 'handleHitRadius'\n | 'selection' | 'selectionOptions' | 'tools'\n | 'layers' // stripped so we can re-add as optional below\n | 'onBackgroundClick' // SceneCanvas synthesizes this; not a consumer prop\n | 'getIsVisible' // SceneCanvas synthesizes this from chromeVisibility\n | 'contentVersion' // SceneCanvas wires this to the scene's own version\n | 'layerVisibility' | 'layerOrder' // re-declared below: they gate picking here too\n | 'debug' // re-declared below with SceneCanvas's own `slops`\n >\n & {\n /** A `Scene` (typically from `useScene`) — or a `SerializedScene`\n * JSON object, which SceneCanvas bakes into a Scene internally on\n * first render. The serialized form is read once; subsequent\n * changes to the prop are ignored. Pass a `key` prop on\n * `<SceneCanvas>` to force a fresh canvas from updated JSON.\n *\n * The accepted JSON shape is intentionally relaxed (`version:\n * number` rather than `1` literal) so a `import json from './x.json'`\n * result satisfies the type without an `as` cast — Vite infers\n * number-literal types as `number` from JSON, which the strict\n * `SerializedScene<…>` would reject. */\n scene:\n | Scene<TData, TLayer, TPose>\n | SerializedScene<TData, TLayer, TPose>\n | { version: number; systemLayers?: ReadonlyArray<{ id: string }>; nodes: ReadonlyArray<unknown> };\n\n /** Layer configuration. When omitted, SceneCanvas applies kit defaults\n * (a scene slot that paints `node.data.fill` rects + a default\n * selection overlay). A partial scene or selection-overlay config is\n * spread over that slot's defaults; pass `slot: null` to suppress a\n * default explicitly. */\n layers?: SceneCanvasLayers<Node<TData, TLayer, TPose>, TPose>;\n\n /** Layout strategies keyed by container node id (or a resolver), for\n * containers whose scene node declares none (`ContainerNode.layout`\n * wins). Applied to a drag and to every other change to their children,\n * through the scene's layout pass. */\n layouts?: SceneToAdapterOptions<TData, TLayer, TPose>['layouts'];\n\n /** Which layout container a drag lands in when several contain the drop\n * point — the innermost (default), the topmost in paint order, or only\n * containers whose strategy declares a `dropRegion`. Decides both the\n * drag-time reflow preview and the commit. */\n layoutDropTarget?: LayoutDropTargetMode;\n\n /** Carries the siblings a layout reflow displaces to their slots over time\n * instead of snapping them — `useAnimatedReflow` builds one. Covers a\n * drag's reflow and every one the scene records (an insert, delete,\n * reorder or resize inside a laid-out container). Absent or `null`,\n * they snap. */\n reflowTransition?: ReflowTransition<TPose> | null;\n\n /** How a child's stored pose folds into its parent's frame. Omit for the\n * absolute-pose model, where a container groups its children but imposes\n * no transform. Pass `RIGID_POSE_COMPOSITION` to make a container's pose\n * a frame, so rotating it rotates its contents and moving it carries them\n * without touching their poses. */\n poseComposition?: SceneToAdapterOptions<TData, TLayer, TPose>['poseComposition'];\n\n /**\n * Optional consumer seam for eager geometry sync: lets pose-transform\n * actions (move, resize, nudge, flip — NOT rotate) also rewrite a node's\n * data-held geometry. Given a node and the affine `m` applied to its pose,\n * `transform(node, m)` returns updated `data` (geometry mapped by `m`) or\n * `null` for nodes with no data-held geometry.\n *\n * Strictly opt-in: when absent, the kit emits only the pose op and leaves\n * `data` untouched. Consumers wire this via `geometryProjection={myProjection}`.\n *\n * @see GeometryProjection\n */\n geometryProjection?: GeometryProjection;\n\n /**\n * Routing-trait classifiers — list of `NodeRoutingEntry` entries. The kit\n * constructs a `NodeRouting` registry per-`<SceneCanvas>` from this prop,\n * then uses the resulting classifier to derive each hit's `kind` when\n * building `getNodeAtPoint`. Tool routing tables (e.g.\n * `{ target: 'rect', actionId: 'move' }`) match against the produced\n * kind strings.\n *\n * Pass `defaultNodeRouting` to pick up the kit's built-in shape kinds\n * (rect, ellipse, polygon, …) for `data: { kind: '<shape>' }` nodes.\n * Spread additional entries for consumer-defined kinds.\n *\n * See `docs/superpowers/specs/2026-05-24-node-traits-reframe-design.md`.\n *\n * **Memoize the `routing` value.** The kit memoizes the registry on the\n * prop's reference identity. Passing a fresh array each render\n * (e.g. `routing={[...defaultNodeRouting, custom]}` inline) rebuilds the\n * registry and cascades into a new adapter, churning gesture state.\n * Define the list as a module-level constant, or wrap it in `useMemo`.\n * (`defaultNodeRouting` alone is a stable module-level constant; spreading\n * it with extras is what needs the memo.)\n */\n routing?: readonly NodeRoutingEntry[];\n\n /** How to read and rewrite this scene's poses. Every built-in action,\n * the selection chrome and picking read it. Default `AUTO_POSE_DESCRIPTOR`\n * (rect poses and `Path` poses). */\n poseDescriptor?: PoseDescriptor<TPose>;\n\n // --- Geometry: hit-test + bounds overrides consumed by the internal\n // `useSelectTool`. Ignored if the consumer passes their own `tools`. ---\n geometry?: {\n /** Hit-test override. Return the topmost id, the full back-to-front hit\n * stack (`string[]`), or `null` for empty space. The stack form lets a\n * consumer with domain overlap ordering (e.g. children over their\n * container) feed the kit's `pickTopMostHit` the true order instead of\n * pre-collapsing to one id. Matches `Canvas`'s `pickEvery` shape. */\n pickEvery?: (worldX: number, worldY: number) => string | string[] | null;\n boundsOf?: (id: string) => Bounds | null;\n /**\n * What \"the pointer is on this node\" means for the default body-pick.\n *\n * - `'pose'` — the node's pose rect, rotation honored. What every\n * consumer got before `'shape'` existed, and now the opt-out.\n * - `'shape'` (default) — the pose rect as a pre-filter, then the ink the painter\n * actually lays down: its silhouette (`findShapeSilhouette`) filled\n * or not per the painter's `ink`, plus its outline widened by the\n * stroke half-width and `pickTolerancePx`. A click in the concave\n * notch of a star, in the corner outside an ellipse, or in the blank\n * half of a text box falls through to whatever is beneath; a click on\n * the thin outline of an unfilled shape hits it.\n *\n * Painters with no silhouette are unaffected — they keep the pose-rect\n * answer either way, so this can never make a node unreachable.\n *\n * Ignored when `pickEvery` is supplied: that override owns the test.\n */\n picking?: 'pose' | 'shape';\n /**\n * Grab slop around a shape's outline, in **screen** pixels. Default 4.\n *\n * Screen pixels rather than world units so the target keeps its\n * apparent size at any zoom. It widens the outline test under\n * `picking: 'shape'` (a 1px hairline is otherwise a half-world-unit\n * target, which is unhittable), and it grows the pose-rect pre-filter\n * so those outline hits survive it. Set `0` for exact geometry.\n */\n pickTolerancePx?: number;\n };\n\n // --- Selection options. `pickBest` and `handleHitRadius` configure the\n // internal select tool, and are ignored under a `tools` takeover;\n // `move`, `snap`, `resize` and `rotate` configure the `move` and\n // `transform` presets, and apply either way. ---\n selectTool?: {\n move?: UseMoveOptions<TPose>;\n resize?: UseResizeOptions<TPose>;\n /** Rotation options, or `false` to disable rotation entirely — drops the\n * `rotate` action AND hides the selection rotation-handle chrome, so a\n * consumer whose objects don't rotate (e.g. a floor-plan / garden\n * editor) opts out with a single switch instead of pairing\n * `actions={{ rotate: null }}` with a `chromeVisibility` override. */\n rotate?: UseRotateOptions<TPose> | false;\n snap?: SnapStrategy<TPose>;\n handleHitRadius?: number;\n /** Override the body-pick used on click/pointerdown. Alt-aware: receives\n * the live alt state + current selection so consumers can implement\n * alt-cycling through an overlapping stack. Default: top-most hit\n * (alt ignored). */\n pickBest?: (worldX: number, worldY: number, alt: boolean, sel: readonly string[]) => string | null;\n };\n\n // --- Insert tool: when `create` is supplied, the synthesized adapter\n // exposes `commitInsert` and inserted objects are added as leaves on\n // `layer` (default `'default'`). ---\n insertTool?: {\n create: SceneToAdapterOptions<TData, TLayer, TPose>['commitInsert'];\n layer?: TLayer;\n };\n\n /** Consumer node factories for the `insert` action, keyed by tool `kind`.\n * Each factory receives the drag AABB + tool `extras` and returns the\n * node's `data` (in this canvas's own data shape) plus an optional `pose`.\n * A factory for a kit kind (`rect`, `line`, …) replaces the kit's default\n * `{ path, fill }` node for that kind; a factory for a novel kind (e.g.\n * `text`) adds insert support the kit doesn't ship. The dep supplies id,\n * layer, and the undoable op. Return `null` to reject an insert. */\n insertNodeFactories?: Record<string, InsertNodeFactory>;\n\n /** External-content ingestion (OS drop / clipboard paste / picker).\n * `handlers` are consumer content handlers registered for this canvas's\n * lifetime (priority 0 by default — they beat the kit's `image/*` /\n * `image/svg+xml` handlers at -100/-90). `resolveSrc` overrides the\n * image handler's `data:`-URI embed (e.g. upload to an asset store,\n * return the URL). `svg.unpack` makes the kit SVG handler parse dropped\n * SVG files into native scene nodes instead of keeping each one a\n * single embedded-image node.\n * `clipboard` configures the kit weasel-JSON paste handler: enabled by\n * default (pastes of weasel clipboard payloads re-materialize through\n * this canvas's adapter); `reviver` restores JSON-unfriendly values the\n * copying side encoded via `jsonReplacer` (typed arrays etc.);\n * `enabled: false` opts the canvas out — but note the kit handler\n * still consumes weasel-matching items at match time; on a disabled\n * canvas it declines inert (a dwarn, nothing ingested) rather than\n * falling through. Only items that never match (non-weasel text)\n * flow on to other handlers.\n * Memoize `handlers` (useState/useMemo/module const) — an inline array\n * literal re-registers the handlers on every render. The same applies\n * to `clipboard.reviver`: an inline function identity-churns the\n * memoized clipboard ctx each render (harmless but wasteful). */\n ingestion?: {\n handlers?: ContentHandlerEntry[];\n resolveSrc?: (file: File) => Promise<string>;\n svg?: SvgIngestOptions;\n clipboard?: {\n reviver?: (key: string, value: unknown) => unknown;\n enabled?: boolean;\n };\n };\n\n // --- Selection ---\n selection?: SelectionApi;\n selectionOptions?: UseSelectionOptions;\n\n /**\n * `false` stops the canvas writing the selection: no click, marquee,\n * lasso, action or tool, and no op committed through the adapter it hands\n * its tools. The consumer's own `SelectionApi` — the `selection` prop, or\n * `useSelection({ scene })` — still writes, and the canvas draws what it\n * holds. Undo and redo still restore the selection each history entry\n * recorded. Default `true`.\n *\n * Click policy (whether shift-click extends) is the selection's `mode`:\n * `useSelection({ mode: 'multi' })`, or `selectionOptions={{ mode: 'multi' }}`\n * for the selection the canvas builds itself.\n */\n selectable?: boolean;\n\n /**\n * Behavior presets to turn on, composable in any combination. A canvas\n * with none renders its scene and keeps a selection (the `selection` API\n * works) that no input sets: no tools, no standard actions or their keys,\n * no clipboard, no drop or paste, and no selection chrome. The dispatcher\n * is still mounted, so bindings a consumer adds work.\n *\n * - `view` — wheel pan and zoom, pinch, the zoom keys, and the hand tool\n * (H, or hold Space). Passing `viewport` implies it.\n * - `pick` — the select tool, as the initial active tool and Escape's\n * return target: click to pick, drag on empty to marquee, click on empty\n * to clear; and the selection outline.\n * - `move` — drag a body to move it, Alt-drag to clone it. Ambient, so it\n * runs under any tool that does not claim the drag.\n * - `transform` — resize and rotation handles, drawn and bound.\n * - `edit` — undo/redo, delete, duplicate, group/ungroup, nudge,\n * select-all, Escape, cancel-gesture, cut/copy/paste, fill and stroke,\n * and their keys.\n * - `arrange` — align, distribute, reorder, flip.\n * - `paths` — pathfinder operations, path-edit entry and anchor editing.\n * - `ingest` — dropped and pasted content (Cmd/Ctrl+V arrives as a paste).\n * - `draw` — all of the above.\n *\n * Tools add the actions they bind — a shape tool brings `insert` — so\n * `defaultTools` composes with any preset. `actions` then adds, overrides\n * or removes on top of what the presets registered.\n */\n features?: readonly Feature[];\n\n // --- Tools: extend, override, or take over ---\n /** Extra tools or overrides keyed by id, or a full `ToolsApi` takeover.\n *\n * **Patch form** (`Record<string, AnyTool | true | false>`): merged\n * into the built-in registry on top of whatever `defaultTools` and\n * `features` already selected.\n * - `true` pulls in the built-in for this id (`'pen'`, `'lasso'`,\n * `'hand'`, …), the same as listing it in `defaultTools`. Unknown\n * built-in ids warn in dev and are ignored.\n * - `AnyTool` adds a new id or replaces an existing one\n * (dev-only warning on replace).\n * - `false` omits a bundled tool entirely.\n * Auto-wiring (keybindings, dispatcher, action registry) still runs.\n *\n * **Takeover form** (`ToolsApi`): the internal registry is bypassed and\n * this `tools` value is forwarded to Canvas as-is — the consumer owns\n * active-slot management, and `pick`'s select tool is theirs to supply.\n * Every other preset still applies. Keybindings are still auto-wired\n * against the supplied registry; pass `enableKeybindings={false}` to opt\n * out. */\n tools?: ToolsApi | Record<string, AnyTool | true | false>;\n\n /**\n * Auto-wire keyboard shortcuts. Default `true`. When `false`, SceneCanvas\n * still mounts its tools but routes no keyboard input to them: it neither\n * subscribes the legacy `useKeybindings` hook (tool hotkeys) nor lets the\n * gesture dispatcher attach its `keydown`/`keyup` listeners (modern\n * keyboard-bound actions like delete / escape / nudge). Pointer, wheel, and\n * contextmenu interactions are unaffected. Leaves the consumer free to call\n * `useKeybindings(tools, { ... })` themselves (e.g. with `disable`,\n * `overrides`, or `defaultTool`).\n */\n enableKeybindings?: boolean;\n\n /**\n * Auto-mount the gesture dispatcher (`useGestureDispatcher`) inside\n * `<SceneCanvas>`. Default `true`. When `false`, the dispatcher is not\n * wired — useful in tests or demos that drive actions through alternative\n * mechanisms, or that want to call `useGestureDispatcher` themselves.\n *\n * The dispatcher reads registered actions' `defaultBinding` fields and\n * routes matching window keydown / canvas pointer / wheel events to the\n * corresponding `invoker.run` (or `invoker.start` for ongoing gestures).\n */\n enableGestureDispatcher?: boolean;\n\n /**\n * Called once after SceneCanvas constructs (or receives) its\n * `ToolsApi`. Useful for introspection — e.g. the toolkit-builder\n * dev surface walks `tools.registry` to render the live route table.\n * Fires with the consumer-supplied `tools` prop when present, or with\n * the internally-synthesized one otherwise.\n */\n onToolsCreated?: (tools: ToolsApi) => void;\n\n /**\n * Built-in tools SceneCanvas registers in its internal `useTools`, on top\n * of the ones presets bring (`select` from `pick`, `hand` from `view`).\n * Default: none. Each tool also registers the kit actions it binds, so\n * `['rect']` brings `insert`. Ignored when the consumer supplies their own\n * `tools` prop.\n */\n defaultTools?: readonly BuiltinToolId[];\n\n /** Per-tool option overrides for the built-in shape/lasso/clone tools.\n * Each entry is a narrow subset of the underlying hook's options\n * surface — `lasso.mode`, `clone.cloneSelection`, etc. */\n toolOptions?: BuiltinToolOptions;\n\n /** Initial active-slot tool id. Default: `'select'` when it is\n * registered, otherwise none — a canvas can run on ambient bindings\n * alone. Must be one of the registered tools. The lasso demo starts with\n * `initialActiveTool=\"lasso\"`. Ignored when the consumer supplies their\n * own `tools` prop. */\n initialActiveTool?: string;\n\n /** Always-on entries to register alongside the internal tools — every one\n * a `SurfaceContribution`, whose views, deps, overlay, bindings, actions\n * and `attach` all install from this one list, and uninstall when the\n * entry leaves it. A tool is a contribution too, so one can go here. If\n * you supply your own `tools` prop, this is ignored — wire `ambient`\n * through your own `useTools` call instead. */\n ambient?: readonly SurfaceContribution[];\n\n /** What an entry's `requires` does when the running kit does not meet\n * it: `'warn'` (the default) logs in development, `'strict'` throws,\n * `'off'` skips the check. */\n versionCheck?: VersionCheck;\n\n /** Touch and pen long-press: its hold time, its haptic, and the\n * feedback shown while it is held. */\n longPress?: SceneCanvasLongPress;\n\n /** Configures the `view` preset, and implies it: passing this turns\n * `view` on.\n *\n * - `inertia` and `animatedZoom` are opt-in: pass `true` for defaults or\n * an object to tune. Omitted means off.\n * - `pan` (wheel pan), `zoom` (Cmd+wheel + Cmd+=/-/0) and `pinchZoom`\n * (two-finger pinch) are on under `view`; pass `false` to disable one.\n * All three are wired by registering the kit's `viewport.*` action\n * descriptors with the actions registry — disabling via the `actions`\n * prop (`actions: { 'viewport.wheelPan': null }`) also works and runs\n * after this.\n *\n * Without `view`, none of them are wired. */\n viewport?: {\n inertia?: boolean | { friction?: number; minSpeed?: number; boundary?: 'stop' | 'bounce' | 'spring'; bounds?: PanBounds };\n /** Two-finger pinch zoom. `true`/omitted = on with the kit's 0.1–8\n * clamp; `false` disables. An object sets the scale clamp. */\n pinchZoom?: boolean | PinchZoomOptions;\n /** Glide Cmd+=/-/0 instead of jumping. `true` uses the kit defaults\n * (250 ms, ease-out-cubic); a {@link ViewportZoomAnimateOptions} tunes\n * duration, easing, interpolator and the reset-branch duration. Wheel\n * and pinch are unaffected — their input already samples every frame. */\n animatedZoom?: boolean | ViewportZoomAnimateOptions;\n /** Wheel pan. `true`/omitted = on; `false` disables; an object locks the\n * axis (`{ axis: 'x' }`) so a single-axis viewport needs no commit clamp. */\n pan?: boolean | WheelPanOptions;\n /** Wheel/keyboard zoom. `true`/omitted = default Cmd+wheel zoom with the\n * kit's 0.1–8 clamp; `false` disables. Pass a {@link ViewportZoomOptions}\n * object to bind zoom to plain wheel (`wheel: 'plain'`, pair with\n * `pan: false`) and/or set `min`/`max` scale clamps. */\n zoom?: boolean | ViewportZoomOptions;\n /** Callback invoked by Cmd-0 (`viewport.zoom` action's `reset` branch).\n * When supplied, replaces the default reset-to-identity behavior —\n * consumers typically refit the document page into the workspace via\n * `fitViewToBounds`. Return the target `View` to let the kit animate\n * there when `animatedZoom` is on; return nothing to dispatch it\n * yourself, which is what a controlled canvas does. */\n recenter?: () => View | void;\n };\n\n /**\n * @experimental\n * Override / disable / extend the default action set. Resolution rules:\n * see `docs/superpowers/specs/2026-05-09-actions-registry-design.md` §D.\n * Pass `null` to disable all defaults.\n */\n actions?: ActionsProp;\n\n /**\n * @experimental\n * Inputs the kit can't synthesize on its own — currently `cloneNode`\n * for the `duplicate` default. When omitted, the `duplicate` default is\n * silently dropped from the registered set.\n */\n /** @deprecated unused after legacy-bridge removal; will be deleted */\n actionDefaults?: {\n cloneNode?: (id: NodeId, offset: { dx: number; dy: number }) => { id: NodeId };\n /** Per-clone offset for the duplicate default. Default {dx:8,dy:8}. */\n duplicateOffset?: { dx: number; dy: number };\n /** Base nudge step. Default 1. */\n nudgeStep?: number;\n /** Shifted nudge step. Default 10. */\n nudgeShiftStep?: number;\n };\n\n /**\n * @experimental\n * Optional resolver: given a scene node, return a short human-readable\n * \"kind\" label (e.g. `'rectangle'`, `'path'`, `'sticky note'`). When\n * supplied, the kit publishes per-id kinds into any surrounding\n * `<SelectionContextProvider>` so non-canvas UI (palette, status bar)\n * can render type-aware copy. Return `undefined` to skip an entry.\n *\n * Default behavior when omitted: containers report `'group'`, paths\n * (poses with a `kind` property) report `'path'`, everything else is\n * left unlabelled.\n */\n describeKind?: (node: Node<TData, TLayer, TPose>) => string | undefined;\n\n /**\n * Optional animator to bind for per-frame redraws. When supplied,\n * SceneCanvas subscribes to `animator.onTick` and requests a redraw on\n * every active animation frame, and paints `animator.colorOverrides`\n * onto the scene's nodes: the kit's path and shape painters apply them,\n * and a custom `drawOne` receives them as `ctx.vertexColors`. Scene\n * mutations trigger repaints automatically, but `colorOverrides` writes\n * do not.\n *\n * Omit when no animation channel touches the render pipeline; idle\n * frames don't cost anything if no animations are active (the animator's\n * subscriber list stays quiet).\n */\n animator?: Animator;\n\n /**\n * Extra views on this canvas: each is a camera over a rect of the same\n * surface, drawn through one GL context, with input routed to it. The flat\n * `view` / `onViewChange` props above stay the canvas's own camera — view\n * zero — and are unaffected by anything declared here.\n *\n * Order is paint and hit order, low to high. Each entry is a\n * `<CanvasView>`; mounting one as a child is the same declaration, and\n * children land after every entry here.\n */\n views?: readonly CanvasViewProps[];\n\n /**\n * Children rendered alongside the canvas, inside its input scope (e.g.\n * shortcuts overlays, probes).\n */\n children?: ReactNode;\n\n /**\n * A yoke to join, from `useYoke()`: canvases on one yoke share the\n * active tool, the gesture in flight and history. Omitted, this canvas\n * keeps its own.\n */\n yoke?: Yoke;\n\n /**\n * Chrome-caps visibility overrides, keyed by chrome id (`selection.outline`,\n * `selection.rotation-handle`, `gesture.marquee`, …). Each entry is a\n * composable {@link Condition} built from the\n * `cond()` builder. Merged on top of the kit's `defaultVisibilityRules`;\n * unspecified ids fall through to the defaults.\n *\n * Set an id to `never` to suppress a chrome element entirely (also\n * unhittable). Set to `always` to force-show. Mix `cond(...)` chains\n * (e.g. `selectionIs(1).and(focused).andNot(gesturing)`) for the in-\n * between cases.\n */\n chromeVisibility?: import('features/chrome-caps').VisibilityRules;\n\n /**\n * The app's mode registry (`createModeRegistry` in `@weasel-js/modes`).\n * The canvas reads the active mode from it to gate chrome, tool\n * activation and the dispatcher's eligibility filter, repaints when it\n * switches, and hands every registered mode to the dev-time route-conflict\n * check. Omitted, the canvas behaves as the kit's normal mode and nothing\n * revokes anchor editing.\n */\n modes?: ModeRegistry;\n\n /**\n * Override detected device facts. Merged over what `matchMedia` reports;\n * `targetScale` is re-derived from the merged `coarsePointer` unless you\n * override it explicitly.\n *\n * Reach for this in three cases: tests that need a coarse profile without\n * stubbing `matchMedia`, demos that want to show touch-sized chrome on a\n * desktop, and hybrid devices where the media query guesses wrong.\n */\n device?: Partial<DeviceProfile>;\n\n /**\n * Optional live focus getter for chrome-caps' `focused` ctx field.\n * SceneCanvas does not own focus state by default — wire this when\n * your visibility rules read the `focused` atom (e.g. the kit's\n * default `selection.rotation-handle` rule requires focus). Omit\n * to default `focused` to `true` (rule fires regardless of focus).\n */\n getFocused?: () => boolean;\n\n /**\n * Custom shader programs to compile on the renderer. Forwarded directly\n * to `<Canvas shaders={...} />`. See `CanvasProps.shaders` for details.\n */\n shaders?: ShaderProgramHandle[];\n\n /**\n * Flatness tolerance for curve tessellation, in world units. Forwarded\n * directly to `<Canvas flattenTolerance={...} />`. See\n * `CanvasProps.flattenTolerance` for details.\n */\n flattenTolerance?: number;\n\n /**\n * FillStyle applied to the full canvas behind the scene. Accepts the kit's\n * `FillStyle` union (solid / pattern / linear-gradient / radial-gradient /\n * conic-gradient) so consumers don't have to author a background node\n * just to colorize the canvas. Rendered as a screen-space layer slotted\n * before `'scene'` — independent of pan / zoom.\n */\n backgroundFill?: FillStyle;\n /**\n * Dev HUD: when true, mounts a fixed-position widget in the top-left\n * of the viewport showing live cursor coords in both viewport\n * (client) and canvas (world) frames. Useful for diagnosing pointer-\n * coord drift / pan-zoom misalignment without instrumenting events.\n */\n cursorCoordsHud?: boolean;\n /**\n * Dev HUD: when true, mounts a fixed-position widget just below the\n * cursor-coords HUD listing the ids returned by `pickEvery(world)`\n * under the cursor. Useful for diagnosing hit-test order and\n * container/leaf overlap during select-tool work.\n */\n pickHud?: boolean;\n /**\n * The debug overlay: `<Canvas debug>`'s config, plus `slops: true` for\n * translucent halos at every affordance hit zone. `false` turns it off;\n * absent reads `?debug=…` from the URL, as `<Canvas>` does.\n */\n debug?: (DebugConfig & { slops?: boolean }) | false;\n /**\n * Dev HUD: when true (or object), mounts a fixed-position widget below\n * the pick HUD showing the active modality mode, active-slot tool, and\n * hotkey stack. Pass `{ modeId }` to populate the mode line.\n */\n modalityHud?: boolean | { modeId?: string };\n\n /**\n * Optional per-id alpha multiplier for the scene-render slot. When\n * supplied, each node's draw output is wrapped in a `GroupDrawCommand`\n * with the returned alpha so the renderer applies the multiplier.\n * Values equal to 1 are a no-op (no wrapper emitted). Typical use:\n * scoping-dim integration dims non-active nodes during a mode transition.\n *\n * Defaults to `() => 1` (no effect).\n */\n alphaFor?: (id: string) => number;\n\n /**\n * Show or hide render layers in this canvas's own view, by id — the map\n * `<Canvas>` takes. Each scene layer paints as its own render layer, keyed\n * `scene:<layerId>`, so `{ 'scene:guides': false }` hides one scene layer\n * here and nowhere else.\n *\n * A layer hidden this way is gone from this view: it does not paint, and a\n * click, a marquee or Cmd+A here passes over it. Another view of the same\n * scene — a `<CanvasView>`, a second canvas, a minimap — still shows it and\n * can still take it. It applies on top of the scene's own\n * `LayerRecord.visible` and cannot show a layer the scene hides.\n */\n layerVisibility?: Record<string, boolean>;\n\n /**\n * Draw order for this view, by render-layer id, bottom first. A listed\n * order is the whole list: a scene layer left out of it is neither painted\n * nor picked here. See `CanvasProps.layerOrder`.\n */\n layerOrder?: string[];\n\n /**\n * Optional per-id pointer-interactivity predicate. When supplied, ids\n * for which the predicate returns `false` are excluded from hit-test\n * results — `getNodeAtPoint` returns null for those positions.\n * Typical use: scoping-dim integration suppresses pointer events for\n * non-active nodes during a mode transition.\n *\n * Defaults to `() => true` (all nodes are interactive).\n */\n isPointerInteractive?: (id: string) => boolean;\n\n /**\n * Called when the user double-clicks the canvas. Receives the hit node\n * (id + kind) at the double-click position, or `null` when the click\n * lands on empty canvas. Wired internally via a `dblclick` listener on\n * the canvas element so it doesn't interfere with the pointer-gesture\n * pipeline.\n *\n * Typical use: modality dispatch — enter path-edit on a path node,\n * isolation on a group, text-edit on a text node.\n */\n onDoubleClick?: (hit: SceneCanvasHit | null) => void;\n };\n\n/** Discriminate the polymorphic `tools` prop: `ToolsApi` has `setActive`\n * / `active` / `registry`; the patch record shape has none of those. */\n/** Stable empty `Set` so `getSuppressedSelectionIds` doesn't allocate\n * a fresh empty Set on every read — selection-overlay's `draw` runs\n * every frame. */\nconst EMPTY_ID_SET: ReadonlySet<string> = new Set();\nconst EMPTY_ANCHOR_SELECTION: ReadonlySet<number> = new Set();\n\nfunction isToolsApi(\n tools: ToolsApi | Record<string, AnyTool | true | false>,\n): tools is ToolsApi {\n return typeof (tools as ToolsApi).setActive === 'function';\n}\n\nfunction SceneCanvasInner<TData, TLayer extends string, TPose>(\n props: SceneCanvasProps<TData, TLayer, TPose>,\n ref: React.ForwardedRef<SceneCanvasApi>,\n) {\n const {\n scene: sceneInput,\n geometry,\n poseDescriptor,\n selectTool: selectToolOpts,\n insertTool,\n insertNodeFactories,\n ingestion,\n layouts,\n layoutDropTarget,\n reflowTransition,\n poseComposition,\n geometryProjection,\n routing,\n selection: selectionProp,\n selectionOptions,\n selectable = true,\n tools: toolsProp,\n features,\n enableKeybindings = true,\n enableGestureDispatcher = true,\n onToolsCreated,\n defaultTools,\n toolOptions,\n initialActiveTool,\n ambient,\n versionCheck,\n longPress,\n viewport,\n layers,\n actions,\n actionDefaults,\n describeKind,\n animator,\n views: viewDescriptors,\n children,\n shaders,\n flattenTolerance,\n backgroundFill,\n cursorCoordsHud,\n pickHud,\n debug,\n modalityHud,\n alphaFor,\n layerVisibility,\n layerOrder,\n isPointerInteractive,\n onDoubleClick,\n chromeVisibility,\n modes,\n getFocused: getFocusedProp,\n device,\n ...rest\n } = props;\n\n const descriptor = (poseDescriptor ?? AUTO_POSE_DESCRIPTOR) as PoseDescriptor<unknown>;\n\n // Resolved once here and provided to the subtree, so overlays, affordances\n // and consumer chrome all read the same object rather than each running\n // their own media queries.\n const deviceProfile = useDeviceProfile(device);\n\n // How big grabbable chrome is for this pointer type. Paint (the selection\n // overlay), hit-test (`buildAffordanceAt`) and the slops debug overlay all\n // resolve from this one object — a size read from the base constants\n // directly is unscaled, and a coarse pointer then paints chrome it cannot\n // grab.\n const chromeSizes = useMemo(\n () => targetSizesPx(deviceProfile.targetScale),\n [deviceProfile.targetScale],\n );\n\n // `scene` accepts either a live `Scene` or a `SerializedScene` JSON\n // object. JSON is baked once via useState init; subsequent renders\n // ignore prop changes (use a `key` prop on `<SceneCanvas>` to force a\n // fresh canvas).\n const isSerialized = (s: unknown): boolean =>\n typeof s === 'object' && s != null && (s as { version?: unknown }).version === 1\n && Array.isArray((s as { nodes?: unknown }).nodes);\n const [bakedScene] = useState<Scene<TData, TLayer, TPose> | null>(\n () => isSerialized(sceneInput)\n ? sceneFromJSON(sceneInput as SerializedScene<TData, TLayer, TPose>, {})\n : null,\n );\n const scene = bakedScene ?? (sceneInput as Scene<TData, TLayer, TPose>);\n\n // Extract view-related props from rest so we can intercept them for the\n // controlled/uncontrolled pattern Canvas exposes without breaking it.\n const { view: viewProp, onViewChange: onViewChangeProp, defaultView, redrawOn: redrawOnProp, ...restProps } = rest;\n const getActiveMode = useMemo(() => (modes ? getActiveModeFor(modes) : undefined), [modes]);\n const redrawOn = useMemo(\n () => (modes ? [...(redrawOnProp ?? []), modes] : redrawOnProp),\n [modes, redrawOnProp],\n );\n\n // Internal canvas ref so the dispatcher can attach its input listeners\n // even when the consumer passes their own forwarded ref.\n const internalCanvasRef = useRef<HTMLElement | null>(null);\n // Holds the full `CanvasExtensionApi` so we can call `requestRedraw` after\n // dispatcher-side gesture pumps. Without this, dispatcher-only actions\n // (marquee, lasso, anything driven solely by `useGestureDispatcher`) never\n // trigger a re-paint between pointerdown and pointerup — the legacy tools\n // dispatcher's `onGestureChange` only fires for legacy `tool.drag.*` hooks,\n // which the migrated actions don't provide.\n const canvasApiRef = useRef<CanvasExtensionApi | null>(null);\n // Set from the merged ref callback, so effects needing the handle key off it\n // instead of assuming when React attaches it.\n const [canvasReady, setCanvasReady] = useState(false);\n\n useEffect(() => {\n dlog('scene-canvas', 'mount');\n return () => dlog('scene-canvas', 'unmount');\n }, []);\n\n // Content-handler registration: the kit's defaults are refcounted (they\n // stay registered while ANY SceneCanvas is mounted — see\n // `acquireKitContentHandlers`); consumer handlers from the `ingestion`\n // prop live for this canvas's lifetime.\n const consumerHandlers = ingestion?.handlers;\n useEffect(() => {\n const disposers = [acquireKitContentHandlers()];\n for (const h of consumerHandlers ?? []) disposers.push(registerContentHandler(h));\n return () => disposers.forEach((d) => d());\n }, [consumerHandlers]);\n\n // Animator subscription: when an animator is provided, request a redraw\n // on every active frame so consumer `drawOne` functions reading\n // `animator.colorOverrides` (or any other non-scene channel the\n // animator may mutate) reflect the latest values. The animator only\n // ticks while animations are active, so idle frames don't repaint.\n useEffect(() => {\n if (!animator) return;\n const unsubscribe = animator.onTick(() => {\n canvasApiRef.current?.requestRedraw?.();\n });\n return unsubscribe;\n }, [animator]);\n\n // Late decodes, deferred glyph bakes and late paint kinds each drew nothing\n // on the frame that asked for them.\n useLateContentRedraw(useCallback(() => { canvasApiRef.current?.requestRedraw?.(); }, []));\n\n // Override writes deliberately don't bump the scene version — that fanout is\n // what a frame loop is trying to avoid — so the repaint has to come from\n // here instead.\n useEffect(() => scene.overrides.subscribe(() => {\n canvasApiRef.current?.requestRedraw?.();\n }), [scene]);\n\n // A scene write repaints; it does not re-render this component. The layers\n // read the scene at paint time and `contentVersion` is a getter, so nothing\n // here needs a commit to draw the new content. Chrome rendering node data as\n // DOM subscribes for itself — `useScene`'s default, `SelectionPanel`, the\n // panels an app hangs beside the canvas — which is what lets a host driving\n // poses from a frame loop take `useScene(…, { subscribe: false })` and\n // actually get it.\n useEffect(() => scene.subscribe(() => {\n canvasApiRef.current?.requestRedraw?.();\n }), [scene]);\n\n // The mirror every HUD, pick and pinch path reads synchronously. Seeded here\n // because those reads start before the canvas's subscription lands.\n const currentViewRef = useRef<View>(\n normalizeView(viewProp ?? defaultView ?? { x: 0, y: 0, scale: { x: 1, y: 1 } }),\n );\n // Committed renders only, so an abandoned transition's view never reaches\n // the `view` dep, picks or the camera animator.\n useInsertionEffect(() => {\n if (viewProp !== undefined) currentViewRef.current = normalizeView(viewProp);\n });\n\n useEffect(() => {\n const api = canvasApiRef.current;\n if (!api) return;\n currentViewRef.current = api.getView();\n return api.subscribeView((v) => { currentViewRef.current = v; });\n }, [canvasReady]);\n\n // The dep registry's `view.set`. Uncontrolled it must not also call\n // `onViewChangeProp` — the canvas reports the write through `notifyViewChange`.\n const handleViewChange = useCallback((v: View) => {\n const api = canvasApiRef.current;\n if (viewProp === undefined && api) { api.setView(v); return; }\n onViewChangeProp?.(normalizeView(v));\n }, [viewProp, onViewChangeProp]);\n\n // The camera runs on its own animator, never the `animator` prop's: that prop\n // is the consumer's scene animator, and their `cancelAll()` or `pause()` must\n // not strand a zoom half-finished or freeze the camera.\n const cameraAnimator = useAnimator();\n const viewChannel = useMemo(\n () => ({ get: () => currentViewRef.current, set: handleViewChange }),\n [handleViewChange],\n );\n const viewAnimation = useViewAnimationOn(viewChannel, cameraAnimator);\n\n // Never writes back to the canvas — `handleViewChange` would recurse. Every\n // `Canvas.setView` lands here on both branches, so it is also the runner's\n // one interrupt feed.\n const notifyViewChange = useCallback((v: View) => {\n viewAnimation.stopIfExternal();\n onViewChangeProp?.(v);\n }, [onViewChangeProp, viewAnimation]);\n\n // `animatedZoom` is the SceneCanvas-level spelling of the zoom action's\n // `animate` option, the way `pinchZoom` is of the pinch tool's clamp.\n const animatedZoom = viewport?.animatedZoom;\n const viewportZoomProp = viewport?.zoom ?? true;\n const resolvedViewportZoom = useMemo<boolean | ViewportZoomOptions>(() => {\n if (viewportZoomProp === false) return false;\n const base = typeof viewportZoomProp === 'object' ? viewportZoomProp : {};\n if (!animatedZoom) return base;\n return { ...base, animate: animatedZoom === true ? {} : animatedZoom };\n }, [viewportZoomProp, animatedZoom]);\n\n // Selection: caller-supplied wins; otherwise build from selectionOptions.\n // Hooks always run unconditionally — when a caller supplies `selection`,\n // the internally-built one is unused but the hook still fires.\n // Bound to the scene, so the selection an edit was made under rides on the\n // scene's history entries and undo can put it back.\n const derivedSelectionOptions = useMemo<UseSelectionOptions>(\n () => ({ scene, ...(selectionOptions ?? {}) }),\n [scene, selectionOptions],\n );\n const internalSelection = useSelection(derivedSelectionOptions);\n const baseSelection = selectionProp ?? internalSelection;\n\n // Everything the kit writes selection through — the `selection` dep, the\n // adapter's `setSelection`, ops committed through either — reads this api,\n // so on an unselectable canvas every write path here is closed. The\n // consumer's own api is not wrapped and still writes.\n const baseAdapterMethods = baseSelection.adapterMethods;\n const readOnlyAdapterMethods = useMemo(() => ({\n getSelection: () => baseAdapterMethods.getSelection(),\n setSelection: () => {},\n }), [baseAdapterMethods]);\n const selection: SelectionApi = useMemo(() => {\n if (selectable) return baseSelection;\n const noopSet = () => {};\n return {\n get current() { return baseSelection.current; },\n get: baseSelection.get,\n contains: baseSelection.contains,\n set: noopSet,\n add: noopSet,\n remove: noopSet,\n toggle: noopSet,\n clear: noopSet,\n applyClick: noopSet,\n adapterMethods: readOnlyAdapterMethods,\n };\n }, [baseSelection, selectable, readOnlyAdapterMethods]);\n\n // Publish the current selection (with optional per-id kind labels) into any\n // surrounding `<SelectionContextProvider>` so non-canvas UI can read it.\n // No-op when no provider is in scope.\n const currentSelection = selection.current;\n const selectionKinds = useMemo<readonly (string | undefined)[] | undefined>(() => {\n if (currentSelection.length === 0) return undefined;\n const out: (string | undefined)[] = [];\n for (const id of currentSelection) {\n const node = scene.get(id);\n if (!node) { out.push(undefined); continue; }\n if (describeKind) { out.push(describeKind(node)); continue; }\n // Default heuristic: containers -> 'group', poses with .kind -> 'path',\n // everything else unlabelled (consumer can supply describeKind to fill in).\n if (node.kind === 'container') { out.push('group'); continue; }\n const pose = node.pose as unknown as { kind?: unknown } | null;\n if (pose && typeof pose === 'object' && 'kind' in pose && typeof pose.kind === 'string') {\n out.push('path');\n continue;\n }\n out.push(undefined);\n }\n return out;\n }, [currentSelection, scene, describeKind]);\n usePublishSelection(currentSelection, selectionKinds);\n\n // Path-editing edit-mode state. Owned here so it's reachable from both:\n // - the `pathEditingOverlay` chrome layer wired below\n // - `useEditAnchorsDepSource`, mounted in the child StandardActionsRegistrar\n // The state stays empty until `enterPathEditAction` (double-click on a\n // selected polygon) sets it, and clears on `exitPathEditAction` (Escape).\n // Until then, the chrome doesn't draw and the gesture doesn't route to\n // `editAnchorsAction` — both gate on `editingId !== ''`.\n const [pathEditingId, setPathEditingId] = useState<string>('');\n const pathEditingIdRef = useLatest(pathEditingId);\n // `anchorEditingAllowed` is declared below (it needs `getActiveModeRef`);\n // hold it in a ref so `effectivePathEditingId` — used by consumers\n // declared both above and below that point — can read it lazily.\n const anchorEditingAllowedRef = useRef<(() => boolean) | undefined>(undefined);\n /**\n * The edit target, masked by whether the host still permits anchor\n * editing.\n *\n * Every surface that cares — the overlay layer, the `editingAnchors`\n * rule input, the selection-overlay suppression set, the select tool's\n * extend-click lock — reads this rather than the raw state. Leaving\n * path-edit mode therefore tears all of them down at once, by any route.\n * That matters because `exitPathEditAction` is not the only way out:\n * `apps/draw` handles Escape in a capture-phase listener and calls\n * `stopPropagation()`, so the dispatcher never sees the key, and before\n * this the raw id stayed set — inert anchor squares kept drawing over\n * the shape and the selection outline stayed suppressed.\n *\n * Masking rather than clearing on purpose: the mode can change without\n * re-rendering this component, so there is no reliable moment to write\n * state. Read-time masking cannot go stale.\n */\n const effectivePathEditingId = useCallback((): string => {\n const allowed = anchorEditingAllowedRef.current;\n if (allowed && !allowed()) return '';\n return pathEditingIdRef.current;\n }, [pathEditingIdRef]);\n // Anchor selection + in-flight marquee. Both are per-frame inputs to\n // the overlay's draw(), never to a React render, so they live in refs\n // and request a repaint directly. Holding them in state would re-render\n // the whole SceneCanvas subtree on every pointermove of a marquee drag.\n const selectedAnchorsRef = useRef<ReadonlySet<number>>(EMPTY_ANCHOR_SELECTION);\n const anchorMarqueeRef = useRef<{ x: number; y: number; width: number; height: number } | null>(null);\n const editAnchorsExternalState = useMemo(() => ({\n getEditingId: () => effectivePathEditingId(),\n setEditingId: (id: string | null) => setPathEditingId(id ?? ''),\n getSelectedAnchors: () => selectedAnchorsRef.current,\n setSelectedAnchors: (next: ReadonlySet<number>) => {\n selectedAnchorsRef.current = next;\n canvasApiRef.current?.requestRedraw?.();\n },\n getMarquee: () => anchorMarqueeRef.current,\n setMarquee: (rect: { x: number; y: number; width: number; height: number } | null) => {\n anchorMarqueeRef.current = rect;\n canvasApiRef.current?.requestRedraw?.();\n },\n }), [effectivePathEditingId]);\n\n // Apply the handle-size fallback here so useSceneSelectTool always receives\n // a concrete radius even when the caller omits selectTool entirely.\n const selectToolWithDefaults = useMemo(() => ({\n handleHitRadius: chromeSizes.handle,\n // Shift-click belongs to the anchor selection while a path is being\n // anchor-edited; see `UseSelectToolOptions.extendClickLocked`.\n extendClickLocked: () => effectivePathEditingId() !== '',\n // `selectionAllowed` used to sit here, hand-checking the active mode for\n // `creates-selection` because the tool's pointerDown classifier was a\n // phase-table route and `Action.eligible` was never evaluated on that\n // pipeline (audit 3.4). The classifier is now `select.pick`, which\n // declares that capability itself — one rule, evaluated in one place.\n ...selectToolOpts,\n }), [selectToolOpts, chromeSizes.handle, effectivePathEditingId]);\n\n // Stable ref to the live selection; updated every render so the affordanceAt\n // and classifyTarget thunks (which live in an effect closure) always read\n // the latest selection without causing re-renders.\n const selectionRef = useLatest(selection);\n\n // Build a per-instance NodeRouting registry. When `routing` is unset, fall\n // back to `inferredNodeRouting` (data-shape inference: `data.text` →\n // `'text'`, `data.path` → `'path'`, `data.image` → `'image'`). Pass an\n // explicit `routing={[]}` to opt out entirely — the classifier becomes\n // undefined and every hit comes back as `kind: 'unknown'`.\n const kindClassifier = useMemo(() => {\n const effective = routing === undefined ? inferredNodeRouting : routing;\n if (effective.length === 0) return undefined;\n const registry = createNodeRouting();\n for (const k of effective) registry.register(k);\n return (data: TData) => registry.classify(data);\n }, [routing]);\n\n // Node id → routing-trait kind, for the body classifier. Reusing the routing\n // registry here is what makes `target: 'kind:text'` on a binding speak the\n // same vocabulary as `Hit.kind` and the routing tables, rather than a second\n // one invented for bindings. Undefined when `routing={[]}` opts out, which\n // leaves every `kind:` target form unmatchable.\n const kindOfNode = useMemo(() => {\n if (!kindClassifier) return undefined;\n return (id: string): string | undefined => {\n const node = scene.get(id as NodeId);\n return node ? kindClassifier(node.data) : undefined;\n };\n }, [kindClassifier, scene]);\n\n // The painted alpha of a node in this view: the caller's `alphaFor`\n // (scoping-dim, and anything else a consumer fades) times any per-node\n // override alpha. `<Canvas>` has no scene, so the override half is folded\n // in here — and the pick path reads the same number the painter does, or a\n // node faded to nothing stays clickable.\n const composedAlphaFor = useMemo(\n () => composeAlphaFor(scene, alphaFor),\n [scene, alphaFor],\n );\n\n // What this view paints of each scene layer, judged against the stack\n // `<Canvas>` composed and read at pick time — so a consumer slot anchored\n // between scene layers is weighed the way paint weighs it.\n const surfaceViewRegistry = useOptionalViewRegistry();\n const layerPaintRef = useLatest<ViewLayerPaint>({ layerVisibility, layerOrder });\n const [sceneLayerGate] = useState(createSceneLayerGate);\n const layerIsPainted = useCallback((layerId: string): boolean => (\n sceneLayerGate(surfaceViewRegistry?.surface()?.layers() ?? [], layerPaintRef.current)(layerId)\n ), [surfaceViewRegistry, sceneLayerGate, layerPaintRef]);\n // Absent when this view hides nothing, so the walk skips the gate.\n const viewLayerGate = layerVisibility !== undefined || layerOrder !== undefined\n ? layerIsPainted\n : undefined;\n\n // Under a frame a child's pose is already relative, so cascading a container\n // move would carry every descendant a second time.\n const framed = poseComposition !== undefined && poseComposition.closure !== 'identity';\n const adapter = useSceneAdapter(scene, {\n // `adapterMethods` is memoized; `selection` itself is a fresh object each render.\n selection: selection.adapterMethods,\n poseDescriptor: descriptor as PoseDescriptor<TPose>,\n commitInsert: insertTool?.create,\n insertLayer: insertTool?.layer,\n layouts,\n poseComposition,\n cascadeContainerPose: !framed,\n });\n\n const {\n selectTool: internalSelect, pickEvery: internalPickEvery, pickBest: internalPickBest,\n boundsOf: internalBoundsOf, boundsOfPose: internalBoundsOfPose, planeOfNode: internalPlaneOfNode,\n moveOptions: internalMoveOptions,\n } = useSceneSelectTool({\n scene,\n adapter,\n poseDescriptor: descriptor as PoseDescriptor<TPose>,\n geometry,\n // The pick tolerance is declared in screen pixels; this is what converts it.\n getView: () => currentViewRef.current,\n // Only when the consumer actually fades something. Without a prop the\n // composed function is just the override lookup, and the source resolves\n // that once per walk instead of once per candidate.\n ...(alphaFor ? { alphaOf: composedAlphaFor } : {}),\n ...(viewLayerGate ? { layerIsPainted: viewLayerGate } : {}),\n selectTool: selectToolWithDefaults,\n });\n // Read through a ref by the chrome layers, which are built once.\n const planeOfNodeRef = useLatest(internalPlaneOfNode);\n\n // Build getNodeAtPoint from the adapter + internalPickEvery. Canvas no longer\n // synthesizes this itself — it accepts it as a prop (seam refactor).\n // The node resolver classifies each hit's `data` directly via kindClassifier\n // (the registry-backed kind function), plus getPose and getNode, matching the\n // old Canvas synthesizer algorithm (see src/canvas/getNodeAtPoint.ts).\n //\n // When isPointerInteractive is supplied, the result is filtered: ids for\n // which the predicate returns false cause getNodeAtPoint to return null,\n // suppressing pointer events for non-interactive nodes (e.g. scoping-dim).\n const getNodeAtPoint = useMemo(() => {\n if (!internalPickEvery) return undefined;\n const nodeResolver = (id: string) => {\n const node = adapter.getNode(id);\n const kind = node && kindClassifier ? kindClassifier(node.data) : 'unknown';\n const pose = adapter.getWorldPose(id);\n const data = node ?? { id };\n return { kind, pose, data };\n };\n const base = makeGetNodeAtPoint(internalPickEvery, nodeResolver);\n if (!isPointerInteractive) return base;\n return (wx: number, wy: number, view?: PickView | null) => {\n const hit = base(wx, wy, view);\n if (hit == null) return null;\n if (isPointerInteractive(hit.id) === false) return null;\n return hit;\n };\n }, [adapter, internalPickEvery, isPointerInteractive, kindClassifier]);\n\n // The presets this canvas runs with. Keyed on the ids, not the array, so an\n // inline `features={['draw']}` does not re-derive every render.\n const featuresKey = (features ?? []).join('|');\n const hasViewport = viewport !== undefined;\n const enabled = useMemo(\n () => resolveFeatures(features, { viewport: hasViewport }),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [featuresKey, hasViewport],\n );\n\n const inertiaEnabled = !!viewport?.inertia;\n const inertiaObj = typeof viewport?.inertia === 'object' ? viewport.inertia : undefined;\n // `inertia: true` means \"on with kit defaults\", so an enabled-but-objectless\n // config still has to reach the tool — an empty object, not `undefined`,\n // which the tool reads as off.\n const handToolInertia = inertiaEnabled\n ? {\n friction: inertiaObj?.friction,\n minSpeed: inertiaObj?.minSpeed,\n boundary: inertiaObj?.boundary,\n bounds: inertiaObj?.bounds,\n }\n : undefined;\n // useHandTool must always be called (rules of hooks); it is a no-op when\n // viewport is absent — the tool is simply not added to the registry.\n const handTool = useHandTool(handToolInertia ? { inertia: handToolInertia } : {});\n\n // Built-ins to mount: what `defaultTools` lists, plus the tool each preset\n // brings — `pick` the select tool, `view` the hand.\n const baseRequestedTools: readonly BuiltinToolId[] = [\n ...(defaultTools ?? []),\n ...(enabled.has('pick') ? ['select' as const] : []),\n ...(enabled.has('view') ? ['hand' as const] : []),\n ];\n\n // Patch-form `tools` extras with value `true` widen the requested set\n // (\"pull in this built-in\"). Computed here so the rest of the if-ladder\n // treats them identically to ids that came in via `defaultTools`.\n const KNOWN_BUILTIN_IDS: ReadonlySet<BuiltinToolId> = new Set<BuiltinToolId>([\n ...NON_SHAPE_BUILTIN_TOOLS, ...KIT_SHAPE_KINDS,\n ]);\n const toolsPatchExtras = (() => {\n if (!toolsProp || isToolsApi(toolsProp)) return null;\n return toolsProp;\n })();\n const trueIds = new Set<BuiltinToolId>();\n if (toolsPatchExtras) {\n for (const [id, value] of Object.entries(toolsPatchExtras)) {\n if (value !== true) continue;\n if (!KNOWN_BUILTIN_IDS.has(id as BuiltinToolId)) {\n if (IS_DEV) {\n console.warn(`[SceneCanvas] tools.${id}=true is not a known built-in id; ignoring`);\n }\n continue;\n }\n trueIds.add(id as BuiltinToolId);\n }\n }\n const wants = (id: BuiltinToolId): boolean =>\n baseRequestedTools.includes(id) || trueIds.has(id);\n\n // Synthesize the shape/lasso/text/clone tools — always called per React\n // rules-of-hooks; only registered below when requested. Per-tool options\n // (lasso mode, clone-selection) thread through `toolOptions`.\n const shapeTools = useBuiltinShapeTools({ scene, adapter, options: toolOptions });\n\n const defaultLongPressFeedback = useMemo(() => createLongPressFeedbackContribution(), []);\n const feedbackOpt = longPress?.feedback ?? true;\n const pressFeedback = feedbackOpt === true ? defaultLongPressFeedback : feedbackOpt || null;\n const mergedAmbient = useMemo(\n () => (pressFeedback ? [...(ambient ?? []), pressFeedback] : (ambient ?? [])),\n [ambient, pressFeedback],\n );\n\n const internalRegistry: Record<string, AnyTool> = {};\n if (wants('select')) internalRegistry.select = internalSelect;\n // `hand` stays in the registry (not ambient) so its H keybinding and its\n // Space hold both apply.\n if (wants('hand')) internalRegistry.hand = handTool;\n // Shape / lasso / text tools — registry entries with built-in\n // keybindings (R/E/G/N/L/T) routed via `useKeybindings`.\n if (wants('rect')) internalRegistry.rect = shapeTools.rect;\n if (wants('ellipse')) internalRegistry.ellipse = shapeTools.ellipse;\n if (wants('line')) internalRegistry.line = shapeTools.line;\n if (wants('polygon')) internalRegistry.polygon = shapeTools.polygon;\n if (wants('star')) internalRegistry.star = shapeTools.star;\n if (wants('pen')) internalRegistry.pen = shapeTools.pen;\n if (wants('pencil')) internalRegistry.pencil = shapeTools.pencil;\n if (wants('lasso')) internalRegistry.lasso = shapeTools.lasso;\n if (wants('text')) internalRegistry.text = shapeTools.text;\n\n // Patch-form `tools` prop: merge extras / overrides / omissions into the\n // internal registry. `false` drops a bundled tool; `true` is already\n // accounted for above via the `wants()` expansion; `AnyTool` adds or\n // replaces (dev-only warning on replace). Takeover form (full `ToolsApi`)\n // is handled below via `toolsProp ?? internalTools`.\n const toolsPatch = toolsPatchExtras;\n if (toolsPatch) {\n for (const [id, value] of Object.entries(toolsPatch)) {\n if (value === false) {\n delete internalRegistry[id];\n } else if (value === true) {\n // Already pulled in via the `wants()`-driven if-ladder above.\n continue;\n } else {\n if (IS_DEV && id in internalRegistry) {\n console.warn(`[SceneCanvas] tools prop overrides bundled \"${id}\" tool`);\n }\n internalRegistry[id] = value;\n }\n }\n }\n\n // Takeover form: only when toolsProp is the full ToolsApi shape.\n const toolsTakeover = toolsProp && isToolsApi(toolsProp) ? toolsProp : null;\n\n const internalTools = useTools({\n active: initialActiveTool ?? ('select' in internalRegistry ? 'select' : null),\n registry: internalRegistry,\n ...(mergedAmbient.length ? { ambient: mergedAmbient } : {}),\n ...(modes ? { modes } : {}),\n });\n\n // Auto-wire keybindings against whichever registry is live.\n //\n // Both calls fire unconditionally (rules of hooks); the inactive one is\n // silenced via the hook's own `disable` option:\n // - internal registry: disabled whenever the consumer passed `tools=`.\n // - consumer registry: disabled when `tools=` was omitted (nothing to\n // bind) or when the consumer opted out via `enableKeybindings={false}`.\n //\n // The `enableKeybindings` opt-out also silences the internal wiring, so\n // a consumer relying entirely on the internal tools can take over with\n // their own `useKeybindings(...)` call. The fallback `useTools` passed\n // to the second call when `toolsProp` is absent is a render-stable empty\n // stand-in just to keep the call site valid; it never actually fires\n // because `disable` is true on that branch.\n const liveToolsRef = useLatest<ToolsApi | null>(toolsTakeover ?? internalTools);\n const getActiveModeRef = useLatest(getActiveMode);\n //\n // `isToolEligible` mirrors `eligibleForMode` (packages/modes) — the same\n // predicate `ToolPalette` uses to grey a button out. Without a mode\n // registry every tool stays activatable.\n const isToolEligible = useCallback((toolId: string): boolean => {\n const getMode = getActiveModeRef.current;\n if (!getMode) return true;\n const registry = liveToolsRef.current?.registry;\n const caps = registry?.[toolId]?.eligibility.capabilities ?? [];\n if (caps.length === 0) return false;\n const allowed = getMode().allowedCapabilities;\n for (const c of caps) if (allowed.has(c)) return true;\n return false;\n }, [getActiveModeRef, liveToolsRef]);\n\n\n const tools = toolsTakeover ?? internalTools;\n\n // The selection's own ambient bindings: `move` and `transform`. They are\n // not tools and sit outside `tools`, so they apply under a takeover too.\n const selectionMoveOptions = useMemo(\n () => ({ move: internalMoveOptions }),\n [internalMoveOptions],\n );\n const rotateOptions = selectToolOpts?.rotate || undefined;\n // Transform first: a handle sits over the selected body, so the move\n // binding matches a handle drag too, and a tie goes to whichever is first.\n const featureContributions = useMemo<Contribution[]>(() => [\n ...(enabled.has('transform') ? [selectionTransformContribution({ rotate: rotateOptions })] : []),\n ...(enabled.has('move') ? [selectionMoveContribution(selectionMoveOptions)] : []),\n ], [enabled, selectionMoveOptions, rotateOptions]);\n\n // Kit-standard actions to register: every preset's own, plus whichever a\n // tool or contribution on this canvas binds — a tool brings the actions it\n // routes to, so `defaultTools={['rect']}` works under any preset.\n const standardActionsExclude = useMemo(() => {\n const include = featureActionIds(enabled);\n const bound = [\n ...Object.values(tools.registry),\n ...tools.ambient,\n ...featureContributions,\n ];\n for (const entry of bound) {\n for (const b of entry.bindings ?? []) include.add(b.actionId);\n }\n return KIT_STANDARD_ACTION_IDS.filter((id) => !include.has(id));\n }, [enabled, tools, featureContributions]);\n\n // Surface the resolved ToolsApi to the introspection callback (the\n // toolkit-builder dev surface uses this to walk `tools.registry` for\n // its live route table). Fires whenever the `tools` identity changes,\n // which is stable across most renders thanks to useTools' useMemo.\n const onToolsCreatedRef = useLatest(onToolsCreated);\n useEffect(() => { onToolsCreatedRef.current?.(tools); }, [tools, onToolsCreatedRef]);\n\n // `onDoubleClick` used to be backed by a native `dblclick` listener on the\n // canvas, which made it a THIRD independent definition of \"double click\"\n // alongside the tool dispatcher's 300ms/8px `dblTap` and the gesture\n // dispatcher's 600ms/8px synthesized event — so which double-click\n // behaviors a consumer got depended on the millisecond gap between the two\n // clicks. The other two are gone; this now observes the gesture\n // dispatcher's single definition and resolves the hit with the same\n // `getNodeAtPoint` picker the rest of the canvas uses.\n //\n // It rides the dispatcher as an OBSERVER rather than an Action binding\n // because the prop is a notification, not a behavior: as a binding it would\n // lose first-match-wins to `enterPathEdit` on every body hit and silently\n // stop firing.\n const onDoubleClickRef = useLatest(onDoubleClick);\n const getNodeAtPointRef = useLatest(getNodeAtPoint);\n const onDoubleClickObserver = useMemo(() => {\n if (!onDoubleClick) return undefined;\n return (world: { x: number; y: number }): void => {\n const cb = onDoubleClickRef.current;\n if (!cb) return;\n const result = getNodeAtPointRef.current?.(world.x, world.y);\n cb(result ? { id: result.id, kind: result.kind } : null);\n };\n // Identity only needs to change between \"wired\" and \"not wired\" — the\n // callback and picker are both read through refs.\n }, [Boolean(onDoubleClick)]); // eslint-disable-line react-hooks/exhaustive-deps\n\n // (Legacy `gestures` prop removed alongside the consumer-facing action\n // hooks; undo/redo and friends now register via the Actions Registry.)\n\n // Merge caller-supplied layers with kit defaults. When `layers` is omitted\n // the result is the full default set (scene + selectionOverlay). Partial\n // configs deep-merge; `null` slot values suppress a default explicitly.\n const mergedLayers = useMemo(\n () => mergeLayersWithDefaults(layers, deviceProfile.targetScale),\n [layers, deviceProfile.targetScale],\n );\n\n // `selectTool.rotate === false` disables rotation: drop the `rotate` action\n // (its rotation-handle chrome is hidden via effectiveChromeVisibility above).\n // A consumer-supplied `rotate` override still wins; `actions === null`\n // (all defaults disabled) is left untouched.\n const resolvedActions = useMemo<ActionsProp | undefined>(() => {\n if (selectToolOpts?.rotate !== false) return actions;\n if (actions === null) return null;\n const merged = { ...(actions ?? {}) } as Record<string, unknown>;\n if (!('rotate' in merged)) merged.rotate = null;\n return merged as ActionsProp;\n }, [actions, selectToolOpts?.rotate]);\n\n // Stable action-lookup getter threaded into the dispatcher so\n // beginUiOngoing can resolve action ids at call time. Populated by\n // StandardActionsRegistrar once it has the registry in scope.\n const getActionRef = useRef<((id: string) => Action | undefined) | null>(null);\n\n // Shared `Dispatcher` instance — created once per `<SceneCanvas>` and\n // threaded to both the gesture-dispatcher mounter (which pumps input\n // events into it) and the preview-ghost layer (which walks its\n // `getInFlightHandles()` for dispatcher-side gesture previews). Lazy\n // ref init keeps identity stable across renders without an effect.\n const dispatcherRef = useRef<Dispatcher | null>(null);\n if (!dispatcherRef.current) {\n dispatcherRef.current = createDispatcher({\n getAction: (id) => getActionRef.current?.(id),\n });\n }\n const dispatcher = dispatcherRef.current;\n\n // The dispatcher's contribution to `helpersRef` — in-flight preview ids,\n // nascent-insert bounds, and the pump signal. Reads through the ref so one\n // stable object keeps pointing at the live dispatcher.\n const gestureSource = useMemo(() => createGestureSource(() => dispatcherRef.current), []);\n\n // The dispatcher's half of this view's overlay-aware lookups: whose\n // committed paint a ghost hides, and the pose a handle proposes for an id.\n const { previewIdsExtra, previewPoseExtra } = useMemo(\n () => createDispatcherPreviewSources(() => dispatcherRef.current),\n [],\n );\n\n const sceneSlot = useMemo(() => {\n const slot = mergedLayers.scene;\n if (!slot || 'layer' in slot) return slot; // null or CustomLayerEntry — leave alone\n return wireSceneSlotToScene(\n slot as SceneSlotConfig<Node<TData, TLayer, TPose>, TPose>,\n scene,\n alphaFor,\n animator?.colorOverrides,\n );\n }, [mergedLayers.scene, alphaFor, scene, animator]);\n\n // Preview-ghost layer: renders in-flight gesture poses on top of the\n // committed scene using the scene slot's `drawOne`, from whichever view's\n // preview sources the draw envelope carries. It takes the scene-wired slot,\n // so a ghosted derived node still resolves its path.\n const previewLayer = usePreviewGhostLayer<TData, TLayer, TPose>({\n scene,\n sceneSlot,\n dispatcher,\n });\n\n // Dispatcher-driven chrome overlays — marquee rect + lasso polyline +\n // any other `OngoingHandle.overlay()` shapes the in-flight actions\n // publish. Screen-space; slotted after the preview-ghost so chrome\n // paints on top of any displaced ghost silhouettes.\n const dispatcherOverlay = useDispatcherOverlayLayer({ dispatcher });\n\n // Chrome-caps hover tracking: last-hovered NodeId fed into `ChromeCtx.hover`.\n // The hook attaches its own pointermove/leave listeners on the canvas and\n // caches the topmost-id from `getNodeAtPoint` on a ref. No re-renders.\n\n const getNodeAtPointRefForHover = useLatest(getNodeAtPoint);\n const getHover = useHoverTracking({\n canvasRef: internalCanvasRef,\n // One lookup, not a client→world thunk beside a picker: the point and the\n // camera its tolerance converts against have to come from the same view.\n // Hover has no pointer to capture, so it resolves fresh — whichever view\n // is under the cursor right now owns the point.\n nodeAtClientPoint: (clientX, clientY) => {\n const canvas = internalCanvasRef.current;\n if (!canvas) return null;\n const target = surfaceViewRegistry?.resolver.at(null, clientX, clientY);\n const origin = target?.origin ?? canvas.getBoundingClientRect();\n const view = target?.view ?? currentViewRef.current;\n const [x, y] = clientToWorldHelper(clientX, clientY, origin, view);\n // A view judges its own layers; the surface's gate is the picker's default.\n const reg = target?.id != null\n ? surfaceViewRegistry?.list().find((r) => r.id === target.id)\n : undefined;\n const hit = getNodeAtPointRefForHover.current?.(\n x, y, reg ? { scale: view.scale, layerIsPainted: reg.layerIsPainted } : view,\n );\n return hit ? { id: hit.id as NodeId } : null;\n },\n enabled: chromeVisibility !== undefined,\n });\n\n // Stable refs for the live selection / view / focus / suppression sources\n // that feed `buildChromeCtx`. The resolver factory below closes over these\n // and is called per draw / per hitTest from Canvas.\n const selectionForCapsRef = useLatest(selection.current as readonly NodeId[]);\n const getFocusedPropRef = useLatest(getFocusedProp);\n // Selection chrome belongs to the presets that act on it: the outline to\n // `pick`, the handles to `transform`. `never` also takes a handle out of\n // hit-testing, so a hidden handle cannot be grabbed.\n //\n // `selectable={false}` suppresses the marquee / lasso chrome by default:\n // every selection write no-ops then, so the select tool's\n // empty-drag binding still CLAIMS the gesture (keeping it from falling\n // through to other ambient drag actions like insert) but paints nothing.\n // An explicit consumer rule for either id still wins.\n const effectiveChromeVisibility = useMemo(() => {\n // Kit defaults first; consumer `chromeVisibility` spread last so it wins.\n const defaults: import('features/chrome-caps').VisibilityRules = {};\n if (!enabled.has('pick')) defaults['selection.outline'] = never;\n if (!enabled.has('transform')) {\n defaults['selection.resize-handles'] = never;\n defaults['selection.rotation-handle'] = never;\n }\n if (!selectable) {\n defaults['action.marquee'] = never;\n defaults['action.lasso'] = never;\n }\n // `selectTool.rotate === false` hides the rotation handle (its action is\n // also dropped below) so a non-rotatable consumer fully opts out.\n if (selectToolOpts?.rotate === false) defaults['selection.rotation-handle'] = never;\n if (Object.keys(defaults).length === 0) return chromeVisibility;\n return { ...defaults, ...chromeVisibility };\n }, [chromeVisibility, selectable, selectToolOpts?.rotate, enabled]);\n const chromeVisibilityRef = useLatest(effectiveChromeVisibility);\n // Read through a ref for the same reason as the others here:\n // `buildCurrentRuleCtx` is a stable `useCallback`, and adding the profile to\n // its deps would rebuild it whenever a media query changes.\n const deviceProfileRef = useLatest(deviceProfile);\n // Per-node resizability predicate from `selectTool.resize.resizable`, folded\n // over the live selection into the `selectionResizable` rule-ctx flag below.\n const resizablePredRef = useLatest(selectToolOpts?.resize?.resizable);\n\n // The visibility predicate factory passed to <Canvas>. Called fresh per\n // draw / hitTest; builds ChromeCtx from the live refs and resolves\n // against the merged rule table. Returns the universal predicate when\n // no consumer overrides are present AND no hover tracking is needed —\n // letting the kit's defaults still gate paint without forcing every\n // legacy consumer onto chrome-caps.\n /** Build the live RuleCtx — selection + view + modifiers + mode + capabilities\n * + active action. Consumed by chrome-caps' resolver and the dispatcher's\n * eligibility filter so both see the same view of the world. */\n const buildRuleCtxFor = useCallback((inputs: ViewRuleInputs) => {\n const sel = inputs.selection;\n // No mode registry wired → behave as normal mode, capabilities included.\n // An empty set here would make every `capability:` rule false and hide\n // the chrome those rules gate. See DEFAULT_ALLOWED_CAPABILITIES.\n const modeInfo = getActiveModeRef.current?.()\n ?? { id: 'normal', allowedCapabilities: DEFAULT_ALLOWED_CAPABILITIES };\n const ctx = buildChromeCtx({\n focused: getFocusedPropRef.current ? getFocusedPropRef.current() : true,\n selection: sel,\n multiActive: sel.length > 1,\n modifiers: { alt: false, ctrl: false, meta: false, shift: false },\n action: inputs.action,\n hover: getHover(),\n view: inputs.view,\n });\n // buildChromeCtx returns a ChromeCtx (legacy shape); resolveVisibility\n // accepts both ChromeCtx and RuleCtx and supplies defaults when mode/\n // allowedCapabilities are absent. We attach them inline so the\n // mode-gated default rules can read them.\n // `selectionResizable`: true only when every selected node is resizable\n // (per `selectTool.resize.resizable`); undefined when no predicate is\n // supplied → the `resizable:` selector treats it as resizable (back-compat).\n const resizablePred = resizablePredRef.current;\n const selectionResizable = resizablePred\n ? sel.every((id) => resizablePred(id as string))\n : undefined;\n return {\n ...ctx,\n zoom: viewZoom(inputs.view),\n mode: modeInfo.id,\n allowedCapabilities: modeInfo.allowedCapabilities,\n selectionResizable,\n editingAnchors: effectivePathEditingId() !== '',\n device: deviceProfileRef.current,\n };\n }, [getHover, effectivePathEditingId, getActiveModeRef, getFocusedPropRef, resizablePredRef, deviceProfileRef]);\n\n /** The surface's own view zero. */\n const currentRuleInputs = useCallback((): ViewRuleInputs => ({\n selection: selectionForCapsRef.current,\n view: currentViewRef.current,\n action: dispatcher.getActiveAction(),\n }), [dispatcher, selectionForCapsRef]);\n const buildCurrentRuleCtx = useCallback(\n () => buildRuleCtxFor(currentRuleInputs()),\n [buildRuleCtxFor, currentRuleInputs],\n );\n\n // Anchor editing survives only as long as the active mode permits it.\n // Deliberately undefined when no mode registry is wired: \"no modality\"\n // means nothing revokes edit mode, whereas a predicate built from the\n // fallback capability set would revoke it immediately (the default set\n // is NORMAL's, which doesn't include `edits-anchors`).\n const anchorEditingAllowed = useMemo(\n () =>\n getActiveMode\n ? () => getActiveModeRef.current!().allowedCapabilities.has('edits-anchors')\n : undefined,\n [getActiveMode, getActiveModeRef],\n );\n useInsertionEffect(() => {\n anchorEditingAllowedRef.current = anchorEditingAllowed;\n });\n\n /** The chrome-caps answers for one view: the surface's rule table evaluated\n * against that view's selection, camera and in-flight action. */\n const chromeCaps = useMemo(() => ({\n ruleCtx: (inputs: ViewRuleInputs) =>\n (getActiveModeRef.current ? buildRuleCtxFor(inputs) as RuleCtx : undefined),\n isVisible: (inputs: ViewRuleInputs) => resolveVisibility(\n chromeVisibilityRef.current,\n buildRuleCtxFor(inputs) as Parameters<typeof resolveVisibility>[1],\n ),\n }), [buildRuleCtxFor, getActiveModeRef, chromeVisibilityRef]);\n\n const getIsVisibleForCanvas = useCallback(\n (): ((id: string) => boolean) => chromeCaps.isVisible(currentRuleInputs()),\n [chromeCaps, currentRuleInputs],\n );\n\n // Pen preview overlay — reads the pen tool's persistent scratch and draws\n // the in-progress path (anchors, handles, rubber-band, close hint). Only\n // wired when the pen tool is actually registered; otherwise null.\n const wantsPen = wants('pen');\n const penPreviewLayer = useMemo(\n () => (wantsPen\n ? createPenPreviewLayer({ penTool: shapeTools.pen as Tool<PenScratch> })\n : null),\n [shapeTools.pen, wantsPen],\n );\n\n // Bump the canvas's redraw whenever edit-mode changes — the chrome layer\n // reads `editingId` via a ref, so without an explicit redraw signal a\n // dirty-render canvas (no animation in flight) sits with stale frames\n // and the user sees no chrome until something else triggers a paint.\n useEffect(() => {\n canvasApiRef.current?.requestRedraw?.();\n }, [pathEditingId]);\n\n // Path-editing overlay — anchor squares, tangent lines, control-point\n // dots for the polygon currently in edit mode. Reads the same state the\n // dep does, so chrome appears exactly when (and only when) the gesture\n // path is also active.\n //\n // `getPose` walks the dispatcher's in-flight handles first so the chrome\n // tracks the live `previewPose` while editAnchorsAction is dragging; only\n // falls back to the committed scene pose between gestures. This is what\n // makes the dragged anchor / handle move under the cursor instead of\n // staying pinned to its committed position until the drag commits.\n const sceneRefForOverlay = useLatest(scene);\n const slopsOn = debug !== undefined && debug !== false && debug.slops === true;\n const selectionOverlayCfg = mergedLayers.selectionOverlay as\n | SelectionOverlaySlotConfig<TPose> | null | undefined;\n const badgeOf = selectionOverlayCfg ? rotationBadgeOf(selectionOverlayCfg) : null;\n // Kept by value so the layers and hit-testers keyed on it don't rebuild\n // every render.\n const rotationBadge = useMemo(\n () => badgeOf,\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [badgeOf?.distancePx, badgeOf?.sizePx],\n );\n // Debug: slops viz layer (off by default). Draws the affordances the\n // gesture mounter hit-tests, which it publishes here, so the halos are the\n // hit regions rather than a copy of them.\n const chromeAffordancesRef = useRef<readonly Affordance[]>([]);\n const slopsLayer = useMemo(\n () => createSlopsDebugLayer({ getAffordances: () => chromeAffordancesRef.current }),\n [],\n );\n\n // Resolve the live (preview-aware) world polygon for `id`. Reads from\n // the dispatcher's in-flight handles first — whichever handle owns\n // the gesture (editAnchors anchor-drag, move-the-whole-path, etc.)\n // contributes the previewPose / previewData that we'd otherwise\n // dispatch separately. Synthesizes a (pose, data) pair and routes it\n // through `resolveEditablePathOf` so chrome and slops viz follow\n // *any* in-flight gesture that previews state for the editing id.\n const livePathFor = (\n id: string,\n previews: readonly GesturePreviewSource[],\n view: View,\n ): PolygonPath | null => {\n const node = sceneRefForOverlay.current?.get(id as never);\n if (!node) return null;\n let pose = node.pose as unknown;\n let data = node.data as unknown;\n let touched = false;\n for (const source of previews) {\n const previewIds = source.previewIds?.();\n if (!previewIds) continue;\n let owns = false;\n for (const pid of previewIds) {\n if (pid === id) { owns = true; break; }\n }\n if (!owns) continue;\n const p = source.previewPose?.(id);\n if (p != null && !touched) { pose = p; touched = true; }\n const d = source.previewData?.(id);\n if (d != null) { data = d; touched = true; }\n }\n // In the drawing camera's world: a path on a parallax plane is stored in\n // the plane's.\n return pathFromPlane(\n resolveEditablePathOf({ pose, data } as { pose: unknown; data: unknown }),\n planeOfNodeRef.current(id, view),\n );\n };\n\n const pathEditingOverlayLayer = useMemo(\n () => createPathEditingOverlayLayer({\n getEditingId: () => effectivePathEditingId() || null,\n getPose: (id, previews, view) => livePathFor(id, previews, view) as never,\n getSelectedAnchors: () => selectedAnchorsRef.current,\n // Drawn by an action that ran in the edited path's plane.\n getMarquee: (view) => {\n const rect = anchorMarqueeRef.current;\n const plane = rect ? planeOfNodeRef.current(effectivePathEditingId(), view) : null;\n return rect && plane ? rectFromPlane(plane, rect) : rect;\n },\n }),\n // Stable identity — closure reads live state through refs.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [],\n );\n\n // Suppress the standard selection overlay (outline + corner/rotate\n // handles) on the node currently in path-edit mode — the per-anchor\n // chrome takes over.\n const getSuppressedSelectionIds = useCallback((): ReadonlySet<string> => {\n const id = effectivePathEditingId();\n return id ? new Set([id]) : EMPTY_ID_SET;\n }, [effectivePathEditingId]);\n\n // Selection overlay — constructed here (scene-aware) per main's seam refactor.\n // Layered on top: path-edit suppression from HEAD's branch.\n const selectionOverlayLayer = useMemo(() => {\n const selCfg = mergedLayers.selectionOverlay as\n | SelectionOverlaySlotConfig<TPose>\n | null\n | undefined;\n if (selCfg === null) return null;\n const cfg = (selCfg ?? {}) as SelectionOverlaySlotConfig<TPose>;\n\n const callerSuppress = cfg.getSuppressedIds;\n const getSuppressedIds = (): ReadonlySet<string> => {\n const own = getSuppressedSelectionIds();\n const caller = callerSuppress?.();\n if (!caller || caller.size === 0) return own;\n if (own.size === 0) return caller;\n const merged = new Set<string>(caller);\n for (const id of own) merged.add(id);\n return merged;\n };\n\n return createSelectionOverlayLayer<TPose>({\n ...cfg,\n getSuppressedIds,\n ...(cfg.poseById\n ? {\n getPose: cfg.poseById,\n poseDescriptor: cfg.poseDescriptor ?? (descriptor as PoseDescriptor<TPose>),\n }\n : {}),\n });\n }, [mergedLayers.selectionOverlay, getSuppressedSelectionIds, descriptor]);\n\n const wiredLayers = useMemo<LayersMap<Node<TData, TLayer, TPose>, TPose>>(() => ({\n ...mergedLayers,\n ...(sceneSlot ? { scene: sceneSlot } : {}),\n // Pass the pre-built selection overlay layer so Canvas receives a\n // CustomLayerEntry and skips its own factory construction for this slot.\n selectionOverlay: selectionOverlayLayer\n ? { layer: selectionOverlayLayer }\n : mergedLayers.selectionOverlay === null ? null : undefined,\n previewGhost: { layer: previewLayer, after: 'scene' },\n dispatcherOverlay: { layer: dispatcherOverlay, after: 'previewGhost' },\n ...(penPreviewLayer ? { penPreview: { layer: penPreviewLayer, after: 'dispatcherOverlay' } } : {}),\n pathEditingOverlay: { layer: pathEditingOverlayLayer, after: 'selectionOverlay' },\n ...(slopsOn ? { slopsDebug: { layer: slopsLayer, after: 'pathEditingOverlay' } } : {}),\n }), [mergedLayers, sceneSlot, selectionOverlayLayer, previewLayer, dispatcherOverlay, penPreviewLayer, pathEditingOverlayLayer, slopsOn, slopsLayer]);\n\n // Standard-action deps: closures over the live scene / selection / adapter\n // so the resolved actions always read current state. `useStandardActions`\n // stabilizes via refs internally — these closures are passed every render\n // but the registered Action descriptors are not re-registered.\n // `CanvasExtensionApi.ingest` — imperative entry into the same\n // content-handler pipeline OS drop / clipboard paste hit. Routed through\n // `registry.trigger('ingest', …)` so the action's `requires` deps\n // (insert, ingestion, …) are resolved exactly as on the dispatcher path.\n // `StandardActionsRegistrar` stashes the registry into this ref.\n const actionsRegistryRef = useRef<ActionsRegistry | null>(null);\n\n // Clipboard-paste ctx for the kit weasel-JSON content handler\n // (`IngestCtx.clipboard`). Built from THIS canvas's synthesized adapter so\n // OS-arriving pastes re-materialize through the same `commitPaste` path\n // `useClipboardOps` uses. Absent (⇒ the handler declines) when the\n // consumer set `ingestion.clipboard.enabled: false` or the adapter lacks\n // `commitPaste` (always present on the synthesized adapter; guarded for\n // future adapter overrides).\n const ingestionClipboardReviver = ingestion?.clipboard?.reviver;\n const ingestionClipboardEnabled = ingestion?.clipboard?.enabled !== false;\n const ingestionClipboard = useMemo<ClipboardIngestCtx | undefined>(() => {\n if (!ingestionClipboardEnabled || !adapter?.commitPaste) return undefined;\n return {\n adapter: adapter as unknown as InsertAdapter<{ id: string }>,\n ...(ingestionClipboardReviver ? { reviver: ingestionClipboardReviver } : {}),\n };\n }, [adapter, ingestionClipboardEnabled, ingestionClipboardReviver]);\n const ingestImpl = useCallback(\n (input: File[] | IngestItem[], point?: { x: number; y: number }) => {\n const items: IngestItem[] = (input as (File | IngestItem)[]).map((entry) =>\n entry instanceof File ? itemsFromFiles([entry])[0] : entry,\n );\n if (items.length === 0) return;\n if (!actionsRegistryRef.current) {\n // The registry is stashed by a descendant effect — a consumer calling\n // ingest() from its own ref callback / layout effect lands here.\n dwarn('ingest', 'CanvasExtensionApi.ingest called before the action registry mounted — call ignored. Defer to an effect or event handler.');\n return;\n }\n actionsRegistryRef.current.trigger('ingest', {\n items,\n ...(point ? { worldX: point.x, worldY: point.y } : {}),\n });\n },\n [],\n );\n\n // Views added through the handle rather than declared as props or children.\n const [addedViews, setAddedViews] = useState<readonly CanvasViewProps[]>([]);\n const addView = useCallback((props: CanvasViewProps): CanvasViewHandle => {\n setAddedViews((list) => [...list.filter((v) => v.id !== props.id), props]);\n return {\n id: props.id,\n draw: (data, outer, dims) =>\n surfaceViewRegistry?.list().find((r) => r.id === props.id)?.layer.draw(data, outer, dims) ?? [],\n remove: () => setAddedViews((list) => list.filter((v) => v !== props)),\n };\n }, [surfaceViewRegistry]);\n\n // Merge the forwarded ref with our internalCanvasRef so the dispatcher can\n // read the canvas element even when the consumer also forwards a ref.\n // The handle exposed to consumers extends the primitive's with `ingest`\n // (SceneCanvas-only — it needs the action stack).\n const mergedRef = useCallback(\n (node: CanvasExtensionApi | null) => {\n internalCanvasRef.current = node?.element ?? null;\n const extended: SceneCanvasApi | null = node\n ? {\n ...node,\n ingest: ingestImpl,\n animateView: viewAnimation.animate,\n stopViewAnimation: viewAnimation.stop,\n isViewAnimating: viewAnimation.isAnimating,\n addView,\n }\n : null;\n canvasApiRef.current = extended;\n setCanvasReady(extended !== null);\n if (typeof ref === 'function') ref(extended);\n else if (ref) (ref as React.MutableRefObject<SceneCanvasApi | null>).current = extended;\n },\n [ref, ingestImpl, viewAnimation, addView],\n );\n\n // What a view needs to build its own overlay-aware state. `geometry` is the\n // same descriptor handed to `<Canvas>`, so the two cannot diverge.\n const viewInputs = useMemo<SurfaceViewInputs>(() => ({\n adapter: adapter as unknown as { getPose(id: string): unknown },\n geometry: descriptor,\n boundsOf: internalBoundsOf,\n boundsOfPose: internalBoundsOfPose as SurfaceViewInputs['boundsOfPose'],\n planeOfNode: internalPlaneOfNode,\n tools,\n pickEvery: internalPickEvery,\n pickBest: internalPickBest,\n kindOfNode,\n chromeCaps,\n selectionApi: selection,\n rotationBadge,\n }), [adapter, descriptor, internalBoundsOf, internalBoundsOfPose, internalPlaneOfNode, tools,\n internalPickEvery, internalPickBest, kindOfNode, chromeCaps, selection, rotationBadge]);\n\n const canvas = (\n <Canvas<Node<TData, TLayer, TPose>, TPose>\n ref={mergedRef}\n adapter={adapter}\n selection={selection}\n poseDescriptor={descriptor as PoseDescriptor<TPose>}\n tools={tools}\n layers={wiredLayers}\n pickEvery={internalPickEvery}\n // The chrome's bounds are the picker's: a node on a parallax plane is\n // boxed where the plane draws it, and a `geometry.boundsOf` reaches both.\n boundsOf={internalBoundsOf}\n boundsOfPose={internalBoundsOfPose}\n getIsVisible={getIsVisibleForCanvas}\n previewIdsExtra={previewIdsExtra}\n // The gesture surface behind `helpersRef.getGestureBounds()` /\n // `subscribeGestures()` — Canvas has no dispatcher of its own.\n gestureSource={gestureSource}\n previewPoseExtra={previewPoseExtra}\n backgroundFill={backgroundFill}\n cursorCoordsHud={cursorCoordsHud}\n pickHud={pickHud}\n modalityHud={modalityHud}\n {...(debug !== undefined ? { debug: canvasDebug(debug) } : {})}\n pickBest={internalPickBest}\n contentVersion={scene.getVersion}\n layerVisibility={layerVisibility}\n layerOrder={layerOrder}\n {...(viewProp !== undefined ? { view: viewProp } : { defaultView })}\n onViewChange={notifyViewChange}\n shaders={shaders}\n flattenTolerance={flattenTolerance}\n // onBackgroundClick is intentionally NOT wired here. The `clearSelection`\n // action binding in the select tool handles \"click on empty background clears\n // selection\" for all SceneCanvas consumers. Wiring a separate background-click\n // callback would interfere with the gesture dispatcher (which handles lasso,\n // marquee, etc.) since tools.dispatcher.hasActiveGesture() only covers the\n // legacy tool channel, not the gesture dispatcher channel.\n {...(redrawOn ? { redrawOn } : {})}\n {...restProps}\n />\n );\n\n // Test hook: opt-in via ?test=1, never in production builds. See src/test-hook.\n const testHookSceneRef = useLatest(scene);\n const testHookSelectionRef = useLatest(selection);\n\n const testHookRef = useRef<WeaselTestHook | null>(null);\n useEffect(() => {\n // Call-site gate: in a consumer's production build, esbuild/webpack/Vite\n // constant-fold `process.env.NODE_ENV` to `\"production\"` and DCE this\n // block, dropping the test-hook references. Same dev-only pattern as\n // React's invariant warnings. Gating only inside `installTestHookIfRequested`\n // is not enough — a called function can't be tree-shaken even if its body\n // is dead, so the gate must sit at the call site too.\n if (process.env.NODE_ENV !== 'production') {\n testHookRef.current = installTestHookIfRequested({\n getScene: () => testHookSceneRef.current as never,\n getSelectionIds: () =>\n (testHookSelectionRef.current?.current as readonly string[] | undefined) ?? [],\n getView: () => currentViewRef.current,\n getActiveToolId: () => liveToolsRef.current?.active ?? null,\n });\n testHookRef.current?._markReady();\n }\n }, [testHookSceneRef, testHookSelectionRef, liveToolsRef]);\n\n return (\n <DeviceProfileProvider value={device}>\n <ViewInputsProvider value={viewInputs}>\n <>\n <PointerProviderIfRoot>\n <>\n {canvas}\n <PointerPublisher canvasRef={internalCanvasRef} />\n <StandardActionsRegistrar\n selection={selection}\n scene={scene as Scene<unknown, string, unknown>}\n adapter={adapter as unknown as BridgeAdapter}\n actionDefaults={actionDefaults}\n actions={resolvedActions}\n excludeActions={standardActionsExclude}\n currentViewRef={currentViewRef}\n onViewChange={handleViewChange}\n resizeOptions={selectToolOpts?.resize as UseResizeOptions<unknown> | undefined}\n poseDescriptor={descriptor}\n geometryProjection={geometryProjection}\n dispatcher={dispatcher}\n getActionRef={getActionRef}\n pickEvery={internalPickEvery}\n layerIsPainted={viewLayerGate}\n alphaOf={alphaFor ? composedAlphaFor : undefined}\n viewportPanEnabled={enabled.has('view') ? (viewport?.pan ?? true) : false}\n viewportZoom={enabled.has('view') ? resolvedViewportZoom : false}\n viewportPinchZoom={enabled.has('view') ? (viewport?.pinchZoom ?? true) : false}\n viewportRecenter={viewport?.recenter}\n viewAnimation={viewAnimation}\n editAnchorsExternalState={editAnchorsExternalState}\n anchorEditingAllowed={anchorEditingAllowed}\n layouts={layouts as SceneCanvasProps<unknown, string, unknown>['layouts']}\n layoutDropTarget={layoutDropTarget}\n reflowTransition={reflowTransition as ReflowTransition<unknown> | null | undefined}\n poseComposition={poseComposition as SceneCanvasProps<unknown, string, unknown>['poseComposition']}\n insertNodeFactories={insertNodeFactories}\n snapPoint={toolOptions?.snapPoint}\n canvasRef={internalCanvasRef}\n canvasApiRef={canvasApiRef}\n ingestionResolveSrc={ingestion?.resolveSrc}\n ingestionSvg={ingestion?.svg}\n ingestionClipboard={ingestionClipboard}\n actionsRegistryRef={actionsRegistryRef}\n />\n <GestureDispatcherMounter\n canvasRef={internalCanvasRef}\n canvasApiRef={canvasApiRef}\n tools={tools}\n contributions={featureContributions}\n enabled={enableGestureDispatcher}\n keyboard={enableKeybindings}\n selectionRef={selectionRef}\n boundsOf={internalBoundsOf}\n planeOfNode={internalPlaneOfNode}\n pickEvery={internalPickEvery}\n pickBest={internalPickBest}\n kindOfNode={kindOfNode}\n viewRef={currentViewRef}\n dispatcher={dispatcher}\n getIsVisibleForCanvas={getIsVisibleForCanvas}\n getRuleCtx={getActiveMode ? buildCurrentRuleCtx : undefined}\n targetScale={deviceProfile.targetScale}\n handleHitRadius={selectToolOpts?.handleHitRadius}\n rotationBadge={rotationBadge}\n chromeAffordancesRef={chromeAffordancesRef}\n onDoubleClick={onDoubleClickObserver}\n longPress={longPress}\n />\n <ToolKeybindingsMounter\n internalTools={internalTools}\n toolsTakeover={toolsTakeover ?? undefined}\n enableKeybindings={enableKeybindings}\n isToolEligible={isToolEligible}\n canvasApi={canvasReady ? canvasApiRef.current : null}\n versionCheck={versionCheck}\n />\n {viewDescriptors?.map((v, i) => (\n <CanvasView key={v.id} {...v} order={v.order ?? i} />\n ))}\n {contributionEntries(tools).flatMap((e) => e.views ?? []).map((v) => (\n <CanvasView key={`contribution:${v.id}`} {...v} />\n ))}\n {addedViews.map((v) => <CanvasView key={`added:${v.id}`} {...v} />)}\n {children}\n </>\n </PointerProviderIfRoot>\n </>\n </ViewInputsProvider>\n </DeviceProfileProvider>\n );\n}\n\n/**\n * Mounts the gesture dispatcher on this canvas's input scope.\n *\n * Accepts `selectionRef`, `boundsOf`, `pickEvery`, and `viewRef` so\n * it can wire `affordanceAt` + `classifyTarget` thunks into the dispatcher.\n * These thunks convert client coords → world coords via the canvas rect + view,\n * then classify the pointer position against affordances and scene bodies.\n */\n/**\n * Mounts `useKeybindings`, whose `tool.activate` / `tool.offhand` /\n * `tool.resetToDefault` registrations land in this canvas's scope.\n *\n * Two calls, mirroring the pair that used to live in `SceneCanvasInner`: the\n * hook snapshots the initial active tool for Escape-returns-to-default, so\n * the internal and consumer-supplied `ToolsApi` each need their own instance\n * and the hook count has to stay stable across the takeover branch.\n */\nfunction ToolKeybindingsMounter({\n internalTools,\n toolsTakeover,\n enableKeybindings,\n isToolEligible,\n canvasApi,\n versionCheck,\n}: {\n internalTools: ToolsApi;\n toolsTakeover?: ToolsApi;\n enableKeybindings: boolean;\n isToolEligible: (toolId: string) => boolean;\n canvasApi: CanvasExtensionApi | null;\n versionCheck?: VersionCheck;\n}) {\n useKeybindings(internalTools, {\n disable: !!toolsTakeover || !enableKeybindings,\n isToolEligible,\n });\n useKeybindings(toolsTakeover ?? internalTools, {\n disable: !toolsTakeover || !enableKeybindings,\n isToolEligible,\n });\n // Entry-owned roles: actions (polygon.adjustSides, …), deps and `attach`.\n // Same reason this lives here and not in the tool hooks: the hooks run above\n // the provider. Not gated on `enableKeybindings` — these back wheel and\n // pointer bindings too, not just keys.\n useContributionRoles(toolsTakeover ?? internalTools, canvasApi, versionCheck);\n return null;\n}\n\nfunction GestureDispatcherMounter({\n canvasRef,\n canvasApiRef,\n tools,\n contributions,\n enabled,\n keyboard,\n selectionRef,\n boundsOf,\n planeOfNode,\n pickEvery,\n pickBest,\n kindOfNode,\n viewRef,\n dispatcher,\n getIsVisibleForCanvas,\n getRuleCtx,\n targetScale,\n handleHitRadius,\n rotationBadge,\n chromeAffordancesRef,\n onDoubleClick,\n longPress: longPressOpts,\n}: {\n canvasRef: React.RefObject<HTMLElement | null>;\n /** Holds the full `CanvasExtensionApi` so the gesture dispatcher can call\n * `requestRedraw()` between pointer events. */\n canvasApiRef?: React.RefObject<CanvasExtensionApi | null>;\n tools: ToolsApi;\n /** Always-live entries the canvas installs beside `tools` — the selection's\n * `move` / `transform` bindings. Ahead of the tools' ambient entries, so a\n * tie at one specificity goes to the kit's. */\n contributions: readonly Contribution[];\n enabled: boolean;\n /** When false, the dispatcher leaves keyboard listeners unattached so\n * keyboard-bound actions never fire. Wired to `enableKeybindings`. */\n keyboard: boolean;\n selectionRef?: React.RefObject<import('core/selection/useSelection').SelectionApi>;\n boundsOf?: (id: string) => import('core/viewport/fitViewToBounds').Bounds | null;\n /** The parallax plane a node is drawn through, under the surface's camera —\n * so path anchors are hit where the plane draws them. */\n planeOfNode?: (id: string) => import('core/viewport/parallax').PlaneMap | null;\n pickEvery?: (worldX: number, worldY: number) => string[];\n /** Single topmost hit (collapses parent/child via `pickTopMostHit`), used to\n * classify the body under the pointer. Must match the select tool's own\n * resolution so a child node isn't misclassified by its parent's selection.\n * Falls back to `pickEvery`'s last id when absent. */\n pickBest?: (worldX: number, worldY: number) => string | null;\n /** Resolves a hit node id to its routing-trait kind, so the body\n * classification carries `kind` alongside `bodyTarget` and the\n * `kind:<k>` / `kind:<k>:selected` target forms can match. Absent when\n * the consumer opted out of routing (`routing={[]}`). */\n kindOfNode?: (id: string) => string | undefined;\n viewRef?: React.RefObject<View>;\n /** Pre-created dispatcher to pump events into. When omitted,\n * `useGestureDispatcher` creates one internally (legacy path). */\n dispatcher?: Dispatcher;\n /** Chrome-caps visibility resolver factory. Threaded into\n * `buildAffordanceAt` so the hit-test pipeline gates corner / rotate /\n * anchor affordances on the same chrome ids the renderer uses. */\n getIsVisibleForCanvas?: () => (id: string) => boolean;\n /** Live RuleCtx factory. Threaded into `useGestureDispatcher` so the\n * dispatcher's eligibility filter sees the same mode/capabilities/selection\n * view of the world that chrome-caps does. */\n getRuleCtx?: () => RuleCtx;\n /** `DeviceProfile.targetScale`, so the affordance grab zones resolve to the\n * same sizes the chrome paints at. */\n targetScale?: number;\n /** Consumer override for the corner-handle grab radius\n * (`selectTool.handleHitRadius`). Undefined takes the device-scaled size. */\n handleHitRadius?: number;\n /** The rotate badge the selection overlay paints, grabbable where drawn. */\n rotationBadge?: { distancePx: number; sizePx: number } | null;\n /** Receives the affordances this mounter hit-tests, for the slops overlay. */\n chromeAffordancesRef?: React.MutableRefObject<readonly Affordance[]>;\n /** Fires on every synthesized double click, in world coords. Backs the\n * `onDoubleClick` prop — see the option's doc on\n * `UseGestureDispatcherOptions` for why it's an observer, not a binding. */\n onDoubleClick?: (world: { x: number; y: number }) => void;\n /** Backs `<SceneCanvas longPress>`. */\n longPress?: SceneCanvasLongPress;\n}) {\n const registry = useActionsRegistry();\n const depRegistry = useDepRegistry();\n const viewRegistry = useOptionalViewRegistry();\n const entriesById = useMemo<ReadonlyMap<string, Contribution>>(() => {\n const m = new Map<string, Contribution>();\n for (const [id, tool] of Object.entries(tools.registry)) {\n m.set(id, tool);\n }\n for (const entry of contributions) m.set(entry.id, entry);\n // Ambient entries too — their bindings assemble at ambient scope, and the\n // dispatcher resolves them through this same map.\n for (const entry of tools.ambient) m.set(entry.id, entry);\n return m;\n }, [tools.registry, tools.ambient, contributions]);\n\n\n // Stable refs for the optional thunk inputs so the thunks themselves are\n // stable function identities across renders (no need to pass them as deps).\n const pickEveryRef = useLatest(pickEvery);\n const pickBestRef = useLatest(pickBest);\n const kindOfNodeRef = useLatest(kindOfNode);\n\n // `getAnchorState` thunk for `buildAffordanceAt` — reads the live\n // `editAnchors` dep from the registry at call time.\n const depRegistryRef = useLatest(depRegistry);\n const planeOfNodeRef = useLatest(planeOfNode);\n const getAnchorState = useMemo(() => anchorStateFrom(\n () => depRegistryRef.current,\n (id, path) => pathFromPlane(path, planeOfNodeRef.current?.(id) ?? null),\n ), [depRegistryRef, planeOfNodeRef]);\n\n // Build the `affordanceAt` thunk. Takes world coords and delegates to\n // `buildAffordanceAt` for handle hit-testing.\n const affordances = useMemo(() => chromeAffordances({\n ...(targetScale !== undefined ? { targetScale } : {}),\n ...(handleHitRadius !== undefined ? { handleHitRadius } : {}),\n rotationBadge,\n getAnchorState,\n }), [targetScale, handleHitRadius, rotationBadge, getAnchorState]);\n useInsertionEffect(() => {\n if (chromeAffordancesRef) chromeAffordancesRef.current = affordances;\n });\n const affordanceAt = useMemo(() => {\n if (!selectionRef || !boundsOf || !viewRef) return undefined;\n return buildAffordanceAt({\n // The canvas's own view chrome, built once by its helpers — not a\n // second construction here that has to agree with the painted one.\n getChromeState: () => viewRegistry?.surface()?.chromeState() ?? EMPTY_CHROME_STATE,\n // Radii are declared in screen pixels and converted against this view.\n getView: () => viewRef.current ?? { x: 0, y: 0, scale: { x: 1, y: 1 } },\n affordances,\n // Chrome-caps resolver: keep the affordance hit-test in sync with what\n // the renderer is actually painting. Without this, a click on a (no\n // longer visible) resize handle position still classifies as a resize\n // handle — e.g. an anchor drag in path-edit mode resizes the path's\n // bounding box instead of moving the anchor.\n ...(getIsVisibleForCanvas ? { getIsVisible: () => getIsVisibleForCanvas() } : {}),\n });\n }, [selectionRef, boundsOf, viewRef, affordances, getIsVisibleForCanvas, viewRegistry]);\n\n // Build the `classifyTarget` thunk. Takes world coords and delegates to\n // `buildClassifyTarget`.\n const classifyTarget = useMemo(() => {\n if (!selectionRef || !pickEvery || !viewRef) return undefined;\n return buildClassifyTarget(\n () => selectionRef.current?.current ?? [],\n // Use the select tool's own topmost-hit resolution (`pickTopMostHit`,\n // which collapses parent/child) so a child body is classified by ITS\n // OWN selection — not its parent's. The naive `pickEvery`-last fallback\n // assumes a bottom-first hit order, which is wrong for adapters whose\n // `pickEvery` returns topmost-first (it would resolve the parent).\n (wx: number, wy: number) => {\n if (pickBestRef.current) return pickBestRef.current(wx, wy);\n const ids = pickEveryRef.current?.(wx, wy) ?? [];\n return ids.length > 0 ? ids[ids.length - 1] : null;\n },\n // Node kind comes from the routing trait — the same classifier that\n // names `Hit.kind` — so `target: 'kind:text'` on a binding speaks the\n // vocabulary the consumer already declared in `routing`, rather than a\n // second one invented for bindings. `routing={[]}` opts out and leaves\n // every `kind:` target unmatchable.\n (id: string) => kindOfNodeRef.current?.(id),\n );\n }, [selectionRef, pickEvery, viewRef, pickBestRef, pickEveryRef, kindOfNodeRef]);\n\n // The canvas rect is read on every call (not cached) so it stays correct\n // after layout changes.\n const clientToWorld = useCallback((clientX: number, clientY: number): { x: number; y: number } => {\n const canvas = canvasRef.current;\n const view = viewRef?.current;\n if (!canvas || !view) {\n recordCoordTrace({ ts: Date.now(), clientX, clientY, rect: null, view: null, world: { x: clientX, y: clientY }, fallback: true });\n return { x: clientX, y: clientY };\n }\n const rect = canvas.getBoundingClientRect();\n const [wx, wy] = clientToWorldHelper(clientX, clientY, rect, view);\n const world = { x: wx, y: wy };\n recordCoordTrace({\n ts: Date.now(), clientX, clientY,\n rect: { left: rect.left, top: rect.top, width: rect.width, height: rect.height },\n view: { x: view.x, y: view.y, scaleX: view.scale.x, scaleY: view.scale.y },\n world, fallback: false,\n });\n return world;\n }, [canvasRef, viewRef]);\n\n const affordanceWithLayers = useMemo(() => {\n // Note this is NOT gated on `affordanceAt` being built: registered layers\n // produce affordances of their own, and a consumer with no selection\n // chrome (a canvas that is nothing but a HUD, say) still needs those.\n return (worldPoint: { x: number; y: number }) => {\n // Registered layers first: they draw on top of the kit's own chrome, so\n // they get first refusal on the point. A hit becomes an `AffordanceHit`\n // whose kind names the layer, carrying whatever the layer's hit-test\n // resolved — which is how `@weasel-js/hud` routes a press on one of its\n // widgets to its own action instead of the active tool.\n const extra = canvasApiRef?.current?.hitTestExtras?.(worldPoint.x, worldPoint.y);\n if (extra) {\n const claim = extra.hit;\n return {\n kind: `layer:${extra.layerId}`,\n owner: extra.layerId,\n strength: claim.strength ?? 'shared',\n ...(claim.claimedKinds !== undefined ? { claimedKinds: claim.claimedKinds } : {}),\n ...(claim.cursor !== undefined ? { cursor: claim.cursor } : {}),\n ...(claim.initialScratch !== undefined ? { payload: claim.initialScratch } : {}),\n };\n }\n return affordanceAt ? affordanceAt(worldPoint) : null;\n };\n }, [affordanceAt, canvasApiRef]);\n\n // Stable callback that asks the canvas to redraw. Reads via ref so the\n // identity stays stable while the underlying API binds after mount.\n const requestRedraw = useCallback(() => {\n canvasApiRef?.current?.requestRedraw?.();\n }, [canvasApiRef]);\n\n // The painted tier's channel, read live for the same reason — the handle it\n // lives on binds after mount.\n const paintedCursor = useCallback(\n () => canvasApiRef?.current?.paintedCursor,\n [canvasApiRef],\n );\n\n // The pending long-press, published as the `longPress` dep for feedback.\n const [longPressState] = useState(createLongPressStore);\n const longPress = useMemo(() => ({\n state: longPressState,\n ...(longPressOpts?.duration !== undefined ? { duration: longPressOpts.duration } : {}),\n ...(longPressOpts?.haptics !== undefined ? { haptics: longPressOpts.haptics } : {}),\n }), [longPressState, longPressOpts?.duration, longPressOpts?.haptics]);\n\n // Input routing to registered views. Rebuilt per event from the registry, so\n // a view that mounts or moves mid-session is routable on the next event; with\n // nothing registered every point resolves to the canvas, as before.\n const views = useMemo(() => {\n if (!viewRegistry) return undefined;\n return {\n targets: () => viewRegistry.list().map((r) => ({ id: r.id, ...r.target })),\n resolver: viewRegistry.resolver,\n };\n }, [viewRegistry]);\n\n // Hover cursors live in `useGestureDispatcher`'s hover-cursor pump:\n // affordance hits carry `AffordanceHit.cursor` (set by `buildAffordanceAt`),\n // and everything else is predicted via `Dispatcher.resolveOnly` +\n // `Action.cursor`. Nothing SceneCanvas-specific remains here.\n useGestureDispatcher({\n canvasRef,\n actions: registry!,\n entriesById,\n enabled,\n keyboard,\n affordanceAt: affordanceWithLayers,\n classifyTarget,\n dispatcher,\n clientToWorld,\n requestRedraw,\n paintedCursor,\n getRuleCtx,\n onDoubleClick,\n longPress,\n ...(views ? { views } : {}),\n });\n useDepSource('longPress', () => longPressState);\n return null;\n}\n\n/**\n * Registers the kit's default action set into this canvas's input scope.\n *\n * For `delete`, `duplicate`, `group`, and `ungroup` the descriptor's\n * invoker is a stub (those deps aren't in `DepSchema` yet — Phase 4 T8\n * TODO). This component registers legacy bridge overrides for them so the\n * consumer-facing `run` path is functional. The overrides land after the\n * descriptor registrations (last-writer-wins) and use the same id, so the\n * dispatcher and keybinding system see a real `run` body.\n */\nfunction StandardActionsRegistrar({\n selection,\n scene,\n adapter,\n actions,\n excludeActions,\n currentViewRef,\n onViewChange,\n resizeOptions,\n poseDescriptor,\n geometryProjection,\n dispatcher,\n getActionRef,\n pickEvery,\n layerIsPainted,\n alphaOf,\n viewportPanEnabled,\n viewportZoom,\n viewportPinchZoom,\n viewportRecenter,\n viewAnimation,\n editAnchorsExternalState,\n anchorEditingAllowed,\n poseComposition,\n layouts,\n layoutDropTarget,\n reflowTransition,\n insertNodeFactories,\n snapPoint,\n canvasRef,\n canvasApiRef,\n ingestionResolveSrc,\n ingestionSvg,\n ingestionClipboard,\n actionsRegistryRef,\n}: {\n selection: SelectionApi;\n scene: Scene<unknown, string, unknown>;\n adapter: BridgeAdapter;\n actionDefaults?: SceneCanvasProps<unknown, string, unknown>['actionDefaults'];\n actions?: ActionsProp;\n /** Kit-standard action ids this canvas's presets and tools leave out. */\n excludeActions: readonly string[];\n currentViewRef: React.RefObject<View>;\n onViewChange: (v: View) => void;\n /** Forwarded from `selectTool.resize` — wires the `resizePolicy` dep\n * consumed by the dispatcher-path `resizeAction`. The legacy\n * `useResizeTool` consumes the same options separately (both paths run\n * in parallel during the dispatcher migration). */\n resizeOptions?: UseResizeOptions<unknown>;\n /** Forwarded from `SceneCanvasProps.poseDescriptor` — wires the\n * `poseDescriptor` dep every built-in pose-touching action reads. */\n poseDescriptor: PoseDescriptor<unknown>;\n /** Forwarded from `SceneCanvasProps.geometryProjection` — wires the\n * `geometryProjection` dep consumed by pose-transform actions (move,\n * resize, nudge, flip). Conditionally mounted so absent → dep undefined. */\n geometryProjection?: GeometryProjection;\n /** Forwarded so `cancelGestureAction` and other actions that need to\n * abort in-flight handles can read the dispatcher's control surface. */\n dispatcher: Dispatcher;\n /** Ref populated with a live action-lookup function so the dispatcher's\n * `getAction` closure can resolve action ids after the registry is\n * mounted. Set on first render; cleared on unmount. */\n getActionRef: React.MutableRefObject<((id: string) => Action | undefined) | null>;\n /** World-space picker forwarded so the `nodeAtPoint` dep source can\n * reuse the same hit-test plumbing the tool dispatcher uses. */\n pickEvery: (worldX: number, worldY: number) => string[];\n /** This canvas's own view gate for scene layers, published on the `view`\n * dep and read by the selecting actions. Absent when it hides nothing. */\n layerIsPainted?: (layerId: string) => boolean;\n /** The composed paint alpha, when the consumer fades anything, so a region\n * select passes over what is painted at zero. */\n alphaOf?: (id: string) => number;\n /** Resolved `viewport.pan` flag — default true, false to disable. */\n viewportPanEnabled: boolean | WheelPanOptions;\n /** Resolved `viewport.zoom` setting — `true` (default Cmd+wheel zoom),\n * `false` (disabled), or a {@link ViewportZoomOptions} config. */\n viewportZoom: boolean | ViewportZoomOptions;\n /** Resolved `viewport.pinchZoom` setting — `true` (default two-finger pinch),\n * `false` (disabled), or a {@link PinchZoomOptions} scale clamp. */\n viewportPinchZoom: boolean | PinchZoomOptions;\n /** Optional recenter callback. When supplied, wires through to the\n * `view` dep so `viewport.zoom` reset (Cmd-0) calls it instead of\n * snapping to identity. A returned `View` is a target the kit may\n * animate to; `void` means the callback dispatched it itself. */\n viewportRecenter?: () => View | void;\n /** The canvas's camera runner, published on the `view` dep so\n * `viewport.zoom`'s discrete branches can animate. */\n viewAnimation: ViewAnimationApi;\n /** Lifted edit-mode state so the `pathEditingOverlay` chrome (rendered\n * outside this subtree) can read the same `editingId` the dep does. */\n editAnchorsExternalState: import('./deps/editAnchors').EditAnchorsStateRef;\n /** Present only when a mode registry is wired (`modes`); see\n * `EditAnchorsDepOptions.anchorEditingAllowed` for why absence — not a\n * predicate over an empty capability set — is the safe default. */\n anchorEditingAllowed?: () => boolean;\n /** Forwarded from `SceneCanvasProps` so the `layout` dep source can wire\n * the per-container layout strategy lookup consumed by `moveAction`. */\n layouts?: SceneCanvasProps<unknown, string, unknown>['layouts'];\n layoutDropTarget?: LayoutDropTargetMode;\n reflowTransition?: ReflowTransition<unknown> | null;\n /** Forwarded from `SceneCanvasProps` so the marquee and lasso dep sources\n * test where a node is drawn rather than where its pose is stored. */\n poseComposition?: SceneCanvasProps<unknown, string, unknown>['poseComposition'];\n /** Forwarded from `SceneCanvasProps` so `useInsertDepSource` can wire the\n * consumer's per-kind node factories into the `insert` dep. */\n insertNodeFactories?: Record<string, InsertNodeFactory>;\n /** Forwarded from `SceneCanvasProps.toolOptions.snapPoint` so the `snap`\n * dep source can expose grid snapping to `insertAction`. */\n snapPoint?: (p: { x: number; y: number }) => { x: number; y: number };\n /** The canvas element ref, so `useIngestionDepSource` can compute the\n * visible world rect from the client rect + current view. */\n canvasRef: React.RefObject<HTMLElement | null>;\n /** The canvas handle, whose debug sink backs the `debug` dep. */\n canvasApiRef: React.RefObject<CanvasExtensionApi | null>;\n /** Forwarded from `SceneCanvasProps.ingestion.resolveSrc` — consumer\n * file→src override for the kit image handler. */\n ingestionResolveSrc?: (file: File) => Promise<string>;\n /** Forwarded from `SceneCanvasProps.ingestion.svg` — kit SVG-handler\n * options (`unpack`). */\n ingestionSvg?: SvgIngestOptions;\n /** Clipboard-paste ctx (this canvas's adapter + the consumer's reviver)\n * for the kit weasel-JSON handler — built in SceneCanvasInner where the\n * typed adapter is in scope; absent when disabled. */\n ingestionClipboard?: ClipboardIngestCtx;\n /** Populated with the live registry so `CanvasExtensionApi.ingest`\n * (assembled in SceneCanvasInner, OUTSIDE the actions provider) can call\n * `registry.trigger('ingest', …)`. Cleared on unmount. */\n actionsRegistryRef: React.MutableRefObject<ActionsRegistry | null>;\n}) {\n const registry = useActionsRegistry();\n\n // Stash the registry for SceneCanvasInner's imperative `ingest` handle.\n useEffect(() => {\n actionsRegistryRef.current = registry;\n return () => { actionsRegistryRef.current = null; };\n }, [registry, actionsRegistryRef]);\n\n // Wire the dispatcher into the registry so registry.begin() can delegate\n // to dispatcher.beginUiOngoing() for UI-driven ongoing actions (color,\n // opacity).\n useEffect(() => {\n if (!registry) return;\n return registry.setDispatcher(dispatcher);\n }, [registry, dispatcher]);\n\n // Populate the action-lookup ref so the dispatcher's getAction closure\n // can resolve action ids once the registry is in scope.\n useEffect(() => {\n if (!registry) return;\n getActionRef.current = (id: string) => registry.list().find((a) => a.id === id);\n return () => { getActionRef.current = null; };\n }, [registry, getActionRef]);\n\n // Momentum for `viewport.dragPan`. The loop must be a hook (it owns a\n // `useVisibleRaf`), so it is built here and republished on the view dep.\n const decayLoop = useDecayLoop();\n\n // Build the ViewApi (stable identity, refreshed closures) and hand it to\n // useStandardActions (which publishes the `view` dep along with selection,\n // scene, history, pointer, activeTool). `hostSize` reads the live canvas\n // element so keyboard zoom (Cmd+=/-) can anchor at the visible center.\n const view = useViewDepSource(\n currentViewRef,\n onViewChange,\n viewportRecenter,\n () => {\n const el = canvasRef.current;\n return el ? { width: el.clientWidth, height: el.clientHeight } : null;\n },\n viewAnimation,\n decayLoop,\n layerIsPainted,\n );\n useStandardActions({ selection, scene, view, history: scene.history, exclude: excludeActions });\n // A view overlays `view` with its own camera; this name it leaves alone.\n useDepSource('rootView', () => view);\n const pointer = usePointerContext();\n useDepSource('pointer', () => pointer ?? undefined);\n\n // viewport.pan / viewport.zoom are SceneCanvas-coupled (need the `view` dep\n // published just above), so they're registered here rather than in\n // KIT_STANDARD_DESCRIPTORS. Both default ON; consumer opts out via\n // `viewport={{ pan: false }}` / `viewport={{ zoom: false }}`.\n useViewportActions({ pan: viewportPanEnabled, zoom: viewportZoom, pinchZoom: viewportPinchZoom });\n\n // Per-dep wiring modules under `src/canvas/deps/`. See each file for the\n // dep's contract and trade-offs.\n useAreaSelectDepSource(scene, selection, poseDescriptor, poseComposition, alphaOf);\n useNodeAtPointDepSource(pickEvery);\n useLayoutDepSource(scene, layouts, layoutDropTarget, reflowTransition);\n useLayoutArrivals(scene, { layouts, poseDescriptor, poseComposition });\n useInsertDepSource(scene, adapter, insertNodeFactories);\n useSliceDepSource(scene, selection, adapter, poseComposition, poseDescriptor);\n useSnapDepSource(snapPoint);\n useDebugDepSource(canvasApiRef);\n useIngestionDepSource(canvasRef, () => currentViewRef.current, ingestionResolveSrc, ingestionSvg, ingestionClipboard);\n useLassoSelectDepSource(scene, selection, poseDescriptor, poseComposition, alphaOf);\n useTextEditDepSource(scene);\n useEditAnchorsDepSource(scene, selection, adapter, editAnchorsExternalState, {\n anchorEditingAllowed,\n });\n useDispatcherDepSource(dispatcher);\n usePoseDescriptorDepSource(poseDescriptor);\n usePoseCompositionDepSource(poseComposition);\n\n // Keyed on the exclusion too: a re-registration of the standard set would\n // otherwise land over the overrides applied on top of it.\n useActionsPropResolver(actions, excludeActions.join('|'));\n\n // Gate the `resizePolicy` dep registration on the consumer having\n // passed `selectTool.resize`. When absent, consumers wire it via a child\n // component (see PointSnapDemo / GroupsDemo). Registering empty defaults\n // here would race with child-component registrations — React runs child\n // effects before parent effects, so the parent's empty default would\n // overwrite the child's real value. The conditional mount avoids that.\n //\n // Same pattern for `geometryProjection`: only mount when the consumer\n // passed the prop so absent → dep undefined → actions stay pose-only.\n return (\n <>\n {resizeOptions ? <ResizePolicyRegistrar options={resizeOptions} /> : null}\n {geometryProjection ? <GeometryProjectionRegistrar projection={geometryProjection} /> : null}\n </>\n );\n}\n\n/** Subcomponent so we can conditionally render (and thus conditionally\n * call) `useResizePolicy`. See parent's comment for why this\n * must be gated rather than always-on. */\nfunction ResizePolicyRegistrar({\n options,\n}: {\n options: UseResizeOptions<unknown>;\n}) {\n useResizePolicy<unknown>(resizePolicyOptions(options));\n return null;\n}\n\n/** Subcomponent so we can conditionally render (and thus conditionally\n * call) `useGeometryProjection`. Mirrors `ResizePolicyRegistrar` — the\n * conditional mount ensures the dep is registered only when the consumer\n * supplies a projection, so absent → dep undefined → actions stay pose-only. */\nfunction GeometryProjectionRegistrar({\n projection,\n}: {\n projection: GeometryProjection;\n}) {\n useGeometryProjection(projection);\n return null;\n}\n\nconst SceneCanvasInnerForwardRef = forwardRef(SceneCanvasInner);\n\n// The canvas's input scope sits above `SceneCanvasInner`, whose own hooks\n// (`useTools` among them) must already read this canvas's tool and registries.\nfunction SceneCanvasWrapper<TData, TLayer extends string, TPose>(\n props: SceneCanvasProps<TData, TLayer, TPose>,\n ref: React.ForwardedRef<SceneCanvasApi>,\n) {\n return (\n <InputScope yoke={props.yoke}>\n <ViewRegistryProvider>\n <SceneCanvasInnerForwardRef {...(props as SceneCanvasProps<unknown, string, unknown>)} ref={ref} />\n </ViewRegistryProvider>\n </InputScope>\n );\n}\n\n/**\n * The canvas component: renders a `Scene` and wires the interaction stack\n * around it.\n *\n * Mounted bare it renders the scene, keeps a selection no input sets, and\n * runs a gesture dispatcher for whatever bindings the consumer adds. The\n * `features` presets turn the kit's behavior on — `features={['draw']}` is the\n * whole editor: tools, standard actions and their keys, selection chrome,\n * undo. This is the intended entry point; the lower-level primitives it\n * composes are not part of the public surface.\n *\n * Its ref exposes a `SceneCanvasApi` for the imperative operations that do not\n * fit a prop (view control, hit queries, redraw requests).\n */\nexport const SceneCanvas = forwardRef(SceneCanvasWrapper) as <\n TData, TLayer extends string, TPose,\n>(\n props: SceneCanvasProps<TData, TLayer, TPose> & { ref?: React.Ref<SceneCanvasApi> },\n) => ReturnType<typeof SceneCanvasInner>;\n"],"mappings":"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"}
@@ -0,0 +1,54 @@
1
+ import { normalizeView as e } from "../core/viewport/view.js";
2
+ import { useLateContentRedraw as t } from "./useLateContentRedraw.js";
3
+ import { useFrameLoop as n } from "./useFrameLoop.js";
4
+ import { useCanvasRenderer as r } from "./useCanvasRenderer.js";
5
+ import { sceneViewFrame as i } from "./sceneViewRender.js";
6
+ import { useCallback as a, useEffect as o, useLayoutEffect as s, useRef as c, useSyncExternalStore as l } from "react";
7
+ import { useLatest as u } from "@weasel-js/react";
8
+ import { jsx as d } from "react/jsx-runtime";
9
+ //#region src/canvas/SceneViewCanvas.tsx
10
+ function f(f) {
11
+ let { scene: p, width: m, height: h, drawOne: g, extraCommands: _, alphaFor: v, layerVisibility: y, layerOrder: b, animator: x, className: S, canvasRef: C, cull: w, paintBounds: T } = f, E = e(f.view);
12
+ l(p.subscribe, p.getVersion, p.getVersion);
13
+ let D = c(null), O = (e) => {
14
+ D.current = e, typeof C == "function" ? C(e) : C && typeof C == "object" && (C.current = e);
15
+ }, { paint: k } = r(), A = u(() => {
16
+ let e = D.current;
17
+ if (!e) return !1;
18
+ let t = i({
19
+ scene: p,
20
+ view: E,
21
+ width: m,
22
+ height: h,
23
+ drawOne: g,
24
+ extraCommands: _,
25
+ alphaFor: v,
26
+ layerVisibility: y,
27
+ layerOrder: b,
28
+ colorOverrides: x?.colorOverrides,
29
+ cull: w,
30
+ paintBounds: T
31
+ });
32
+ return k(e, t, E, {
33
+ width: m,
34
+ height: h
35
+ }), !0;
36
+ }), { requestRedraw: j } = n(a(() => A.current(), [A])), M = c(!1);
37
+ return s(() => {
38
+ if (M.current) {
39
+ j();
40
+ return;
41
+ }
42
+ M.current = A.current(), M.current || j();
43
+ }), o(() => p.overrides.subscribe(j), [p, j]), o(() => x?.onTick(j), [x, j]), t(j), /* @__PURE__ */ d("canvas", {
44
+ ref: O,
45
+ width: m,
46
+ height: h,
47
+ className: S
48
+ });
49
+ }
50
+ var p = f;
51
+ //#endregion
52
+ export { p as SceneViewCanvas };
53
+
54
+ //# sourceMappingURL=SceneViewCanvas.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SceneViewCanvas.js","names":["SceneViewCanvasInner","props","view","normalizeView","scene","localRef","useRef","setCanvasRef","el","canvasRef","paintCanvas","useCanvasRenderer","paintRef","useLatest","canvas","commands","sceneViewFrame","animator","useFrameLoop","useCallback","paintedRef","useLayoutEffect","requestRedraw","useEffect","useLateContentRedraw","SceneViewCanvas"],"sources":["../../src/canvas/SceneViewCanvas.tsx"],"sourcesContent":["/**\n * `<SceneViewCanvas>` — pointer-inert, read-only render of a `Scene` at a\n * given `View` into its own `<canvas>` DOM element.\n *\n * The component:\n * - mounts its own `<canvas>`,\n * - subscribes to the scene via `useSyncExternalStore(scene.subscribe,\n * scene.getVersion)` so any scene mutation triggers a re-render,\n * - subscribes to `scene.overrides` as well, since override writes never\n * bump the scene version — without this the view would paint document\n * poses while `<SceneCanvas>` paints overridden ones,\n * - paints through `useFrameLoop` rather than from React, so both a render\n * (prop change or version bump) and an override commit just mark the\n * surface dirty and one `requestAnimationFrame` coalesces them. The mount\n * paint is synchronous so the first frame the user sees is the scene, not\n * a blank canvas,\n * - attaches **no** event listeners (consumers attach their own via\n * `canvasRef`),\n * - frees its renderer and every GL object it owns on unmount\n * (`useCanvasRenderer`).\n *\n * Sizing follows `<SceneCanvas>`'s convention: the consumer passes `width` /\n * `height` in CSS pixels. The HTML `width` / `height` attributes of the\n * `<canvas>` (drawing-buffer size) are set to `width × dpr` and `height × dpr`\n * by the canvas renderer (via the underlying renderer's `resize`). The CSS\n * size — what the consumer sees on screen — is managed via the `className`\n * prop; no inline styles are emitted (per project rules).\n */\nimport {\n useCallback,\n useEffect,\n useLayoutEffect,\n useRef,\n useSyncExternalStore,\n} from 'react';\nimport type { Ref } from 'react';\nimport { useLatest } from '@weasel-js/react';\nimport { useFrameLoop } from './useFrameLoop';\nimport { useLateContentRedraw } from './useLateContentRedraw';\nimport { useCanvasRenderer } from './useCanvasRenderer';\nimport { sceneViewFrame } from './sceneViewRender';\nimport type { RenderSceneToCanvasArgs, SceneViewDrawOne, SceneViewLayers } from './sceneViewRender';\nimport type { DrawCommand } from '../renderer/DrawCommand';\nimport { normalizeView, type View } from '../core/viewport/view';\nimport type { Scene } from '../core/scene/types';\nimport type { Animator } from '../animation/types';\n\n/** Props for `<SceneViewCanvas>`. */\nexport interface SceneViewCanvasProps<TData, TLayer extends string, TPose> {\n /** Scene to render. Must be the same `Scene` instance passed to whoever\n * is mutating it; the component subscribes to its version stream and\n * repaints when the version advances. */\n scene: Scene<TData, TLayer, TPose>;\n /** Camera. Applied to scene + `extraCommands` via the renderer's group\n * transform. */\n view: View;\n /** CSS-pixel width. Drives both layout (via the rendered drawing-buffer\n * size) and the renderer's coordinate space. */\n width: number;\n /** CSS-pixel height. */\n height: number;\n /** Per-node draw callback. See `SceneViewDrawOne`. The consumer is\n * responsible for what gets painted — there is no AABB-fill default. */\n drawOne: SceneViewDrawOne<TData, TLayer, TPose>;\n /** Optional extra commands appended after scene commands, inside the same\n * view transform. Used by `<MinimapCanvas>` for its visible-window\n * indicator; available to other consumers that want to overlay a\n * world-space annotation. */\n extraCommands?: ReadonlyArray<DrawCommand>;\n /** Optional per-id alpha multiplier, mirroring `<SceneCanvas>`'s scene-slot\n * `alphaFor`. Pass the same function the main canvas uses to keep a\n * scoping-dim treatment consistent across both. Defaults to `() => 1`. */\n alphaFor?: (id: string) => number;\n /** Hide scene layers in this view only, keyed `scene:<layerId>` as on\n * `<SceneCanvas>` — pass the main canvas's map to keep the two in step. */\n layerVisibility?: SceneViewLayers['layerVisibility'];\n /** Paint order for this view, keyed as `layerVisibility`. */\n layerOrder?: SceneViewLayers['layerOrder'];\n /** Skip nodes and commands that cannot reach this view — the scene slot's\n * `cull`. Off by default; worth it when the view shows a small part of a\n * large scene. */\n cull?: boolean;\n /** Where `drawOne`'s output for a node can reach — the scene slot's\n * `paintBounds`. Defaults to `defaultPaintBounds` when `drawOne` is\n * `defaultDrawOne`. */\n paintBounds?: RenderSceneToCanvasArgs<TData, TLayer, TPose>['paintBounds'];\n /** Optional animator, as on `<SceneCanvas>`: the view repaints on its ticks\n * and paints its `colorOverrides`. Pass the main canvas's animator so both\n * show the same colors. */\n animator?: Animator;\n /** Optional CSS class for sizing / positioning the `<canvas>`. The kit\n * does not emit inline styles for layout — use a class. */\n className?: string;\n /** Forwarded ref to the underlying `<canvas>`. Consumers attach their own\n * pointer listeners or call `toBlob` for snapshots through this. */\n canvasRef?: Ref<HTMLCanvasElement>;\n}\n\nfunction SceneViewCanvasInner<TData, TLayer extends string, TPose>(\n props: SceneViewCanvasProps<TData, TLayer, TPose>,\n) {\n const {\n scene, width, height, drawOne, extraCommands, alphaFor, layerVisibility, layerOrder,\n animator, className, canvasRef, cull, paintBounds,\n } = props;\n const view = normalizeView(props.view);\n\n // Subscribe to scene version. The snapshot value isn't used directly —\n // we only need React to re-render the component when the scene mutates.\n useSyncExternalStore(scene.subscribe, scene.getVersion, scene.getVersion);\n\n const localRef = useRef<HTMLCanvasElement | null>(null);\n\n // Forward the canvas element to the caller's ref. `useImperativeHandle`-on-\n // ref isn't quite right for a plain element; instead, we expose the same\n // element via a callback ref pattern by writing through to the consumer-\n // supplied ref each time React attaches the canvas.\n const setCanvasRef = (el: HTMLCanvasElement | null): void => {\n localRef.current = el;\n if (typeof canvasRef === 'function') {\n canvasRef(el);\n } else if (canvasRef && typeof canvasRef === 'object') {\n (canvasRef as { current: HTMLCanvasElement | null }).current = el;\n }\n };\n\n // The frame loop paints, not React — so an override commit can repaint\n // without a render. The thunk defers to `paintRef`, which every committed\n // render republishes from an insertion effect — ahead of the layout effect\n // below, and never from a render React abandoned.\n const { paint: paintCanvas } = useCanvasRenderer();\n const paint = (): boolean => {\n const canvas = localRef.current;\n if (!canvas) return false;\n const commands = sceneViewFrame({\n scene,\n view,\n width,\n height,\n drawOne,\n extraCommands: extraCommands as DrawCommand[] | undefined,\n alphaFor,\n layerVisibility,\n layerOrder,\n colorOverrides: animator?.colorOverrides,\n cull,\n paintBounds,\n });\n paintCanvas(canvas, commands, view, { width, height });\n return true;\n };\n const paintRef = useLatest(paint);\n\n const { requestRedraw } = useFrameLoop(useCallback(() => paintRef.current(), [paintRef]));\n\n // Every render — a prop change or a scene-version bump — marks the surface\n // dirty. No dependency array: the paint reads all of them.\n //\n // The mount paint is the exception: it runs here, in the caller's stack, so\n // the first frame the user sees is the scene rather than a blank canvas.\n const paintedRef = useRef(false);\n useLayoutEffect(() => {\n if (paintedRef.current) { requestRedraw(); return; }\n paintedRef.current = paintRef.current();\n if (!paintedRef.current) requestRedraw();\n });\n\n // Override writes never bump the scene version, so the version subscription\n // above cannot see them.\n useEffect(() => scene.overrides.subscribe(requestRedraw), [scene, requestRedraw]);\n useEffect(() => animator?.onTick(requestRedraw), [animator, requestRedraw]);\n useLateContentRedraw(requestRedraw);\n\n return (\n <canvas\n ref={setCanvasRef}\n width={width}\n height={height}\n className={className}\n />\n );\n}\n\n/**\n * Pointer-inert read-only scene view. See `SceneViewCanvasProps` for the\n * full surface and the module docstring for the rendering model.\n *\n * `forwardRef` is not used because the component is generic over `<TData,\n * TLayer, TPose>` and React's `forwardRef` erases generics. The\n * `canvasRef` prop is the plain-prop equivalent (the spec calls it out as\n * the public surface).\n */\nexport const SceneViewCanvas = SceneViewCanvasInner;\n"],"mappings":";;;;;;;;;AAkGA,SAASA,EACP,GACA;CACA,IAAM,EACJ,UAAO,UAAO,WAAQ,YAAS,kBAAe,aAAU,oBAAiB,eACzE,aAAU,cAAW,cAAW,SAAM,mBACpCC,GACEC,IAAOC,EAAcF,EAAM,IAAI;CAIrC,EAAqBG,EAAM,WAAWA,EAAM,YAAYA,EAAM,UAAU;CAExE,IAAMC,IAAWC,EAAiC,IAAI,GAMhDC,KAAgB,MAAuC;EAE3D,AADA,EAAS,UAAUC,GACf,OAAOC,KAAc,aACvBA,EAAUD,CAAE,IACHC,KAAa,OAAOA,KAAc,aAC3C,EAAqD,UAAUD;CAEnE,GAMM,EAAE,OAAOE,MAAgBC,EAAkB,GAqB3CC,IAAWC,QApBY;EAC3B,IAAMC,IAAST,EAAS;EACxB,IAAI,CAACS,GAAQ,OAAO;EACpB,IAAMC,IAAWC,EAAe;GAC9B;GACA;GACA;GACA;GACA;GACe;GACf;GACA;GACA;GACA,gBAAgBC,GAAU;GAC1B;GACA;EACF,CAAC;EAED,OADAP,EAAYI,GAAQC,GAAUb,GAAM;GAAE;GAAO;EAAO,CAAC,GAC9C;CACT,CACgC,GAE1B,EAAE,qBAAkBgB,EAAaC,QAAkBP,EAAS,QAAQ,GAAG,CAACA,CAAQ,CAAC,CAAC,GAOlFQ,IAAad,EAAO,EAAK;CAa/B,OAZAe,QAAsB;EACpB,IAAID,EAAW,SAAS;GAAE,EAAc;GAAG;EAAQ;EAEnD,AADA,EAAW,UAAUR,EAAS,QAAQ,GACjCQ,EAAW,WAASE,EAAc;CACzC,CAAC,GAIDC,QAAgBnB,EAAM,UAAU,UAAUkB,CAAa,GAAG,CAAClB,GAAOkB,CAAa,CAAC,GAChFC,QAAgBN,GAAU,OAAOK,CAAa,GAAG,CAACL,GAAUK,CAAa,CAAC,GAC1EE,EAAqBF,CAAa,GAGhC,kBAAC,UAAD;EACE,KAAKf;EACE;EACC;EACG;CACZ,CAAA;AAEL;AAWA,IAAakB,IAAkBzB"}
@@ -0,0 +1,9 @@
1
+ //#region src/canvas/accentColor.ts
2
+ var e = "#4c8dff";
3
+ function t(t) {
4
+ return !t || typeof getComputedStyle != "function" ? e : getComputedStyle(t).getPropertyValue("--wzl-accent").trim() || e;
5
+ }
6
+ //#endregion
7
+ export { e as FALLBACK_ACCENT, t as accentColorOf };
8
+
9
+ //# sourceMappingURL=accentColor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"accentColor.js","names":["FALLBACK_ACCENT","accentColorOf","el"],"sources":["../../src/canvas/accentColor.ts"],"sourcesContent":["/** The accent canvas chrome paints in when the element sits under no theme. */\nexport const FALLBACK_ACCENT = '#4c8dff';\n\n/** Read `--wzl-accent` off `el`, where the theme cascade lands on a canvas. */\nexport function accentColorOf(el: Element | null | undefined): string {\n if (!el || typeof getComputedStyle !== 'function') return FALLBACK_ACCENT;\n return getComputedStyle(el).getPropertyValue('--wzl-accent').trim() || FALLBACK_ACCENT;\n}\n"],"mappings":";AACA,IAAaA,IAAkB;AAG/B,SAAgBC,EAAc,GAAwC;CAEpE,OADI,CAACC,KAAM,OAAO,oBAAqB,aAAmBF,IACnD,iBAAiBE,CAAE,CAAC,CAAC,iBAAiB,cAAc,CAAC,CAAC,KAAK,KAAKF;AACzE"}