@weasel-js/core 1.9.3 → 1.9.4

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 (542) hide show
  1. package/CHANGELOG.md +356 -0
  2. package/README.md +2 -2
  3. package/dist/WeaselProvider.js +5 -5
  4. package/dist/affordances/composeAffordanceLayer.js +10 -20
  5. package/dist/affordances/composeAffordanceLayer.js.map +1 -1
  6. package/dist/affordances/cornerResize.js +25 -17
  7. package/dist/affordances/cornerResize.js.map +1 -1
  8. package/dist/affordances/hitAffordanceRegions.js +27 -20
  9. package/dist/affordances/hitAffordanceRegions.js.map +1 -1
  10. package/dist/affordances/rotationHandle.js +18 -18
  11. package/dist/affordances/rotationHandle.js.map +1 -1
  12. package/dist/animation/behaviors/momentum.js +93 -55
  13. package/dist/animation/behaviors/momentum.js.map +1 -1
  14. package/dist/animation/loop.js +10 -12
  15. package/dist/animation/loop.js.map +1 -1
  16. package/dist/animation/reflow.js +8 -8
  17. package/dist/animation/reflow.js.map +1 -1
  18. package/dist/animation/stagger.js +64 -56
  19. package/dist/animation/stagger.js.map +1 -1
  20. package/dist/animation/timeline/booking.js +62 -54
  21. package/dist/animation/timeline/booking.js.map +1 -1
  22. package/dist/animation/timeline/createTimeline.js +85 -76
  23. package/dist/animation/timeline/createTimeline.js.map +1 -1
  24. package/dist/animation/timeline/sampleTrack.js +13 -5
  25. package/dist/animation/timeline/sampleTrack.js.map +1 -1
  26. package/dist/animation/useAnimator.js +45 -35
  27. package/dist/animation/useAnimator.js.map +1 -1
  28. package/dist/animation/wrappers/animateLifecycle.js +31 -24
  29. package/dist/animation/wrappers/animateLifecycle.js.map +1 -1
  30. package/dist/animation/wrappers/animateOnSetPose.js +28 -26
  31. package/dist/animation/wrappers/animateOnSetPose.js.map +1 -1
  32. package/dist/animation/wrappers/instantPose.js +13 -0
  33. package/dist/animation/wrappers/instantPose.js.map +1 -0
  34. package/dist/{poseDescriptor-D-OH-tu5.d.ts → autoPoseDescriptor-Ct7yqivU.d.ts} +28 -3
  35. package/dist/barrel/chrome.js +16 -0
  36. package/dist/barrel/input.js +19 -0
  37. package/dist/barrel/interactions.js +42 -0
  38. package/dist/barrel/paint.js +18 -0
  39. package/dist/barrel/paths.js +19 -0
  40. package/dist/barrel/renderer.js +20 -0
  41. package/dist/barrel/routing.js +51 -0
  42. package/dist/barrel/text.js +18 -0
  43. package/dist/barrel/viewport.js +52 -0
  44. package/dist/builtins-DPcdghtB.d.ts +1223 -0
  45. package/dist/canvas/Canvas.js +363 -448
  46. package/dist/canvas/Canvas.js.map +1 -1
  47. package/dist/canvas/CanvasView.js +164 -165
  48. package/dist/canvas/CanvasView.js.map +1 -1
  49. package/dist/canvas/CursorCoordsHud.js +37 -32
  50. package/dist/canvas/CursorCoordsHud.js.map +1 -1
  51. package/dist/canvas/DrawCanvas.js +49 -43
  52. package/dist/canvas/DrawCanvas.js.map +1 -1
  53. package/dist/canvas/MinimapCanvas.js +26 -25
  54. package/dist/canvas/MinimapCanvas.js.map +1 -1
  55. package/dist/canvas/NodeShape.js +59 -377
  56. package/dist/canvas/NodeShape.js.map +1 -1
  57. package/dist/canvas/PickHud.js +50 -47
  58. package/dist/canvas/PickHud.js.map +1 -1
  59. package/dist/canvas/SceneCanvas/GestureDispatcherMounter.js +167 -0
  60. package/dist/canvas/SceneCanvas/GestureDispatcherMounter.js.map +1 -0
  61. package/dist/canvas/SceneCanvas/PointerProviderIfRoot.js +13 -13
  62. package/dist/canvas/SceneCanvas/StandardActionsRegistrar.js +67 -0
  63. package/dist/canvas/SceneCanvas/StandardActionsRegistrar.js.map +1 -0
  64. package/dist/canvas/SceneCanvas/ToolKeybindingsMounter.js +16 -0
  65. package/dist/canvas/SceneCanvas/ToolKeybindingsMounter.js.map +1 -0
  66. package/dist/canvas/SceneCanvas/coordTrace.js +10 -0
  67. package/dist/canvas/SceneCanvas/coordTrace.js.map +1 -0
  68. package/dist/canvas/SceneCanvas/defaultNodeProperties.js +112 -70
  69. package/dist/canvas/SceneCanvas/defaultNodeProperties.js.map +1 -1
  70. package/dist/canvas/SceneCanvas/defaultNodeRouting.js +9 -8
  71. package/dist/canvas/SceneCanvas/defaultNodeRouting.js.map +1 -1
  72. package/dist/canvas/SceneCanvas/features.js +1 -0
  73. package/dist/canvas/SceneCanvas/features.js.map +1 -1
  74. package/dist/canvas/SceneCanvas/isDev.js +12 -0
  75. package/dist/canvas/SceneCanvas/isDev.js.map +1 -0
  76. package/dist/canvas/SceneCanvas/poseGeometry.js +29 -28
  77. package/dist/canvas/SceneCanvas/poseGeometry.js.map +1 -1
  78. package/dist/canvas/SceneCanvas/poseRegistrars.js +13 -0
  79. package/dist/canvas/SceneCanvas/poseRegistrars.js.map +1 -0
  80. package/dist/canvas/SceneCanvas/props.js +38 -0
  81. package/dist/canvas/SceneCanvas/props.js.map +1 -0
  82. package/dist/canvas/SceneCanvas/useBuiltinShapeTools.js +21 -62
  83. package/dist/canvas/SceneCanvas/useBuiltinShapeTools.js.map +1 -1
  84. package/dist/canvas/SceneCanvas/useDispatcherOverlayLayer.js.map +1 -1
  85. package/dist/canvas/SceneCanvas/usePreviewGhostLayer.js +46 -48
  86. package/dist/canvas/SceneCanvas/usePreviewGhostLayer.js.map +1 -1
  87. package/dist/canvas/SceneCanvas/useSceneSelectTool.js +33 -33
  88. package/dist/canvas/SceneCanvas/useSceneSelectTool.js.map +1 -1
  89. package/dist/canvas/SceneCanvas.js +534 -788
  90. package/dist/canvas/SceneCanvas.js.map +1 -1
  91. package/dist/canvas/SceneViewCanvas.js +45 -43
  92. package/dist/canvas/SceneViewCanvas.js.map +1 -1
  93. package/dist/canvas/buildSceneLayer.js +91 -0
  94. package/dist/canvas/buildSceneLayer.js.map +1 -0
  95. package/dist/canvas/buildSceneTree.js +16 -19
  96. package/dist/canvas/buildSceneTree.js.map +1 -1
  97. package/dist/canvas/canvasRenderer.js +68 -52
  98. package/dist/canvas/canvasRenderer.js.map +1 -1
  99. package/dist/canvas/deps/changes.js +13 -0
  100. package/dist/canvas/deps/changes.js.map +1 -0
  101. package/dist/canvas/deps/editAnchors.js +28 -28
  102. package/dist/canvas/deps/insert.js +119 -91
  103. package/dist/canvas/deps/insert.js.map +1 -1
  104. package/dist/canvas/deps/slice.js +46 -45
  105. package/dist/canvas/deps/slice.js.map +1 -1
  106. package/dist/canvas/deps/textEdit.js +10 -9
  107. package/dist/canvas/deps/textEdit.js.map +1 -1
  108. package/dist/canvas/derivedPath.js +46 -23
  109. package/dist/canvas/derivedPath.js.map +1 -1
  110. package/dist/canvas/getNodeAtPoint.js +7 -7
  111. package/dist/canvas/getNodeAtPoint.js.map +1 -1
  112. package/dist/canvas/hud.module.js +1 -1
  113. package/dist/canvas/hud.module.js.map +1 -1
  114. package/dist/canvas/kitRequirements.js +2 -2
  115. package/dist/canvas/kitRequirements.js.map +1 -1
  116. package/dist/canvas/layerOrder.js +13 -6
  117. package/dist/canvas/layerOrder.js.map +1 -1
  118. package/dist/canvas/minimapMath.js +12 -10
  119. package/dist/canvas/minimapMath.js.map +1 -1
  120. package/dist/canvas/nodeShapes/derivedPainter.js +34 -0
  121. package/dist/canvas/nodeShapes/derivedPainter.js.map +1 -0
  122. package/dist/canvas/nodeShapes/imagePainter.js +87 -0
  123. package/dist/canvas/nodeShapes/imagePainter.js.map +1 -0
  124. package/dist/canvas/nodeShapes/memo.js +9 -0
  125. package/dist/canvas/nodeShapes/memo.js.map +1 -0
  126. package/dist/canvas/nodeShapes/nodePaint.js +57 -0
  127. package/dist/canvas/nodeShapes/nodePaint.js.map +1 -0
  128. package/dist/canvas/nodeShapes/pathPainter.js +38 -0
  129. package/dist/canvas/nodeShapes/pathPainter.js.map +1 -0
  130. package/dist/canvas/nodeShapes/poseBox.js +20 -0
  131. package/dist/canvas/nodeShapes/poseBox.js.map +1 -0
  132. package/dist/canvas/nodeShapes/rectFallbackPainter.js +38 -0
  133. package/dist/canvas/nodeShapes/rectFallbackPainter.js.map +1 -0
  134. package/dist/canvas/nodeShapes/shapePainter.js +72 -0
  135. package/dist/canvas/nodeShapes/shapePainter.js.map +1 -0
  136. package/dist/canvas/nodeShapes/textPainter.js +55 -0
  137. package/dist/canvas/nodeShapes/textPainter.js.map +1 -0
  138. package/dist/canvas/overlayRoleStrokes.js.map +1 -1
  139. package/dist/canvas/paintCull.js +10 -11
  140. package/dist/canvas/paintCull.js.map +1 -1
  141. package/dist/canvas/pickWalk.js +52 -63
  142. package/dist/canvas/pickWalk.js.map +1 -1
  143. package/dist/canvas/poseRotation.js +11 -23
  144. package/dist/canvas/poseRotation.js.map +1 -1
  145. package/dist/canvas/renderDebugSnapshot.js +5 -5
  146. package/dist/canvas/renderSceneToPixels.js +3 -1
  147. package/dist/canvas/renderSceneToPixels.js.map +1 -1
  148. package/dist/canvas/sceneAdapter.js +66 -148
  149. package/dist/canvas/sceneAdapter.js.map +1 -1
  150. package/dist/canvas/sceneClipboard.js +112 -0
  151. package/dist/canvas/sceneClipboard.js.map +1 -0
  152. package/dist/canvas/sceneSlotWiring.js +4 -4
  153. package/dist/canvas/sceneSlotWiring.js.map +1 -1
  154. package/dist/canvas/sceneViewRender.js +39 -40
  155. package/dist/canvas/sceneViewRender.js.map +1 -1
  156. package/dist/canvas/useCanvasRenderer.js +14 -6
  157. package/dist/canvas/useCanvasRenderer.js.map +1 -1
  158. package/dist/canvas/useCanvasView.js +58 -0
  159. package/dist/canvas/useCanvasView.js.map +1 -0
  160. package/dist/canvas/useFrameLoop.js +35 -26
  161. package/dist/canvas/useFrameLoop.js.map +1 -1
  162. package/dist/canvas/useSceneLayerList.js +21 -0
  163. package/dist/canvas/useSceneLayerList.js.map +1 -0
  164. package/dist/clipboard.d.ts +10 -6
  165. package/dist/clone.d.ts +4 -3
  166. package/dist/core/adapters/arrayAdapter.js +48 -39
  167. package/dist/core/adapters/arrayAdapter.js.map +1 -1
  168. package/dist/core/device/index.js +5 -4
  169. package/dist/core/device/useDeviceProfile.js +38 -44
  170. package/dist/core/device/useDeviceProfile.js.map +1 -1
  171. package/dist/core/device/watchDevicePixelRatio.js +17 -0
  172. package/dist/core/device/watchDevicePixelRatio.js.map +1 -0
  173. package/dist/core/fillInPoseFrame.js.map +1 -1
  174. package/dist/core/geometry/poseDescriptor.js +21 -19
  175. package/dist/core/geometry/poseDescriptor.js.map +1 -1
  176. package/dist/core/geometry/poseFrame.js +44 -0
  177. package/dist/core/geometry/poseFrame.js.map +1 -0
  178. package/dist/core/geometry/poseRotation.js.map +1 -1
  179. package/dist/core/geometry/regionHit.js +9 -10
  180. package/dist/core/geometry/regionHit.js.map +1 -1
  181. package/dist/core/geometry/unionBounds.js +31 -29
  182. package/dist/core/geometry/unionBounds.js.map +1 -1
  183. package/dist/core/isPlainObject.js +2 -11
  184. package/dist/core/ops/arrange.js +1 -0
  185. package/dist/core/ops/arrange.js.map +1 -1
  186. package/dist/core/ops/create.js +10 -5
  187. package/dist/core/ops/create.js.map +1 -1
  188. package/dist/core/ops/delete.js +12 -24
  189. package/dist/core/ops/delete.js.map +1 -1
  190. package/dist/core/ops/reorder/index.js +43 -40
  191. package/dist/core/ops/reorder/index.js.map +1 -1
  192. package/dist/core/ops/reorder/setChildOrder.js +34 -0
  193. package/dist/core/ops/reorder/setChildOrder.js.map +1 -0
  194. package/dist/core/paintKinds.js +5 -5
  195. package/dist/core/paintKinds.js.map +1 -1
  196. package/dist/core/scene/NodeProperties.js.map +1 -1
  197. package/dist/core/scene/appliedLog.js +37 -0
  198. package/dist/core/scene/appliedLog.js.map +1 -0
  199. package/dist/core/scene/arrivalWindow.js +101 -0
  200. package/dist/core/scene/arrivalWindow.js.map +1 -0
  201. package/dist/core/scene/derivedPath.js.map +1 -1
  202. package/dist/core/scene/historyFacade.js +84 -0
  203. package/dist/core/scene/historyFacade.js.map +1 -0
  204. package/dist/core/scene/kitOps.js +173 -0
  205. package/dist/core/scene/kitOps.js.map +1 -0
  206. package/dist/core/scene/layerStack.js +38 -0
  207. package/dist/core/scene/layerStack.js.map +1 -0
  208. package/dist/core/scene/lockGuard.js +37 -0
  209. package/dist/core/scene/lockGuard.js.map +1 -0
  210. package/dist/core/scene/nodeFnFields.js +5 -6
  211. package/dist/core/scene/nodeFnFields.js.map +1 -1
  212. package/dist/core/scene/nodeMemo.js +45 -19
  213. package/dist/core/scene/nodeMemo.js.map +1 -1
  214. package/dist/core/scene/nodeStore.js +126 -0
  215. package/dist/core/scene/nodeStore.js.map +1 -0
  216. package/dist/core/scene/pickability.js +6 -0
  217. package/dist/core/scene/pickability.js.map +1 -0
  218. package/dist/core/scene/poseFeed.js +38 -38
  219. package/dist/core/scene/poseFeed.js.map +1 -1
  220. package/dist/core/scene/poseOverrides.js +34 -38
  221. package/dist/core/scene/poseOverrides.js.map +1 -1
  222. package/dist/core/scene/renderOrder.js +84 -0
  223. package/dist/core/scene/renderOrder.js.map +1 -0
  224. package/dist/core/scene/scene.js +289 -866
  225. package/dist/core/scene/scene.js.map +1 -1
  226. package/dist/core/scene/serialization.js +68 -0
  227. package/dist/core/scene/serialization.js.map +1 -0
  228. package/dist/core/scene/treeOrder.js +13 -0
  229. package/dist/core/scene/treeOrder.js.map +1 -0
  230. package/dist/core/scene/types.js.map +1 -1
  231. package/dist/core/viewport/meanScale.js +1 -1
  232. package/dist/core/viewport/meanScale.js.map +1 -1
  233. package/dist/core/viewport/view.js +12 -12
  234. package/dist/core/viewport/view.js.map +1 -1
  235. package/dist/core/viewport/zoomBounds.js +10 -8
  236. package/dist/core/viewport/zoomBounds.js.map +1 -1
  237. package/dist/{cornerHandles-BCrDp_mH.d.ts → cornerHandles-CtCb8a3G.d.ts} +1 -1
  238. package/dist/debug/createDebugOverlayLayer.js +14 -14
  239. package/dist/debug/createDebugOverlayLayer.js.map +1 -1
  240. package/dist/debug/flag.js +2 -41
  241. package/dist/features/chrome-caps/useHoverTracking.js +22 -17
  242. package/dist/features/chrome-caps/useHoverTracking.js.map +1 -1
  243. package/dist/features/focus/gateLayer.js +3 -4
  244. package/dist/features/focus/gateLayer.js.map +1 -1
  245. package/dist/features/images/imageCache.js +19 -9
  246. package/dist/features/images/imageCache.js.map +1 -1
  247. package/dist/features/ingestion/contentHandlers.js +14 -11
  248. package/dist/features/ingestion/contentHandlers.js.map +1 -1
  249. package/dist/features/ingestion/index.js +1 -1
  250. package/dist/features/ingestion/registerKitHandlers.js +7 -7
  251. package/dist/features/ingestion/weaselJsonHandler.js +17 -14
  252. package/dist/features/ingestion/weaselJsonHandler.js.map +1 -1
  253. package/dist/features/meshPaint/lazyKind.js +201 -35
  254. package/dist/features/meshPaint/lazyKind.js.map +1 -1
  255. package/dist/features/meshPaint/meshPaint.js +82 -79
  256. package/dist/features/meshPaint/meshPaint.js.map +1 -1
  257. package/dist/features/minimap/createMinimapContribution.js +42 -42
  258. package/dist/features/minimap/layers.js +44 -62
  259. package/dist/features/minimap/layers.js.map +1 -1
  260. package/dist/features/parallax/createParallaxPlane.js +10 -14
  261. package/dist/features/parallax/createParallaxPlane.js.map +1 -1
  262. package/dist/features/paths/anchorEdits.js +19 -8
  263. package/dist/features/paths/anchorEdits.js.map +1 -1
  264. package/dist/features/paths/anchors.js +31 -26
  265. package/dist/features/paths/anchors.js.map +1 -1
  266. package/dist/features/paths/booleans.js +2 -2
  267. package/dist/features/paths/index.js +13 -11
  268. package/dist/features/paths/markerCommands.js +37 -36
  269. package/dist/features/paths/markerCommands.js.map +1 -1
  270. package/dist/features/paths/pathInWorld.js +19 -19
  271. package/dist/features/paths/pathInWorld.js.map +1 -1
  272. package/dist/features/paths/pathLayer.js.map +1 -1
  273. package/dist/features/paths/strokeToPath.js +40 -0
  274. package/dist/features/paths/strokeToPath.js.map +1 -0
  275. package/dist/features/paths/tessellate/stroke.js.map +1 -1
  276. package/dist/features/patterns/commandPaint.js +18 -0
  277. package/dist/features/patterns/commandPaint.js.map +1 -0
  278. package/dist/features/patterns/index.js +5 -17
  279. package/dist/features/patterns/index.js.map +1 -1
  280. package/dist/features/patterns/rasterizeTile.js +17 -0
  281. package/dist/features/patterns/rasterizeTile.js.map +1 -0
  282. package/dist/features/patterns/resolveSpec.js +52 -44
  283. package/dist/features/patterns/resolveSpec.js.map +1 -1
  284. package/dist/features/poseRun/usePoseRun.js +8 -3
  285. package/dist/features/poseRun/usePoseRun.js.map +1 -1
  286. package/dist/features/selection/SelectionContext.js +5 -0
  287. package/dist/features/selection/SelectionContext.js.map +1 -1
  288. package/dist/features/selection/overlay.js +18 -18
  289. package/dist/features/selection/overlay.js.map +1 -1
  290. package/dist/features/text/domOffsets.js +82 -0
  291. package/dist/features/text/domOffsets.js.map +1 -0
  292. package/dist/features/text/domRuns.js +103 -131
  293. package/dist/features/text/domRuns.js.map +1 -1
  294. package/dist/features/text/hitTest.js +5 -2
  295. package/dist/features/text/hitTest.js.map +1 -1
  296. package/dist/features/text/isTextData.js +8 -0
  297. package/dist/features/text/isTextData.js.map +1 -0
  298. package/dist/features/text/overlayDirection.js +15 -0
  299. package/dist/features/text/overlayDirection.js.map +1 -0
  300. package/dist/features/text/runs/rangeStyle.js +32 -34
  301. package/dist/features/text/runs/rangeStyle.js.map +1 -1
  302. package/dist/features/text/textCommand.js +34 -33
  303. package/dist/features/text/textCommand.js.map +1 -1
  304. package/dist/features/text/textToPath.js +40 -40
  305. package/dist/features/text/textToPath.js.map +1 -1
  306. package/dist/features/text/useSceneTextEdit.js +76 -82
  307. package/dist/features/text/useSceneTextEdit.js.map +1 -1
  308. package/dist/features/text/useTextEdit.js +184 -160
  309. package/dist/features/text/useTextEdit.js.map +1 -1
  310. package/dist/features/tiling/createTiledLayer.js +24 -22
  311. package/dist/features/tiling/createTiledLayer.js.map +1 -1
  312. package/dist/index.d.ts +11033 -7749
  313. package/dist/index.js +316 -309
  314. package/dist/input/keyState.js +42 -43
  315. package/dist/input/keyState.js.map +1 -1
  316. package/dist/input/useKeyModifiers.js +11 -0
  317. package/dist/input/useKeyModifiers.js.map +1 -0
  318. package/dist/interactions/actions/align/align.js +8 -8
  319. package/dist/interactions/actions/clipboard/clipboardOps.js +34 -32
  320. package/dist/interactions/actions/clipboard/clipboardOps.js.map +1 -1
  321. package/dist/interactions/actions/clipboard/materializePaste.js +10 -7
  322. package/dist/interactions/actions/clipboard/materializePaste.js.map +1 -1
  323. package/dist/interactions/actions/clipboard/wireFormat.js.map +1 -1
  324. package/dist/interactions/actions/clone/behaviors/cloneByAltDrag.js.map +1 -1
  325. package/dist/interactions/actions/defaultCommitAdapter.js +20 -18
  326. package/dist/interactions/actions/defaultCommitAdapter.js.map +1 -1
  327. package/dist/interactions/actions/defaults/align.js +9 -10
  328. package/dist/interactions/actions/defaults/align.js.map +1 -1
  329. package/dist/interactions/actions/defaults/anchorEditing.js +59 -81
  330. package/dist/interactions/actions/defaults/anchorEditing.js.map +1 -1
  331. package/dist/interactions/actions/defaults/areaSelect.js +35 -38
  332. package/dist/interactions/actions/defaults/areaSelect.js.map +1 -1
  333. package/dist/interactions/actions/defaults/clipboard.js +26 -10
  334. package/dist/interactions/actions/defaults/clipboard.js.map +1 -1
  335. package/dist/interactions/actions/defaults/clone.js +44 -60
  336. package/dist/interactions/actions/defaults/clone.js.map +1 -1
  337. package/dist/interactions/actions/defaults/copySubtree.js +40 -0
  338. package/dist/interactions/actions/defaults/copySubtree.js.map +1 -0
  339. package/dist/interactions/actions/defaults/distribute.js +14 -13
  340. package/dist/interactions/actions/defaults/distribute.js.map +1 -1
  341. package/dist/interactions/actions/defaults/duplicate.js +17 -57
  342. package/dist/interactions/actions/defaults/duplicate.js.map +1 -1
  343. package/dist/interactions/actions/defaults/editAnchors.js +18 -18
  344. package/dist/interactions/actions/defaults/enterTextEdit.js.map +1 -1
  345. package/dist/interactions/actions/defaults/flip.js +52 -46
  346. package/dist/interactions/actions/defaults/flip.js.map +1 -1
  347. package/dist/interactions/actions/defaults/group.js +43 -48
  348. package/dist/interactions/actions/defaults/group.js.map +1 -1
  349. package/dist/interactions/actions/defaults/ingest.js +35 -33
  350. package/dist/interactions/actions/defaults/ingest.js.map +1 -1
  351. package/dist/interactions/actions/defaults/insert.js +50 -51
  352. package/dist/interactions/actions/defaults/insert.js.map +1 -1
  353. package/dist/interactions/actions/defaults/insertPathAnchor.js +7 -7
  354. package/dist/interactions/actions/defaults/lassoSelect.js +67 -70
  355. package/dist/interactions/actions/defaults/lassoSelect.js.map +1 -1
  356. package/dist/interactions/actions/defaults/move.js +267 -249
  357. package/dist/interactions/actions/defaults/move.js.map +1 -1
  358. package/dist/interactions/actions/defaults/nudge.js +40 -68
  359. package/dist/interactions/actions/defaults/nudge.js.map +1 -1
  360. package/dist/interactions/actions/defaults/nudgeSteps.js +37 -0
  361. package/dist/interactions/actions/defaults/nudgeSteps.js.map +1 -0
  362. package/dist/interactions/actions/defaults/reorder.js +2 -0
  363. package/dist/interactions/actions/defaults/reorder.js.map +1 -1
  364. package/dist/interactions/actions/defaults/resize.js +104 -98
  365. package/dist/interactions/actions/defaults/resize.js.map +1 -1
  366. package/dist/interactions/actions/defaults/rotate.js +111 -110
  367. package/dist/interactions/actions/defaults/rotate.js.map +1 -1
  368. package/dist/interactions/actions/defaults/setFill.js +7 -7
  369. package/dist/interactions/actions/defaults/setFillOpacity.js +4 -4
  370. package/dist/interactions/actions/defaults/setStroke.js +12 -12
  371. package/dist/interactions/actions/defaults/setStrokeOpacity.js +6 -6
  372. package/dist/interactions/actions/defaults/sliceOps.js +19 -19
  373. package/dist/interactions/actions/defaults/viewportDragPan.js +37 -26
  374. package/dist/interactions/actions/defaults/viewportDragPan.js.map +1 -1
  375. package/dist/interactions/actions/edit-anchors/geometry.js +28 -23
  376. package/dist/interactions/actions/edit-anchors/geometry.js.map +1 -1
  377. package/dist/interactions/actions/flip/helpers.js +30 -17
  378. package/dist/interactions/actions/flip/helpers.js.map +1 -1
  379. package/dist/interactions/actions/hitSelection.js +8 -0
  380. package/dist/interactions/actions/hitSelection.js.map +1 -0
  381. package/dist/interactions/actions/lasso-select/behaviors/selectFromLasso.js +14 -18
  382. package/dist/interactions/actions/lasso-select/behaviors/selectFromLasso.js.map +1 -1
  383. package/dist/interactions/actions/move/behaviors/snapBackOrDelete.js +5 -5
  384. package/dist/interactions/actions/move/behaviors/snapBackOrDelete.js.map +1 -1
  385. package/dist/interactions/actions/move/behaviors/snapToContainer.js +32 -21
  386. package/dist/interactions/actions/move/behaviors/snapToContainer.js.map +1 -1
  387. package/dist/interactions/actions/move/gestureAdapter.js +32 -15
  388. package/dist/interactions/actions/move/gestureAdapter.js.map +1 -1
  389. package/dist/interactions/actions/move/landedDescendants.js +33 -0
  390. package/dist/interactions/actions/move/landedDescendants.js.map +1 -0
  391. package/dist/interactions/actions/outlines/createOutlines.js +18 -18
  392. package/dist/interactions/actions/poseDescriptorDep.js +16 -4
  393. package/dist/interactions/actions/poseDescriptorDep.js.map +1 -1
  394. package/dist/interactions/actions/poseFrame.js +11 -6
  395. package/dist/interactions/actions/poseFrame.js.map +1 -1
  396. package/dist/interactions/actions/previewOverrides.js +5 -5
  397. package/dist/interactions/actions/previewOverrides.js.map +1 -1
  398. package/dist/interactions/actions/selectionSubtree.js +69 -0
  399. package/dist/interactions/actions/selectionSubtree.js.map +1 -0
  400. package/dist/interactions/actions/useStandardActions.js +66 -62
  401. package/dist/interactions/actions/useStandardActions.js.map +1 -1
  402. package/dist/interactions/gestures/dragGesture/dragGesture.js +4 -7
  403. package/dist/interactions/gestures/dragGesture/dragGesture.js.map +1 -1
  404. package/dist/interactions/gestures/dragGesture/dragPointOf.js +23 -0
  405. package/dist/interactions/gestures/dragGesture/dragPointOf.js.map +1 -0
  406. package/dist/interactions/gestures/handleDrag/handleDrag.js +21 -26
  407. package/dist/interactions/gestures/handleDrag/handleDrag.js.map +1 -1
  408. package/dist/interactions/gestures/pointerDrag/pointerDrag.js +8 -6
  409. package/dist/interactions/gestures/pointerDrag/pointerDrag.js.map +1 -1
  410. package/dist/interactions/gestures/thresholdDrag/thresholdDrag.js +8 -4
  411. package/dist/interactions/gestures/thresholdDrag/thresholdDrag.js.map +1 -1
  412. package/dist/{math-Drrw4ewZ.d.ts → math-J-ACHyEg.d.ts} +1 -2
  413. package/dist/math.d.ts +2 -3
  414. package/dist/move.d.ts +12 -11
  415. package/dist/{originProjection-DEklpDc_.d.ts → originProjection-gHnOup4e.d.ts} +1 -1
  416. package/dist/{registerProgram-BMZRDgrh.d.ts → registerProgram-T9S_PfAX.d.ts} +18 -7
  417. package/dist/renderer/DrawCommand.js.map +1 -1
  418. package/dist/renderer/WeaselRenderer.js +75 -73
  419. package/dist/renderer/WeaselRenderer.js.map +1 -1
  420. package/dist/renderer/cache/GLImageCache.js +15 -5
  421. package/dist/renderer/cache/GLImageCache.js.map +1 -1
  422. package/dist/renderer/cache/GLMeshCache.js +23 -23
  423. package/dist/renderer/cache/GLMeshCache.js.map +1 -1
  424. package/dist/renderer/cache/GLTextureCache.js +18 -1
  425. package/dist/renderer/cache/GLTextureCache.js.map +1 -1
  426. package/dist/renderer/cache/cache.js.map +1 -1
  427. package/dist/renderer/cache/markerCommandCache.js.map +1 -1
  428. package/dist/renderer/cache/strokeMeshCache.js.map +1 -1
  429. package/dist/renderer/cullDrawCommands.js +11 -11
  430. package/dist/renderer/draw/batch.js +133 -0
  431. package/dist/renderer/draw/batch.js.map +1 -0
  432. package/dist/renderer/draw/clip.js +89 -0
  433. package/dist/renderer/draw/clip.js.map +1 -0
  434. package/dist/renderer/draw/customShader.js +230 -0
  435. package/dist/renderer/draw/customShader.js.map +1 -0
  436. package/dist/renderer/draw/drawTriangles.js +8 -0
  437. package/dist/renderer/draw/drawTriangles.js.map +1 -0
  438. package/dist/renderer/draw/effects.js +28 -0
  439. package/dist/renderer/draw/effects.js.map +1 -0
  440. package/dist/renderer/draw/flushBatch.js +35 -0
  441. package/dist/renderer/draw/flushBatch.js.map +1 -0
  442. package/dist/renderer/draw/gradient.js +90 -0
  443. package/dist/renderer/draw/gradient.js.map +1 -0
  444. package/dist/renderer/draw/image.js +38 -0
  445. package/dist/renderer/draw/image.js.map +1 -0
  446. package/dist/renderer/draw/mesh.js +16 -0
  447. package/dist/renderer/draw/mesh.js.map +1 -0
  448. package/dist/renderer/draw/paintBind.js +70 -0
  449. package/dist/renderer/draw/paintBind.js.map +1 -0
  450. package/dist/renderer/draw/pathPaint.js +142 -0
  451. package/dist/renderer/draw/pathPaint.js.map +1 -0
  452. package/dist/renderer/draw/scratchPass.js +83 -0
  453. package/dist/renderer/draw/scratchPass.js.map +1 -0
  454. package/dist/renderer/draw/stencil.js +28 -0
  455. package/dist/renderer/draw/stencil.js.map +1 -0
  456. package/dist/renderer/draw/text.js +167 -0
  457. package/dist/renderer/draw/text.js.map +1 -0
  458. package/dist/renderer/draw/uniforms.js +77 -0
  459. package/dist/renderer/draw/uniforms.js.map +1 -0
  460. package/dist/renderer/draw.js +60 -1116
  461. package/dist/renderer/draw.js.map +1 -1
  462. package/dist/renderer/effects/EffectTargets.js +3 -0
  463. package/dist/renderer/effects/EffectTargets.js.map +1 -1
  464. package/dist/renderer/effects/composite.js +7 -5
  465. package/dist/renderer/effects/composite.js.map +1 -1
  466. package/dist/renderer/index.js +18 -17
  467. package/dist/renderer/math/color.js +63 -83
  468. package/dist/renderer/math/color.js.map +1 -1
  469. package/dist/renderer/math/mat3.js +15 -11
  470. package/dist/renderer/math/mat3.js.map +1 -1
  471. package/dist/renderer/math/viewToMat3.js +1 -1
  472. package/dist/renderer/math/viewToMat3.js.map +1 -1
  473. package/dist/renderer/shaders/ShaderProgram.js +13 -13
  474. package/dist/renderer/shaders/ShaderProgram.js.map +1 -1
  475. package/dist/renderer/shaders/glyphPaint.js +3 -3
  476. package/dist/renderer/shaders/glyphPaint.js.map +1 -1
  477. package/dist/renderer/shaders/gradFill.js +2 -1
  478. package/dist/renderer/shaders/gradFill.js.map +1 -1
  479. package/dist/renderer/shaders/pathFill.js +2 -1
  480. package/dist/renderer/shaders/pathFill.js.map +1 -1
  481. package/dist/renderer/shaders/patternFill.js +2 -1
  482. package/dist/renderer/shaders/patternFill.js.map +1 -1
  483. package/dist/renderer/shaders/registerProgram.js.map +1 -1
  484. package/dist/renderer/strokeLengths.js.map +1 -1
  485. package/dist/renderer/textures/registerTexture.js +25 -5
  486. package/dist/renderer/textures/registerTexture.js.map +1 -1
  487. package/dist/renderer.d.ts +16 -15
  488. package/dist/renderer.js +17 -16
  489. package/dist/resize.d.ts +5 -6
  490. package/dist/resize.js +5 -5
  491. package/dist/style.css +1 -1
  492. package/dist/test-hook/install.js +12 -6
  493. package/dist/test-hook/install.js.map +1 -1
  494. package/dist/{test-seams-CuIxe0xY.d.ts → test-seams-DM2B87-g.d.ts} +4 -4
  495. package/dist/test-seams.d.ts +2 -2
  496. package/dist/tools/builtin/ellipse/useEllipseTool.js +1 -0
  497. package/dist/tools/builtin/ellipse/useEllipseTool.js.map +1 -1
  498. package/dist/tools/builtin/hand/useHandTool.js +1 -0
  499. package/dist/tools/builtin/hand/useHandTool.js.map +1 -1
  500. package/dist/tools/builtin/lasso/useLassoTool.js +11 -11
  501. package/dist/tools/builtin/lasso/useLassoTool.js.map +1 -1
  502. package/dist/tools/builtin/line/useLineTool.js +1 -0
  503. package/dist/tools/builtin/line/useLineTool.js.map +1 -1
  504. package/dist/tools/builtin/pen/usePenTool.js +153 -103
  505. package/dist/tools/builtin/pen/usePenTool.js.map +1 -1
  506. package/dist/tools/builtin/pencil/usePencilTool.js +1 -0
  507. package/dist/tools/builtin/pencil/usePencilTool.js.map +1 -1
  508. package/dist/tools/builtin/polygon/usePolygonTool.js +13 -8
  509. package/dist/tools/builtin/polygon/usePolygonTool.js.map +1 -1
  510. package/dist/tools/builtin/rect/useRectTool.js +1 -0
  511. package/dist/tools/builtin/rect/useRectTool.js.map +1 -1
  512. package/dist/tools/builtin/select/selectionContributions.js +24 -23
  513. package/dist/tools/builtin/select/selectionContributions.js.map +1 -1
  514. package/dist/tools/builtin/select/useSelectTool.js +51 -48
  515. package/dist/tools/builtin/select/useSelectTool.js.map +1 -1
  516. package/dist/tools/builtin/shared/pointerFollower.js +17 -0
  517. package/dist/tools/builtin/shared/pointerFollower.js.map +1 -0
  518. package/dist/tools/builtin/slice/useSliceTool.js +49 -54
  519. package/dist/tools/builtin/slice/useSliceTool.js.map +1 -1
  520. package/dist/tools/builtin/star/useStarTool.js +22 -16
  521. package/dist/tools/builtin/star/useStarTool.js.map +1 -1
  522. package/dist/tools/builtin/text/useTextTool.js +1 -0
  523. package/dist/tools/builtin/text/useTextTool.js.map +1 -1
  524. package/dist/tools/useKeybindings.js +14 -30
  525. package/dist/tools/useKeybindings.js.map +1 -1
  526. package/dist/{types-B_9g6hMM.d.ts → types-B4iJRHC3.d.ts} +5 -1
  527. package/dist/{types-A37hYkeR.d.ts → types-k-5Oqh-U.d.ts} +31 -7
  528. package/dist/util/color.js +3 -3
  529. package/dist/util/color.js.map +1 -1
  530. package/dist/util/paint.js.map +1 -1
  531. package/dist/version.js +1 -1
  532. package/package.json +20 -18
  533. package/dist/autoPoseDescriptor-vCdt55xm.d.ts +0 -27
  534. package/dist/builtins-C-VgUlWI.d.ts +0 -4514
  535. package/dist/core/isPlainObject.js.map +0 -1
  536. package/dist/debug/flag.js.map +0 -1
  537. package/dist/interactions/actions/defaults/freshNodeId.js +0 -10
  538. package/dist/interactions/actions/defaults/freshNodeId.js.map +0 -1
  539. package/dist/renderer/shaders/imageFill.js +0 -14
  540. package/dist/renderer/shaders/imageFill.js.map +0 -1
  541. package/dist/tools/prefs.js +0 -62
  542. package/dist/tools/prefs.js.map +0 -1
@@ -1,108 +1,106 @@
1
1
  import { composeWorldPose as e, frameAtOrAbove as t } from "../core/scene/composeFrame.js";
2
2
  import { definesFrame as n, effectivePose as r } from "../core/scene/effectivePose.js";
3
- import { asNodeId as i } from "../core/scene/types.js";
4
- import { poseDescriptorForNode as a, translatePoseViaDescriptor as o, visualBoundsViaDescriptor as s } from "../core/geometry/poseDescriptor.js";
5
- import { AUTO_POSE_DESCRIPTOR as c } from "../interactions/actions/resize/autoPoseDescriptor.js";
3
+ import { poseDescriptorForNode as i, translatePoseViaDescriptor as a, visualBoundsViaDescriptor as o } from "../core/geometry/poseDescriptor.js";
4
+ import { AUTO_POSE_DESCRIPTOR as s } from "../interactions/actions/resize/autoPoseDescriptor.js";
5
+ import { asNodeId as c } from "../core/scene/types.js";
6
6
  import { fnFieldsOfNode as l } from "../core/scene/nodeFnFields.js";
7
- import { applyOpsTo as u } from "../core/applyOps.js";
8
- import { hitTestArea as d, hitTestLassoPolygon as f, regionPickOptions as p } from "./deps/hitTestArea.js";
9
- import { useMemo as m } from "react";
7
+ import { pickability as u } from "../core/scene/pickability.js";
8
+ import { applyOpsTo as d } from "../core/applyOps.js";
9
+ import { hitTestArea as f, hitTestLassoPolygon as p, regionPickOptions as m } from "./deps/hitTestArea.js";
10
+ import { pasteSceneSnapshot as h, snapshotSceneSelection as g } from "./sceneClipboard.js";
11
+ import { useMemo as _ } from "react";
10
12
  //#region src/canvas/sceneAdapter.ts
11
- var h = 0;
12
- function g() {
13
- return `n${(h++).toString(36)}-${Math.random().toString(36).slice(2, 8)}`;
14
- }
15
- var _ = 0;
16
- function v() {
17
- return `paste-${(_++).toString(36)}-${Math.random().toString(36).slice(2, 8)}`;
18
- }
19
- function y(e) {
20
- return Array.isArray(e) ? [...e] : typeof e == "object" && e ? { ...e } : e;
21
- }
22
- function b(m, h = {}) {
23
- let _ = () => {
13
+ function v(_, v = {}) {
14
+ let y = () => {
24
15
  let e = /* @__PURE__ */ new Set();
25
- for (let t of m.layers) t.visible && e.add(t.id);
16
+ for (let t of _.layers) t.visible && e.add(t.id);
26
17
  return e;
27
- }, b = h.selection, x = b?.getSelection ?? b?.get ?? (() => []), S = b?.setSelection ?? b?.set ?? (() => {}), C = h.poseDescriptor ?? c, w = (e) => s(e, C), T = (e, t, n, r) => o(e, t, n, r === void 0 ? C : a(C, r)), E = h.poseComposition, D = E !== void 0 && E.closure !== "identity", O = E ? { poseComposition: E } : {}, k = (e) => e ? {
18
+ }, b = v.selection, x = b?.getSelection ?? b?.get ?? (() => []), S = b?.setSelection ?? b?.set ?? (() => {}), C = v.poseDescriptor ?? s, w = (e, t) => o(e, i(C, t)), T = (e, t, n, r) => a(e, t, n, r === void 0 ? C : i(C, r)), E = v.poseComposition, D = E !== void 0 && E.closure !== "identity", O = E ? { poseComposition: E } : {}, k = (e) => e ? {
28
19
  ...O,
29
- ...p(e, void 0, void 0)
20
+ ...m(e, void 0, void 0)
30
21
  } : O;
31
- if (D && h.cascadeContainerPose) throw Error("sceneToAdapter: poseComposition and cascadeContainerPose contradict each other. Under a composing strategy a child's pose is already relative to its parent, so the cascade would move every descendant twice. Drop cascadeContainerPose.");
22
+ if (D && v.cascadeContainerPose) throw Error("sceneToAdapter: poseComposition and cascadeContainerPose contradict each other. Under a composing strategy a child's pose is already relative to its parent, so the cascade would move every descendant twice. Drop cascadeContainerPose.");
32
23
  let A = {
24
+ scene: _,
25
+ composes: D,
26
+ worldPoseOf: (e) => j.getWorldPose(e),
27
+ frameAtOrAbove: (e) => t(j, e),
28
+ poseBounds: w,
29
+ translate: T
30
+ }, j = {
33
31
  getNode(e) {
34
- return m.get(i(e));
32
+ return _.get(c(e));
35
33
  },
36
34
  getNodes() {
37
- let e = _(), t = [];
38
- for (let n of m.renderOrderNodes()) e.has(n.layer) && t.push(n);
35
+ let e = y(), t = [];
36
+ for (let n of _.renderOrderNodes()) e.has(n.layer) && t.push(n);
39
37
  return t;
40
38
  },
41
39
  getPose(e) {
42
- let t = i(e), n = m.get(t);
40
+ let t = c(e), n = _.get(t);
43
41
  if (!n) throw Error(`sceneToAdapter: unknown node "${e}"`);
44
- return r(m, n);
42
+ return r(_, n);
45
43
  },
46
44
  getParent(e) {
47
- return m.get(i(e))?.parent ?? null;
45
+ return _.get(c(e))?.parent ?? null;
48
46
  },
49
47
  definesFrame(e) {
50
- let t = m.get(i(e));
48
+ let t = _.get(c(e));
51
49
  return t === void 0 || n(t);
52
50
  },
53
51
  getWorldPose(t) {
54
- return D ? e(A, t, E.compose) : A.getPose(t);
52
+ return D ? e(j, t, E.compose) : j.getPose(t);
55
53
  },
56
54
  ...D ? { composePose: E.compose } : {},
57
55
  setPose(e, t) {
58
- if (h.cascadeContainerPose) {
59
- let n = m.get(i(e));
56
+ if (v.cascadeContainerPose) {
57
+ let n = _.get(c(e));
60
58
  if (n && n.kind === "container") {
61
- let r = a(C, n), o = r.getBounds(n.pose), s = r.getBounds(t), c = s.x - o.x, l = s.y - o.y;
62
- if (c !== 0 || l !== 0) {
59
+ let r = i(C, n), a = r.getBounds(n.pose), o = r.getBounds(t), s = o.x - a.x, l = o.y - a.y;
60
+ if (s !== 0 || l !== 0) {
63
61
  let n = [], r = (e) => {
64
- for (let t of m.childrenOf(i(e))) n.push(t), r(t);
62
+ for (let t of _.childrenOf(c(e))) n.push(t), r(t);
65
63
  };
66
- r(e), m.batch("move container", () => {
67
- m.setPose(i(e), t);
64
+ r(e), _.batch("move container", () => {
65
+ _.setPose(c(e), t);
68
66
  for (let e of n) {
69
- let t = m.get(i(e));
70
- t && m.setPose(i(e), T(t.pose, c, l, t));
67
+ let t = _.get(c(e));
68
+ t && _.setPose(c(e), T(t.pose, s, l, t));
71
69
  }
72
70
  });
73
71
  return;
74
72
  }
75
73
  }
76
74
  }
77
- m.setPose(i(e), t);
75
+ _.setPose(c(e), t);
78
76
  },
79
77
  setParent(e, t) {
80
- m.move(i(e), t === null ? null : i(t));
78
+ _.move(c(e), t === null ? null : c(t));
81
79
  },
82
80
  getChildren(e) {
83
- return e === null ? [...m.roots] : [...m.childrenOf(i(e))];
81
+ return e === null ? [..._.roots] : [..._.childrenOf(c(e))];
84
82
  },
85
83
  setChildOrder(e, t) {
86
- m.batch("Reorder", () => {
87
- for (let n = 0; n < t.length; n++) (e === null ? m.roots : m.childrenOf(i(e)))[n] !== t[n] && m.reorder(i(t[n]), n);
84
+ _.batch("Reorder", () => {
85
+ for (let n = 0; n < t.length; n++) (e === null ? _.roots : _.childrenOf(c(e)))[n] !== t[n] && _.reorder(c(t[n]), n);
88
86
  });
89
87
  },
90
88
  getLayers() {
91
- return m.layers.map((e) => ({
89
+ return _.layers.map((e) => ({
92
90
  id: e.id,
93
91
  visible: e.visible,
94
92
  parallax: e.parallax
95
93
  }));
96
94
  },
97
95
  getLayout(e) {
98
- let t = m.layoutOf(i(e));
99
- return t !== null || !h.layouts ? t : typeof h.layouts == "function" ? h.layouts(e) : h.layouts[e] ?? null;
96
+ let t = _.layoutOf(c(e));
97
+ return t !== null || !v.layouts ? t : typeof v.layouts == "function" ? v.layouts(e) : v.layouts[e] ?? null;
100
98
  },
101
99
  applyOps(e, t) {
102
- t === void 0 ? u(this, e) : m.applyBatch(e, t, this);
100
+ t === void 0 ? d(this, e) : _.applyBatch(e, t, this);
103
101
  },
104
102
  insertNode(e, t) {
105
- m.add({
103
+ _.add({
106
104
  kind: e.kind,
107
105
  layer: e.layer,
108
106
  pose: e.pose,
@@ -111,36 +109,37 @@ function b(m, h = {}) {
111
109
  ...t === void 0 ? {} : { index: t },
112
110
  ...e.parent === null ? {} : { parent: e.parent },
113
111
  ...e.dependsOn === void 0 ? {} : { dependsOn: e.dependsOn },
112
+ ...u(e),
114
113
  ...l(e)
115
114
  });
116
115
  },
117
116
  removeNode(e) {
118
- m.remove(i(e));
117
+ _.remove(c(e));
119
118
  },
120
119
  setData(e, t) {
121
- m.update(i(e), { data: t });
120
+ _.update(c(e), { data: t });
122
121
  },
123
122
  setLayout(e, t) {
124
- m.setLayout(i(e), t);
123
+ _.setLayout(c(e), t);
125
124
  },
126
125
  getRemovalClosure(e) {
127
- return [...m.removalClosure(e.map(i))];
126
+ return [..._.removalClosure(e.map(c))];
128
127
  },
129
128
  getSelection: x,
130
129
  setSelection: S,
131
130
  hitTestArea(e, t) {
132
- return d(m, e, k(t), C, { includeContainers: !0 });
131
+ return f(_, e, k(t), C, { includeContainers: !0 });
133
132
  },
134
133
  hitTestLasso(e, t, n) {
135
- return f(m, e, t, k(n), C, { includeContainers: !0 });
134
+ return p(_, e, t, k(n), C, { includeContainers: !0 });
136
135
  },
137
- ...h.commitInsert ? { commitInsert: (e) => {
138
- let t = h.commitInsert(e);
136
+ ...v.commitInsert ? { commitInsert: (e) => {
137
+ let t = v.commitInsert(e);
139
138
  if (!t) return null;
140
- let n = h.insertLayer ?? "default";
139
+ let n = v.insertLayer ?? "default";
141
140
  return {
142
141
  kind: "leaf",
143
- id: i(t.id ?? g()),
142
+ id: t.id === void 0 ? _.mintId() : c(t.id),
144
143
  layer: n,
145
144
  pose: t.pose,
146
145
  data: t.data,
@@ -148,91 +147,10 @@ function b(m, h = {}) {
148
147
  };
149
148
  } } : {},
150
149
  snapshotSelection(e) {
151
- let n = new Set(e), r = /* @__PURE__ */ new Set(), a = [], o = (e, n) => {
152
- if (!D) return e.pose;
153
- if (n) return A.getWorldPose(e.id);
154
- let i = t(A, e.parent);
155
- return i !== null && r.has(i) ? e.pose : A.getWorldPose(e.id);
156
- }, s = (e) => e.dependsOn === "children" && e.derivePose ? {
157
- dependsOn: e.dependsOn,
158
- derivePose: e.derivePose
159
- } : {}, c = (e, t = !1) => {
160
- if (r.has(e)) return;
161
- let n = m.get(i(e));
162
- if (n) {
163
- if (r.add(e), n.kind === "container") {
164
- a.push({
165
- kind: "container",
166
- id: n.id,
167
- layer: n.layer,
168
- parent: n.parent,
169
- pose: y(o(n, t)),
170
- data: y(n.data),
171
- children: [...n.children],
172
- ...n.clipFromPose ? { clipFromPose: n.clipFromPose } : {},
173
- ...s(n)
174
- });
175
- for (let t of m.childrenOf(i(e))) c(t);
176
- } else a.push({
177
- kind: "leaf",
178
- id: n.id,
179
- layer: n.layer,
180
- parent: n.parent,
181
- pose: y(o(n, t)),
182
- data: y(n.data)
183
- });
184
- }
185
- };
186
- for (let t of e) m.ancestorsOf(i(t)).some((e) => n.has(e)) || c(t, !0);
187
- return { items: a };
150
+ return g(A, e);
188
151
  },
189
- commitPaste(e, t, r) {
190
- let a = e.items;
191
- if (a.length === 0) return [];
192
- let o = /* @__PURE__ */ new Map();
193
- for (let e of a) o.set(e.id, i(v()));
194
- let s = (e) => e.parent === null || !o.has(e.parent), c = new Map(a.map((e) => [e.id, e])), l = (e) => {
195
- if (!D) return !1;
196
- let t = e.parent === null ? void 0 : c.get(e.parent);
197
- for (; t !== void 0;) {
198
- if (n(t)) return !0;
199
- t = t.parent === null ? void 0 : c.get(t.parent);
200
- }
201
- return !1;
202
- }, u = t.dx, d = t.dy;
203
- if (r?.dropPoint) {
204
- let e = Infinity, t = Infinity;
205
- for (let n of a) {
206
- if (!s(n)) continue;
207
- let r = w(n.pose);
208
- r.x < e && (e = r.x), r.y < t && (t = r.y);
209
- }
210
- Number.isFinite(e) && Number.isFinite(t) && (u = r.dropPoint.worldX - e, d = r.dropPoint.worldY - t);
211
- }
212
- let f = [];
213
- for (let e of a) {
214
- let t = {
215
- id: o.get(e.id),
216
- layer: e.layer,
217
- parent: s(e) ? null : o.get(e.parent),
218
- pose: l(e) ? y(e.pose) : T(y(e.pose), u, d),
219
- data: y(e.data)
220
- };
221
- e.kind === "container" ? f.push({
222
- ...t,
223
- kind: "container",
224
- children: e.children.filter((e) => o.has(e)).map((e) => o.get(e)),
225
- ...e.clipFromPose ? { clipFromPose: e.clipFromPose } : {},
226
- ...e.dependsOn === "children" && e.derivePose ? {
227
- dependsOn: e.dependsOn,
228
- derivePose: e.derivePose
229
- } : {}
230
- }) : f.push({
231
- ...t,
232
- kind: "leaf"
233
- });
234
- }
235
- return f;
152
+ commitPaste(e, t, n) {
153
+ return h(A, e, t, n);
236
154
  },
237
155
  getPasteOffset() {
238
156
  return {
@@ -241,11 +159,11 @@ function b(m, h = {}) {
241
159
  };
242
160
  }
243
161
  };
244
- return A;
162
+ return j;
245
163
  }
246
- function x(e, t = {}) {
164
+ function y(e, t = {}) {
247
165
  let { selection: n, commitInsert: r, insertLayer: i, layouts: a, poseDescriptor: o, cascadeContainerPose: s, poseComposition: c } = t;
248
- return m(() => b(e, {
166
+ return _(() => v(e, {
249
167
  selection: n,
250
168
  commitInsert: r,
251
169
  insertLayer: i,
@@ -265,6 +183,6 @@ function x(e, t = {}) {
265
183
  ]);
266
184
  }
267
185
  //#endregion
268
- export { b as sceneToAdapter, x as useSceneAdapter };
186
+ export { v as sceneToAdapter, y as useSceneAdapter };
269
187
 
270
188
  //# sourceMappingURL=sceneAdapter.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"sceneAdapter.js","names":["adapterFallbackIdCounter","adapterFallbackId","pasteIdCounter","pasteNodeId","copyField","value","sceneToAdapter","visibleLayers","out","layer","scene","sel","options","getSelection","setSelection","d","AUTO_POSE_DESCRIPTOR","poseBounds","visualBoundsViaDescriptor","p","translate","translatePoseViaDescriptor","dx","dy","node","poseDescriptorForNode","composition","composes","pickOpts","pickOptsFor","view","regionPickOptions","adapter","asNodeId","id","visible","nid","effectivePose","n","definesFrame","composeWorldPose","g","before","after","pose","descIds","collect","cid","rootId","cn","parentId","i","ids","l","declared","label","applyOpsTo","ops","index","fnFieldsOfNode","layout","hitTestArea","rect","hitTestLassoPolygon","polygon","mode","created","bounds","idSet","taken","items","poseFor","isRoot","frame","frameAtOrAbove","derivation","capture","a","src","clipboard","idMap","item","byId","ridesPastedFrame","offset","ctx","minX","minY","b","base","c","useSceneAdapter","useMemo","selection","commitInsert","insertLayer","layouts","poseDescriptor","cascadeContainerPose","poseComposition"],"sources":["../../src/canvas/sceneAdapter.ts"],"sourcesContent":["/**\n * Synthesize a `<Canvas>`-compatible adapter from a `Scene` primitive.\n *\n * The Scene owns nodes/poses/parenting and auto-records ops on every mutation.\n * `<SceneCanvas>` calls `sceneToAdapter(scene)` and forwards the result to\n * `<Canvas>`'s `adapter` prop. Selection and hit-testing are not part of the\n * Scene model — Canvas's internal `useSelection` and pose-derived pickEvery\n * cover those.\n *\n * Pose semantics match the rest of the kit: `getPose` / `setPose` return /\n * write **local** coordinates (relative to parent). The Scene stores pose on\n * each node directly; world composition (when needed) is the renderer's job\n * via `composeWorldPose`, not the adapter's.\n */\nimport { useMemo } from 'react';\nimport type {\n AreaSelectAdapter,\n ClipboardSnapshot,\n InsertAdapter,\n LassoHitMode,\n LassoSelectAdapter,\n RegionPickView,\n LayerEnumerableAdapter,\n MoveAdapter,\n ResizeAdapter,\n RotateAdapter,\n} from 'core/adapters/types';\nimport type { LayoutStrategy } from '../layout/types';\nimport type { Op } from 'core/ops/types';\nimport type { Node, NodeId, Scene } from 'core/scene/types';\nimport { definesFrame, effectivePose } from 'core/scene/effectivePose';\nimport { fnFieldsOfNode } from 'core/scene/nodeFnFields';\nimport { asNodeId } from 'core/scene/types';\nimport { applyOpsTo } from 'core/applyOps';\nimport { hitTestArea, hitTestLassoPolygon, regionPickOptions } from 'canvas/deps/hitTestArea';\nimport type { ScenePickSourceOptions } from 'canvas/pickWalk';\nimport {\n poseDescriptorForNode,\n translatePoseViaDescriptor,\n visualBoundsViaDescriptor,\n type PoseDescriptor,\n} from 'interactions/actions/resize/geometry';\nimport { AUTO_POSE_DESCRIPTOR } from 'interactions/actions/resize/autoPoseDescriptor';\nimport { composeWorldPose, frameAtOrAbove, type PoseComposition } from 'features/groups/composePose';\nimport type { Bounds } from '../core/viewport/fitViewToBounds';\n\n/** Minimal selection contract `sceneToAdapter` needs to wire `getSelection` /\n * `setSelection`. Matches `useSelection().adapterMethods` plus an imperative\n * read; pass `useSelection()` itself or `selection.adapterMethods`. */\nexport interface SceneAdapterSelection {\n get?(): string[];\n set?(ids: string[]): void;\n getSelection?(): string[];\n setSelection?(ids: string[]): void;\n}\n\n/** Sibling z-order surface used by reorder ops. Inlined here (rather than\n * pulled from `core/ops/reorder` to avoid import cycles); the `null` parent\n * channel addresses the root sibling list. */\n/** @internal */\ninterface ReorderAdapter {\n getChildren(parentId: string | null): string[];\n setChildOrder(parentId: string | null, ids: string[]): void;\n}\n\n/** Everything the interaction layer can ask of a scene, as one type: the\n * move, resize, rotate, selection, layer and reorder contracts combined.\n * `<SceneCanvas>` synthesizes one of these, which is why most consumers never\n * touch an adapter directly. */\nexport type SceneCanvasAdapter<TData, TLayer extends string, TPose> =\n & MoveAdapter<Node<TData, TLayer, TPose>, TPose>\n & ResizeAdapter<Node<TData, TLayer, TPose>, TPose>\n & RotateAdapter<Node<TData, TLayer, TPose>, TPose>\n & AreaSelectAdapter\n & LassoSelectAdapter\n & LayerEnumerableAdapter<TLayer>\n & ReorderAdapter\n & Partial<InsertAdapter<Node<TData, TLayer, TPose>>>\n // Tighten the parts that are optional on the underlying adapter contracts\n // but unconditionally provided by a scene-backed adapter. Anything that\n // routes scene mutations through this adapter (kit InsertOps, hierarchical\n // hooks like useNest, etc.) can rely on these being present.\n & {\n getParent(id: string): string | null;\n /** The node's pose with every ancestor's frame folded in. Equal to\n * `getPose` unless a `poseComposition` is configured. */\n getWorldPose(id: string): TPose;\n /** Whether `id`'s pose is a frame its children are expressed in — see\n * `definesFrame`. */\n definesFrame(id: string): boolean;\n /** Present only when a composing strategy is configured; the render\n * walk feature-detects it. */\n composePose?(parent: TPose, child: TPose): TPose;\n getSelection(): string[];\n setSelection(ids: string[]): void;\n insertNode(node: Node<TData, TLayer, TPose>, index?: number): void;\n removeNode(id: string): void;\n /** Replace a node's `data` — what a `setData` op writes through. */\n setData(id: string, data: TData): void;\n /** Swap a container's layout — what a `setLayout` op writes through. */\n setLayout(id: string, layout: LayoutStrategy<TPose> | string | null): void;\n getRemovalClosure(ids: readonly string[]): string[];\n applyOps(ops: Op[], label?: string): void;\n snapshotSelection(ids: string[]): ClipboardSnapshot;\n commitPaste(\n clipboard: ClipboardSnapshot,\n offset: { dx: number; dy: number },\n ctx?: { dropPoint?: { worldX: number; worldY: number } },\n ): Node<TData, TLayer, TPose>[];\n getPasteOffset(clipboard: ClipboardSnapshot): { dx: number; dy: number };\n };\n\n/** Optional extras for the synthesized adapter. Pass `commitInsert` to wire\n * the insert gesture into a Scene-owned canvas; the returned object becomes\n * a leaf on the layer named by `layer` (default `'default'`). */\nexport interface SceneToAdapterOptions<TData, TLayer extends string, TPose> {\n /** Factory for new objects. Returning `null` aborts the insert. */\n commitInsert?: (bounds: Bounds) => {\n pose: TPose;\n data: TData;\n id?: string;\n } | null;\n /** Layer to place inserted nodes on. Defaults to the trivial-form layer. */\n insertLayer?: TLayer;\n /** Selection source for `AreaSelectAdapter.getSelection` / `setSelection`.\n * Pass the result of `useSelection()` (or its `adapterMethods`). When\n * omitted, `getSelection` returns `[]` and `setSelection` is a noop —\n * fine for read-only or selection-less canvases, but the marquee gesture\n * won't update any external selection state. */\n selection?: SceneAdapterSelection;\n /** How to read and rewrite this scene's poses. Default `AUTO_POSE_DESCRIPTOR`. */\n poseDescriptor?: PoseDescriptor<TPose>;\n /** Layout strategies keyed by container node id, for containers whose\n * scene node declares none (`ContainerNode.layout` wins). `move` runs its\n * layout-aware pass on them; for inserts, deletes and resizes to reach\n * them too, install them with `useLayoutArrivals`. Pass either a static\n * map, or a `getLayout(id)` function for dynamic resolution. */\n layouts?:\n | Record<string, LayoutStrategy<TPose>>\n | ((containerId: string) => LayoutStrategy<TPose> | null);\n /** When true, `setPose` on a container translates every descendant by the\n * same delta, through the pose descriptor. Scene v1 stores absolute poses,\n * so without it children stay behind. */\n cascadeContainerPose?: boolean;\n /** How a child's stored pose folds into its parent's frame. Omit for the\n * absolute-pose model, where a parent contributes no transform. Supplying a\n * composing strategy makes a container's pose a **frame**: rotating the\n * container rotates its contents, and `setPose` on it must not also\n * translate them, so it cannot be combined with `cascadeContainerPose`. */\n poseComposition?: PoseComposition<TPose>;\n}\n\n// Fallback id generator for `commitInsert` when the consumer factory omits\n// `created.id`. Mirrors `scene.ts`'s `defaultGenerateId` shape; module-scoped\n// counter keeps ids unique across adapters in a session.\nlet adapterFallbackIdCounter = 0;\nfunction adapterFallbackId(): string {\n return `n${(adapterFallbackIdCounter++).toString(36)}-${Math.random().toString(36).slice(2, 8)}`;\n}\n\n// Fresh ids for pasted nodes. The scene's own `generateId` isn't reachable\n// from the adapter, so `commitPaste` mints ids in the same shape as\n// `defaultGenerateId` with a `paste-` prefix (module-scoped counter + random\n// suffix keeps them unique across adapters and repeated pastes). Accepted\n// risk: the counter is per-tab, so cross-tab paste (the OS-clipboard path)\n// leans on the random suffix alone for uniqueness — a collision makes\n// `scene.add` throw rather than silently overwrite.\nlet pasteIdCounter = 0;\nfunction pasteNodeId(): string {\n return `paste-${(pasteIdCounter++).toString(36)}-${Math.random().toString(36).slice(2, 8)}`;\n}\n\n// Copy one node field (pose / data / children) so clipboard snapshots don't\n// alias live scene state. Spread-level copy per the clipboard contract:\n// mutating a snapshot's pose/data/children must not touch the scene.\nfunction copyField<T>(value: T): T {\n if (Array.isArray(value)) return [...value] as T;\n if (value !== null && typeof value === 'object') return { ...(value as object) } as T;\n return value;\n}\n\n/** Derive the adapter for a scene. Reads go straight to the scene; writes are\n * ops applied through its history, so anything done through the adapter is\n * undoable. */\nexport function sceneToAdapter<TData, TLayer extends string, TPose>(\n scene: Scene<TData, TLayer, TPose>,\n options: SceneToAdapterOptions<TData, TLayer, TPose> = {},\n): SceneCanvasAdapter<TData, TLayer, TPose> {\n const visibleLayers = (): Set<TLayer> => {\n const out = new Set<TLayer>();\n for (const layer of scene.layers) {\n if (layer.visible) out.add(layer.id);\n }\n return out;\n };\n\n const sel = options.selection;\n const getSelection = sel?.getSelection ?? sel?.get ?? (() => [] as string[]);\n const setSelection = sel?.setSelection ?? sel?.set ?? (() => {});\n const d = (options.poseDescriptor ?? AUTO_POSE_DESCRIPTOR) as PoseDescriptor<TPose>;\n const poseBounds = (p: TPose): Bounds => visualBoundsViaDescriptor(p, d);\n const translate = (p: TPose, dx: number, dy: number, node?: unknown): TPose =>\n translatePoseViaDescriptor(\n p, dx, dy, node === undefined ? d : poseDescriptorForNode(d, node),\n );\n\n const composition = options.poseComposition;\n const composes = composition !== undefined && composition.closure !== 'identity';\n const pickOpts: ScenePickSourceOptions<unknown> = composition\n ? { poseComposition: composition as PoseComposition<unknown> }\n : {};\n // The asking view's layer gate and camera, over the adapter's own options.\n const pickOptsFor = (view: RegionPickView | undefined): ScenePickSourceOptions<unknown> =>\n (view ? { ...pickOpts, ...regionPickOptions(view, undefined, undefined) } : pickOpts);\n if (composes && options.cascadeContainerPose) {\n throw new Error(\n 'sceneToAdapter: poseComposition and cascadeContainerPose contradict each other. ' +\n 'Under a composing strategy a child\\'s pose is already relative to its parent, so ' +\n 'the cascade would move every descendant twice. Drop cascadeContainerPose.',\n );\n }\n\n const adapter: SceneCanvasAdapter<TData, TLayer, TPose> = {\n getNode(id) {\n return scene.get(asNodeId(id));\n },\n getNodes() {\n const visible = visibleLayers();\n const out: Node<TData, TLayer, TPose>[] = [];\n for (const n of scene.renderOrderNodes()) {\n if (visible.has(n.layer)) out.push(n);\n }\n return out;\n },\n getPose(id) {\n const nid = asNodeId(id);\n const n = scene.get(nid);\n if (!n) throw new Error(`sceneToAdapter: unknown node \"${id}\"`);\n return effectivePose(scene, n);\n },\n getParent(id) {\n const n = scene.get(asNodeId(id));\n return n?.parent ?? null;\n },\n definesFrame(id) {\n const n = scene.get(asNodeId(id));\n return n === undefined || definesFrame(n);\n },\n getWorldPose(id) {\n if (!composes) return adapter.getPose(id);\n return composeWorldPose(adapter, id, composition!.compose);\n },\n // Only present when it would do something: the render walk skips the fold\n // entirely when this is absent, which is the absolute-pose path.\n ...(composes ? { composePose: composition!.compose } : {}),\n setPose(id, pose) {\n // Container cascade (opt-in): under scene v1's absolute-pose semantics,\n // moving a container needs to translate every descendant by the same\n // delta so children visually stay attached. The whole cascade lands as\n // one scene.batch so undo collapses to a single step.\n if (options.cascadeContainerPose) {\n const node = scene.get(asNodeId(id));\n if (node && node.kind === 'container') {\n const g = poseDescriptorForNode(d, node);\n const before = g.getBounds(node.pose);\n const after = g.getBounds(pose);\n const dx = after.x - before.x;\n const dy = after.y - before.y;\n if (dx !== 0 || dy !== 0) {\n const descIds: string[] = [];\n const collect = (rootId: string): void => {\n for (const cid of scene.childrenOf(asNodeId(rootId))) {\n descIds.push(cid);\n collect(cid);\n }\n };\n collect(id);\n scene.batch('move container', () => {\n scene.setPose(asNodeId(id), pose);\n for (const cid of descIds) {\n const cn = scene.get(asNodeId(cid));\n if (!cn) continue;\n scene.setPose(asNodeId(cid), translate(cn.pose, dx, dy, cn));\n }\n });\n return;\n }\n }\n }\n scene.setPose(asNodeId(id), pose);\n },\n setParent(id, parentId) {\n scene.move(asNodeId(id), parentId === null ? null : asNodeId(parentId));\n },\n getChildren(id) {\n // Reorder ops call this with parentId === null to mean \"root siblings.\"\n // The kit's existing callers always pass a string, so this widening is\n // additive — falls through to scene.childrenOf for the typed path and\n // returns scene.roots for the null path.\n if (id === null) return [...scene.roots];\n return [...scene.childrenOf(asNodeId(id))];\n },\n setChildOrder(parentId, ids) {\n // Batched reorder: each scene.reorder call is its own kit:move log\n // entry, but scene.batch wraps them into one undo unit + one notify.\n scene.batch('Reorder', () => {\n for (let i = 0; i < ids.length; i++) {\n // Skip ids that are already in the target slot to avoid useless\n // log entries.\n const current = parentId === null\n ? scene.roots\n : scene.childrenOf(asNodeId(parentId));\n if (current[i] === ids[i]) continue;\n scene.reorder(asNodeId(ids[i]), i);\n }\n });\n },\n getLayers() {\n return scene.layers.map((l) => ({ id: l.id, visible: l.visible, parallax: l.parallax }));\n },\n getLayout(id) {\n const declared = scene.layoutOf(asNodeId(id));\n if (declared !== null || !options.layouts) return declared;\n return typeof options.layouts === 'function'\n ? options.layouts(id)\n : options.layouts[id] ?? null;\n },\n // Unified applyOps: when a label is supplied the ops are wrapped in a\n // batch checkpoint (history-aware path used by Move/Resize/Rotate/Insert/\n // Delete tools). When a journal is active (via scene's getActiveJournal\n // option), scene.applyBatch routes to the journal instead of recording a\n // new parent-history entry. Without a label the ops are applied transiently\n // via applyOpsTo (AreaSelectAdapter contract — no checkpoint).\n applyOps(ops: Op[], label?: string) {\n if (label !== undefined) {\n scene.applyBatch(ops, label, this);\n } else {\n applyOpsTo(this, ops);\n }\n },\n // Node-mutation surface used by kit InsertOps / DeleteOps (e.g.\n // useNest wrapping the selection in a new container node, or its\n // inverse). Re-adds via the full structural spec so the round-trip\n // survives undo/redo; removes by id.\n insertNode(node: Node<TData, TLayer, TPose>, index?: number) {\n scene.add({\n kind: node.kind,\n layer: node.layer,\n pose: node.pose,\n data: node.data,\n id: node.id,\n ...(index !== undefined ? { index } : {}),\n ...(node.parent !== null ? { parent: node.parent } : {}),\n // Derivation travels with the node, or undo of a delete brings an\n // edge back as a static path that never follows its endpoints again.\n ...(node.dependsOn !== undefined ? { dependsOn: node.dependsOn } : {}),\n ...fnFieldsOfNode(node),\n });\n },\n removeNode(id: string) {\n scene.remove(asNodeId(id));\n },\n setData(id: string, data: TData) {\n scene.update(asNodeId(id), { data });\n },\n setLayout(id: string, layout: LayoutStrategy<TPose> | string | null) {\n scene.setLayout(asNodeId(id), layout);\n },\n getRemovalClosure(ids: readonly string[]): string[] {\n return [...scene.removalClosure(ids.map(asNodeId))];\n },\n // AreaSelectAdapter surface — included unconditionally so plain\n // `useSelectTool(sceneToAdapter(scene, { selection }))` Just Works for the\n // marquee gesture. `applyOps` (above) dispatches transiently when called\n // without a label, matching the AreaSelectAdapter contract.\n getSelection,\n setSelection,\n // The live marquee's and lasso's own hit-tests. Containers come back:\n // this adapter's consumer has nothing to fold children into them.\n hitTestArea(rect: Bounds, view?: RegionPickView) {\n return hitTestArea(\n scene,\n rect,\n pickOptsFor(view),\n d as PoseDescriptor<unknown>,\n { includeContainers: true },\n );\n },\n hitTestLasso(polygon, mode: LassoHitMode, view?: RegionPickView) {\n return hitTestLassoPolygon(\n scene,\n polygon,\n mode,\n pickOptsFor(view),\n d as PoseDescriptor<unknown>,\n { includeContainers: true },\n );\n },\n // commitInsert (gesture-time leaf insert) is opt-in: present only when\n // `options.commitInsert` is. The full insertNode/removeNode mutators\n // above are always present so kit-side InsertOp / DeleteOp round-trip\n // through scene.add / scene.remove regardless.\n //\n // Contract: this is a pure factory — it constructs a Node spec but does\n // NOT touch the scene. `useInsert`'s onEnd dispatches an `InsertOp`\n // whose apply() calls `adapter.insertNode` → `scene.add`, which is the\n // sole insertion path. Calling `scene.add` here too would double-insert,\n // and the second add throws on id collision (silently dropping the\n // gesture's pointer-up cleanup and breaking the next drag).\n ...(options.commitInsert\n ? {\n commitInsert: (bounds: { x: number; y: number; width: number; height: number }) => {\n const created = options.commitInsert!(bounds);\n if (!created) return null;\n const layer = (options.insertLayer ?? ('default' as TLayer));\n const id = asNodeId(created.id ?? adapterFallbackId());\n return {\n kind: 'leaf',\n id,\n layer,\n pose: created.pose,\n data: created.data,\n parent: null,\n } as Node<TData, TLayer, TPose>;\n },\n }\n : {}),\n // Clipboard seam (`useClipboardOps` / the paste ingestion path).\n //\n // `snapshotSelection` captures adapter-shaped node copies; `commitPaste`\n // is a pure factory like `commitInsert` above — it mints fresh nodes but\n // NEVER touches the scene. Insertion happens via the hook's InsertOps\n // (one per created node, parents before children), which is what makes a\n // whole paste a single undo entry.\n snapshotSelection(ids: string[]): ClipboardSnapshot {\n const idSet = new Set(ids);\n const taken = new Set<string>();\n const items: Node<TData, TLayer, TPose>[] = [];\n // DFS from one snapshot root: push the node, then its subtree —\n // parents-before-children, so paste can re-insert in array order.\n // A stored pose is relative to its frame, and a node whose frame is not\n // copied with it lands somewhere else entirely on paste. Capture those in\n // world coordinates: every root, and under an envelope root, the nodes\n // sharing the frame the root left behind.\n const poseFor = (n: Node<TData, TLayer, TPose>, isRoot: boolean): TPose => {\n if (!composes) return n.pose;\n if (isRoot) return adapter.getWorldPose(n.id);\n const frame = frameAtOrAbove(adapter, n.parent);\n return frame !== null && taken.has(frame) ? n.pose : adapter.getWorldPose(n.id);\n };\n // Only a derivation over `'children'` survives the copy: an id list\n // would still name the originals.\n const derivation = (n: Node<TData, TLayer, TPose>) =>\n n.dependsOn === 'children' && n.derivePose\n ? { dependsOn: n.dependsOn, derivePose: n.derivePose }\n : {};\n\n const capture = (id: string, isRoot = false): void => {\n if (taken.has(id)) return;\n const n = scene.get(asNodeId(id));\n if (!n) return;\n taken.add(id);\n if (n.kind === 'container') {\n items.push({\n kind: 'container',\n id: n.id,\n layer: n.layer,\n parent: n.parent,\n pose: copyField(poseFor(n, isRoot)),\n data: copyField(n.data),\n children: [...n.children],\n ...(n.clipFromPose ? { clipFromPose: n.clipFromPose } : {}),\n ...derivation(n),\n });\n for (const cid of scene.childrenOf(asNodeId(id))) capture(cid);\n } else {\n items.push({\n kind: 'leaf',\n id: n.id,\n layer: n.layer,\n parent: n.parent,\n pose: copyField(poseFor(n, isRoot)),\n data: copyField(n.data),\n });\n }\n };\n for (const id of ids) {\n // Dedupe: an id whose ancestor is also selected is already covered\n // by that ancestor's subtree walk.\n if (scene.ancestorsOf(asNodeId(id)).some((a) => idSet.has(a))) continue;\n capture(id, true);\n }\n return { items };\n },\n commitPaste(\n clipboard: ClipboardSnapshot,\n offset: { dx: number; dy: number },\n ctx?: { dropPoint?: { worldX: number; worldY: number } },\n ): Node<TData, TLayer, TPose>[] {\n // Snapshot items are adapter-shaped node copies: what snapshotSelection\n // captures, and what commitPaste itself returns (`useClipboardOps`\n // feeds `created` back in as the next cascade source).\n const src = clipboard.items as Node<TData, TLayer, TPose>[];\n if (src.length === 0) return [];\n const idMap = new Map<string, NodeId>();\n for (const item of src) idMap.set(item.id, asNodeId(pasteNodeId()));\n // Items whose captured parent isn't part of the snapshot become roots\n // of the pasted cluster.\n const isRoot = (item: Node<TData, TLayer, TPose>): boolean =>\n item.parent === null || !idMap.has(item.parent);\n // Under a composing strategy a node inside a pasted frame rides it, and\n // offsetting it as well would move it twice.\n const byId = new Map(src.map((item) => [item.id, item]));\n const ridesPastedFrame = (item: Node<TData, TLayer, TPose>): boolean => {\n if (!composes) return false;\n let p = item.parent === null ? undefined : byId.get(item.parent);\n while (p !== undefined) {\n if (definesFrame(p)) return true;\n p = p.parent === null ? undefined : byId.get(p.parent);\n }\n return false;\n };\n // Scene v1 poses are absolute (see the cascade notes above), so the\n // delta applies to EVERY pasted node — the cluster translates rigidly,\n // descendants staying attached to their parents.\n let dx = offset.dx;\n let dy = offset.dy;\n if (ctx?.dropPoint) {\n // Drop-point policy: land the cluster origin (min corner of the root\n // items' bounds) on the drop point; `offset` is ignored.\n let minX = Infinity;\n let minY = Infinity;\n for (const item of src) {\n if (!isRoot(item)) continue;\n const b = poseBounds(item.pose);\n if (b.x < minX) minX = b.x;\n if (b.y < minY) minY = b.y;\n }\n if (Number.isFinite(minX) && Number.isFinite(minY)) {\n dx = ctx.dropPoint.worldX - minX;\n dy = ctx.dropPoint.worldY - minY;\n }\n }\n const out: Node<TData, TLayer, TPose>[] = [];\n for (const item of src) {\n const base = {\n id: idMap.get(item.id)!,\n layer: item.layer,\n parent: isRoot(item) ? null : idMap.get(item.parent as string)!,\n pose: ridesPastedFrame(item) ? copyField(item.pose) : translate(copyField(item.pose), dx, dy),\n data: copyField(item.data),\n };\n if (item.kind === 'container') {\n out.push({\n ...base,\n kind: 'container',\n children: item.children.filter((c) => idMap.has(c)).map((c) => idMap.get(c)!),\n ...(item.clipFromPose ? { clipFromPose: item.clipFromPose } : {}),\n ...(item.dependsOn === 'children' && item.derivePose\n ? { dependsOn: item.dependsOn, derivePose: item.derivePose }\n : {}),\n });\n } else {\n out.push({ ...base, kind: 'leaf' });\n }\n }\n // `src` is parents-before-children (snapshotSelection's DFS order),\n // and this loop preserves it — children re-attach to freshly-inserted\n // parents when the hook's InsertOps apply in order.\n return out;\n },\n // Constant cascade: the hook re-snapshots the just-created items, so\n // repeated pastes stack +12/+12 each time.\n getPasteOffset(): { dx: number; dy: number } {\n return { dx: 12, dy: 12 };\n },\n };\n\n return adapter;\n}\n\n/**\n * React-hook wrapper around `sceneToAdapter`. Memoizes on every option, so\n * the adapter keeps its identity across renders unless one of them changes.\n */\nexport function useSceneAdapter<TData, TLayer extends string, TPose>(\n scene: Scene<TData, TLayer, TPose>,\n options: SceneToAdapterOptions<TData, TLayer, TPose> = {},\n): SceneCanvasAdapter<TData, TLayer, TPose> {\n const {\n selection, commitInsert, insertLayer, layouts, poseDescriptor, cascadeContainerPose, poseComposition,\n } = options;\n return useMemo(\n () => sceneToAdapter(scene, {\n selection, commitInsert, insertLayer, layouts, poseDescriptor, cascadeContainerPose, poseComposition,\n }),\n [scene, selection, commitInsert, insertLayer, layouts, poseDescriptor, cascadeContainerPose, poseComposition],\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"sceneAdapter.js","names":["sceneToAdapter","visibleLayers","out","layer","scene","sel","options","getSelection","setSelection","d","AUTO_POSE_DESCRIPTOR","poseBounds","visualBoundsViaDescriptor","p","poseDescriptorForNode","node","translate","translatePoseViaDescriptor","dx","dy","composition","composes","pickOpts","pickOptsFor","view","regionPickOptions","clipboardEnv","adapter","id","frameAtOrAbove","asNodeId","visible","nid","effectivePose","n","definesFrame","composeWorldPose","g","before","after","pose","descIds","collect","cid","rootId","cn","parentId","i","ids","l","declared","label","applyOpsTo","ops","index","pickability","fnFieldsOfNode","layout","hitTestArea","rect","hitTestLassoPolygon","polygon","mode","created","bounds","snapshotSceneSelection","pasteSceneSnapshot","clipboard","offset","ctx","useSceneAdapter","useMemo","selection","commitInsert","insertLayer","layouts","poseDescriptor","cascadeContainerPose","poseComposition"],"sources":["../../src/canvas/sceneAdapter.ts"],"sourcesContent":["/**\n * Synthesize a `<Canvas>`-compatible adapter from a `Scene` primitive.\n *\n * The Scene owns nodes/poses/parenting and auto-records ops on every mutation.\n * `<SceneCanvas>` calls `sceneToAdapter(scene)` and forwards the result to\n * `<Canvas>`'s `adapter` prop. Selection and hit-testing are not part of the\n * Scene model — Canvas's internal `useSelection` and pose-derived pickEvery\n * cover those.\n *\n * Pose semantics match the rest of the kit: `getPose` / `setPose` return /\n * write **local** coordinates (relative to parent). The Scene stores pose on\n * each node directly; world composition (when needed) is the renderer's job\n * via `composeWorldPose`, not the adapter's.\n */\nimport { useMemo } from 'react';\nimport type {\n AreaSelectAdapter,\n ClipboardSnapshot,\n InsertAdapter,\n PasteCtx,\n LassoHitMode,\n LassoSelectAdapter,\n RegionPickView,\n LayerEnumerableAdapter,\n MoveAdapter,\n ResizeAdapter,\n RotateAdapter,\n} from 'core/adapters/types';\nimport type { LayoutStrategy } from '../layout/types';\nimport type { Op } from 'core/ops/types';\nimport type { Node, Scene } from 'core/scene/types';\nimport { definesFrame, effectivePose } from 'core/scene/effectivePose';\nimport { fnFieldsOfNode } from 'core/scene/nodeFnFields';\nimport { pickability } from 'core/scene/pickability';\nimport { asNodeId } from 'core/scene/types';\nimport { applyOpsTo } from 'core/applyOps';\nimport { hitTestArea, hitTestLassoPolygon, regionPickOptions } from 'canvas/deps/hitTestArea';\nimport type { ScenePickSourceOptions } from 'canvas/pickWalk';\nimport {\n poseDescriptorForNode,\n translatePoseViaDescriptor,\n visualBoundsViaDescriptor,\n type PoseDescriptor,\n} from 'interactions/actions/resize/geometry';\nimport { AUTO_POSE_DESCRIPTOR } from 'interactions/actions/resize/autoPoseDescriptor';\nimport { composeWorldPose, frameAtOrAbove, type PoseComposition } from 'features/groups/composePose';\nimport type { Bounds } from '../core/viewport/fitViewToBounds';\nimport { pasteSceneSnapshot, snapshotSceneSelection, type SceneClipboardEnv } from './sceneClipboard';\n\n/** Minimal selection contract `sceneToAdapter` needs to wire `getSelection` /\n * `setSelection`. Matches `useSelection().adapterMethods` plus an imperative\n * read; pass `useSelection()` itself or `selection.adapterMethods`. */\nexport interface SceneAdapterSelection {\n get?(): string[];\n set?(ids: string[]): void;\n getSelection?(): string[];\n setSelection?(ids: string[]): void;\n}\n\n/** Sibling z-order surface used by reorder ops. Inlined here (rather than\n * pulled from `core/ops/reorder` to avoid import cycles); the `null` parent\n * channel addresses the root sibling list. */\n/** @internal */\ninterface ReorderAdapter {\n getChildren(parentId: string | null): string[];\n setChildOrder(parentId: string | null, ids: string[]): void;\n}\n\n/** Everything the interaction layer can ask of a scene, as one type: the\n * move, resize, rotate, selection, layer and reorder contracts combined.\n * `<SceneCanvas>` synthesizes one of these, which is why most consumers never\n * touch an adapter directly. */\nexport type SceneCanvasAdapter<TData, TLayer extends string, TPose> =\n & MoveAdapter<Node<TData, TLayer, TPose>, TPose>\n & ResizeAdapter<Node<TData, TLayer, TPose>, TPose>\n & RotateAdapter<Node<TData, TLayer, TPose>, TPose>\n & AreaSelectAdapter\n & LassoSelectAdapter\n & LayerEnumerableAdapter<TLayer>\n & ReorderAdapter\n & Partial<InsertAdapter<Node<TData, TLayer, TPose>>>\n // Tighten the parts that are optional on the underlying adapter contracts\n // but unconditionally provided by a scene-backed adapter. Anything that\n // routes scene mutations through this adapter (kit InsertOps, hierarchical\n // hooks like useNest, etc.) can rely on these being present.\n & {\n getParent(id: string): string | null;\n /** The node's pose with every ancestor's frame folded in. Equal to\n * `getPose` unless a `poseComposition` is configured. */\n getWorldPose(id: string): TPose;\n /** Whether `id`'s pose is a frame its children are expressed in — see\n * `definesFrame`. */\n definesFrame(id: string): boolean;\n /** Present only when a composing strategy is configured; the render\n * walk feature-detects it. */\n composePose?(parent: TPose, child: TPose): TPose;\n getSelection(): string[];\n setSelection(ids: string[]): void;\n insertNode(node: Node<TData, TLayer, TPose>, index?: number): void;\n removeNode(id: string): void;\n /** Replace a node's `data` — what a `setData` op writes through. */\n setData(id: string, data: TData): void;\n /** Swap a container's layout — what a `setLayout` op writes through. */\n setLayout(id: string, layout: LayoutStrategy<TPose> | string | null): void;\n getRemovalClosure(ids: readonly string[]): string[];\n applyOps(ops: Op[], label?: string): void;\n snapshotSelection(ids: string[]): ClipboardSnapshot;\n commitPaste(\n clipboard: ClipboardSnapshot,\n offset: { dx: number; dy: number },\n ctx?: PasteCtx,\n ): Node<TData, TLayer, TPose>[];\n getPasteOffset(clipboard: ClipboardSnapshot): { dx: number; dy: number };\n };\n\n/** Optional extras for the synthesized adapter. Pass `commitInsert` to wire\n * the insert gesture into a Scene-owned canvas; the returned object becomes\n * a leaf on the layer named by `layer` (default `'default'`). */\nexport interface SceneToAdapterOptions<TData, TLayer extends string, TPose> {\n /** Factory for new objects. Returning `null` aborts the insert. */\n commitInsert?: (bounds: Bounds) => {\n pose: TPose;\n data: TData;\n id?: string;\n } | null;\n /** Layer to place inserted nodes on. Defaults to the trivial-form layer. */\n insertLayer?: TLayer;\n /** Selection source for `AreaSelectAdapter.getSelection` / `setSelection`.\n * Pass the result of `useSelection()` (or its `adapterMethods`). When\n * omitted, `getSelection` returns `[]` and `setSelection` is a noop —\n * fine for read-only or selection-less canvases, but the marquee gesture\n * won't update any external selection state. */\n selection?: SceneAdapterSelection;\n /** How to read and rewrite this scene's poses. Default `AUTO_POSE_DESCRIPTOR`. */\n poseDescriptor?: PoseDescriptor<TPose>;\n /** Layout strategies keyed by container node id, for containers whose\n * scene node declares none (`ContainerNode.layout` wins). `move` runs its\n * layout-aware pass on them; for inserts, deletes and resizes to reach\n * them too, install them with `useLayoutArrivals`. Pass either a static\n * map, or a `getLayout(id)` function for dynamic resolution. */\n layouts?:\n | Record<string, LayoutStrategy<TPose>>\n | ((containerId: string) => LayoutStrategy<TPose> | null);\n /** When true, `setPose` on a container translates every descendant by the\n * same delta, through the pose descriptor. Scene v1 stores absolute poses,\n * so without it children stay behind. */\n cascadeContainerPose?: boolean;\n /** How a child's stored pose folds into its parent's frame. Omit for the\n * absolute-pose model, where a parent contributes no transform. Supplying a\n * composing strategy makes a container's pose a **frame**: rotating the\n * container rotates its contents, and `setPose` on it must not also\n * translate them, so it cannot be combined with `cascadeContainerPose`. */\n poseComposition?: PoseComposition<TPose>;\n}\n\n/** Derive the adapter for a scene. Reads go straight to the scene; writes are\n * ops applied through its history, so anything done through the adapter is\n * undoable. */\nexport function sceneToAdapter<TData, TLayer extends string, TPose>(\n scene: Scene<TData, TLayer, TPose>,\n options: SceneToAdapterOptions<TData, TLayer, TPose> = {},\n): SceneCanvasAdapter<TData, TLayer, TPose> {\n const visibleLayers = (): Set<TLayer> => {\n const out = new Set<TLayer>();\n for (const layer of scene.layers) {\n if (layer.visible) out.add(layer.id);\n }\n return out;\n };\n\n const sel = options.selection;\n const getSelection = sel?.getSelection ?? sel?.get ?? (() => [] as string[]);\n const setSelection = sel?.setSelection ?? sel?.set ?? (() => {});\n const d = (options.poseDescriptor ?? AUTO_POSE_DESCRIPTOR) as PoseDescriptor<TPose>;\n const poseBounds = (p: TPose, node: unknown): Bounds =>\n visualBoundsViaDescriptor(p, poseDescriptorForNode(d, node));\n const translate = (p: TPose, dx: number, dy: number, node?: unknown): TPose =>\n translatePoseViaDescriptor(\n p, dx, dy, node === undefined ? d : poseDescriptorForNode(d, node),\n );\n\n const composition = options.poseComposition;\n const composes = composition !== undefined && composition.closure !== 'identity';\n const pickOpts: ScenePickSourceOptions<unknown> = composition\n ? { poseComposition: composition as PoseComposition<unknown> }\n : {};\n // The asking view's layer gate and camera, over the adapter's own options.\n const pickOptsFor = (view: RegionPickView | undefined): ScenePickSourceOptions<unknown> =>\n (view ? { ...pickOpts, ...regionPickOptions(view, undefined, undefined) } : pickOpts);\n if (composes && options.cascadeContainerPose) {\n throw new Error(\n 'sceneToAdapter: poseComposition and cascadeContainerPose contradict each other. ' +\n 'Under a composing strategy a child\\'s pose is already relative to its parent, so ' +\n 'the cascade would move every descendant twice. Drop cascadeContainerPose.',\n );\n }\n\n const clipboardEnv: SceneClipboardEnv<TData, TLayer, TPose> = {\n scene,\n composes,\n worldPoseOf: (id) => adapter.getWorldPose(id),\n frameAtOrAbove: (id) => frameAtOrAbove(adapter, id),\n poseBounds,\n translate,\n };\n\n const adapter: SceneCanvasAdapter<TData, TLayer, TPose> = {\n getNode(id) {\n return scene.get(asNodeId(id));\n },\n getNodes() {\n const visible = visibleLayers();\n const out: Node<TData, TLayer, TPose>[] = [];\n for (const n of scene.renderOrderNodes()) {\n if (visible.has(n.layer)) out.push(n);\n }\n return out;\n },\n getPose(id) {\n const nid = asNodeId(id);\n const n = scene.get(nid);\n if (!n) throw new Error(`sceneToAdapter: unknown node \"${id}\"`);\n return effectivePose(scene, n);\n },\n getParent(id) {\n const n = scene.get(asNodeId(id));\n return n?.parent ?? null;\n },\n definesFrame(id) {\n const n = scene.get(asNodeId(id));\n return n === undefined || definesFrame(n);\n },\n getWorldPose(id) {\n if (!composes) return adapter.getPose(id);\n return composeWorldPose(adapter, id, composition!.compose);\n },\n // Only present when it would do something: the render walk skips the fold\n // entirely when this is absent, which is the absolute-pose path.\n ...(composes ? { composePose: composition!.compose } : {}),\n setPose(id, pose) {\n // Container cascade (opt-in): under scene v1's absolute-pose semantics,\n // moving a container needs to translate every descendant by the same\n // delta so children visually stay attached. The whole cascade lands as\n // one scene.batch so undo collapses to a single step.\n if (options.cascadeContainerPose) {\n const node = scene.get(asNodeId(id));\n if (node && node.kind === 'container') {\n const g = poseDescriptorForNode(d, node);\n const before = g.getBounds(node.pose);\n const after = g.getBounds(pose);\n const dx = after.x - before.x;\n const dy = after.y - before.y;\n if (dx !== 0 || dy !== 0) {\n const descIds: string[] = [];\n const collect = (rootId: string): void => {\n for (const cid of scene.childrenOf(asNodeId(rootId))) {\n descIds.push(cid);\n collect(cid);\n }\n };\n collect(id);\n scene.batch('move container', () => {\n scene.setPose(asNodeId(id), pose);\n for (const cid of descIds) {\n const cn = scene.get(asNodeId(cid));\n if (!cn) continue;\n scene.setPose(asNodeId(cid), translate(cn.pose, dx, dy, cn));\n }\n });\n return;\n }\n }\n }\n scene.setPose(asNodeId(id), pose);\n },\n setParent(id, parentId) {\n scene.move(asNodeId(id), parentId === null ? null : asNodeId(parentId));\n },\n getChildren(id) {\n // Reorder ops call this with parentId === null to mean \"root siblings.\"\n // The kit's existing callers always pass a string, so this widening is\n // additive — falls through to scene.childrenOf for the typed path and\n // returns scene.roots for the null path.\n if (id === null) return [...scene.roots];\n return [...scene.childrenOf(asNodeId(id))];\n },\n setChildOrder(parentId, ids) {\n // Batched reorder: each scene.reorder call is its own kit:move log\n // entry, but scene.batch wraps them into one undo unit + one notify.\n scene.batch('Reorder', () => {\n for (let i = 0; i < ids.length; i++) {\n // Skip ids that are already in the target slot to avoid useless\n // log entries.\n const current = parentId === null\n ? scene.roots\n : scene.childrenOf(asNodeId(parentId));\n if (current[i] === ids[i]) continue;\n scene.reorder(asNodeId(ids[i]), i);\n }\n });\n },\n getLayers() {\n return scene.layers.map((l) => ({ id: l.id, visible: l.visible, parallax: l.parallax }));\n },\n getLayout(id) {\n const declared = scene.layoutOf(asNodeId(id));\n if (declared !== null || !options.layouts) return declared;\n return typeof options.layouts === 'function'\n ? options.layouts(id)\n : options.layouts[id] ?? null;\n },\n // Unified applyOps: when a label is supplied the ops are wrapped in a\n // batch checkpoint (history-aware path used by Move/Resize/Rotate/Insert/\n // Delete tools). When a journal is active (via scene's getActiveJournal\n // option), scene.applyBatch routes to the journal instead of recording a\n // new parent-history entry. Without a label the ops are applied transiently\n // via applyOpsTo (AreaSelectAdapter contract — no checkpoint).\n applyOps(ops: Op[], label?: string) {\n if (label !== undefined) {\n scene.applyBatch(ops, label, this);\n } else {\n applyOpsTo(this, ops);\n }\n },\n // Node-mutation surface used by kit InsertOps / DeleteOps (e.g.\n // useNest wrapping the selection in a new container node, or its\n // inverse). Re-adds via the full structural spec so the round-trip\n // survives undo/redo; removes by id.\n insertNode(node: Node<TData, TLayer, TPose>, index?: number) {\n scene.add({\n kind: node.kind,\n layer: node.layer,\n pose: node.pose,\n data: node.data,\n id: node.id,\n ...(index !== undefined ? { index } : {}),\n ...(node.parent !== null ? { parent: node.parent } : {}),\n // Derivation travels with the node, or undo of a delete brings an\n // edge back as a static path that never follows its endpoints again.\n ...(node.dependsOn !== undefined ? { dependsOn: node.dependsOn } : {}),\n ...pickability(node),\n ...fnFieldsOfNode(node),\n });\n },\n removeNode(id: string) {\n scene.remove(asNodeId(id));\n },\n setData(id: string, data: TData) {\n scene.update(asNodeId(id), { data });\n },\n setLayout(id: string, layout: LayoutStrategy<TPose> | string | null) {\n scene.setLayout(asNodeId(id), layout);\n },\n getRemovalClosure(ids: readonly string[]): string[] {\n return [...scene.removalClosure(ids.map(asNodeId))];\n },\n // AreaSelectAdapter surface — included unconditionally so plain\n // `useSelectTool(sceneToAdapter(scene, { selection }))` Just Works for the\n // marquee gesture. `applyOps` (above) dispatches transiently when called\n // without a label, matching the AreaSelectAdapter contract.\n getSelection,\n setSelection,\n // The live marquee's and lasso's own hit-tests. Containers come back:\n // this adapter's consumer has nothing to fold children into them.\n hitTestArea(rect: Bounds, view?: RegionPickView) {\n return hitTestArea(\n scene,\n rect,\n pickOptsFor(view),\n d as PoseDescriptor<unknown>,\n { includeContainers: true },\n );\n },\n hitTestLasso(polygon, mode: LassoHitMode, view?: RegionPickView) {\n return hitTestLassoPolygon(\n scene,\n polygon,\n mode,\n pickOptsFor(view),\n d as PoseDescriptor<unknown>,\n { includeContainers: true },\n );\n },\n // commitInsert (gesture-time leaf insert) is opt-in: present only when\n // `options.commitInsert` is. The full insertNode/removeNode mutators\n // above are always present so kit-side InsertOp / DeleteOp round-trip\n // through scene.add / scene.remove regardless.\n //\n // Contract: this is a pure factory — it constructs a Node spec but does\n // NOT touch the scene. `useInsert`'s onEnd dispatches an `InsertOp`\n // whose apply() calls `adapter.insertNode` → `scene.add`, which is the\n // sole insertion path. Calling `scene.add` here too would double-insert,\n // and the second add throws on id collision (silently dropping the\n // gesture's pointer-up cleanup and breaking the next drag).\n ...(options.commitInsert\n ? {\n commitInsert: (bounds: { x: number; y: number; width: number; height: number }) => {\n const created = options.commitInsert!(bounds);\n if (!created) return null;\n const layer = (options.insertLayer ?? ('default' as TLayer));\n const id = created.id === undefined ? scene.mintId() : asNodeId(created.id);\n return {\n kind: 'leaf',\n id,\n layer,\n pose: created.pose,\n data: created.data,\n parent: null,\n } as Node<TData, TLayer, TPose>;\n },\n }\n : {}),\n // Clipboard seam (`useClipboardOps` / the paste ingestion path).\n snapshotSelection(ids: string[]): ClipboardSnapshot {\n return snapshotSceneSelection(clipboardEnv, ids);\n },\n commitPaste(\n clipboard: ClipboardSnapshot,\n offset: { dx: number; dy: number },\n ctx?: PasteCtx,\n ): Node<TData, TLayer, TPose>[] {\n return pasteSceneSnapshot(clipboardEnv, clipboard, offset, ctx);\n },\n // Constant cascade: the hook re-snapshots the just-created items, so\n // repeated pastes stack +12/+12 each time.\n getPasteOffset(): { dx: number; dy: number } {\n return { dx: 12, dy: 12 };\n },\n };\n\n return adapter;\n}\n\n/**\n * React-hook wrapper around `sceneToAdapter`. Memoizes on every option, so\n * the adapter keeps its identity across renders unless one of them changes.\n */\nexport function useSceneAdapter<TData, TLayer extends string, TPose>(\n scene: Scene<TData, TLayer, TPose>,\n options: SceneToAdapterOptions<TData, TLayer, TPose> = {},\n): SceneCanvasAdapter<TData, TLayer, TPose> {\n const {\n selection, commitInsert, insertLayer, layouts, poseDescriptor, cascadeContainerPose, poseComposition,\n } = options;\n return useMemo(\n () => sceneToAdapter(scene, {\n selection, commitInsert, insertLayer, layouts, poseDescriptor, cascadeContainerPose, poseComposition,\n }),\n [scene, selection, commitInsert, insertLayer, layouts, poseDescriptor, cascadeContainerPose, poseComposition],\n );\n}\n"],"mappings":"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"}
@@ -0,0 +1,112 @@
1
+ import { definesFrame as e } from "../core/scene/effectivePose.js";
2
+ import { asNodeId as t } from "../core/scene/types.js";
3
+ import { NODE_FN_FIELDS as n, createNodeFnFields as r, fnFieldsOfNode as i, fnKeysOf as a } from "../core/scene/nodeFnFields.js";
4
+ import { pickability as o } from "../core/scene/pickability.js";
5
+ //#region src/canvas/sceneClipboard.ts
6
+ function s(e) {
7
+ return Array.isArray(e) ? [...e] : typeof e == "object" && e ? { ...e } : e;
8
+ }
9
+ var c = (e) => Array.isArray(e.dependsOn) ? e.dependsOn : [];
10
+ function l(e, n) {
11
+ let { scene: c } = e, l = r(c.registry), u = new Set(n), d = /* @__PURE__ */ new Set(), f = [], p = (t, n) => {
12
+ if (!e.composes) return t.pose;
13
+ if (n) return e.worldPoseOf(t.id);
14
+ let r = e.frameAtOrAbove(t.parent);
15
+ return r !== null && d.has(r) ? t.pose : e.worldPoseOf(t.id);
16
+ }, m = (e, n = !1) => {
17
+ if (d.has(e)) return;
18
+ let r = c.get(t(e));
19
+ if (r && (d.add(e), f.push({
20
+ kind: r.kind,
21
+ id: r.id,
22
+ layer: r.layer,
23
+ parent: r.parent,
24
+ pose: s(p(r, n)),
25
+ data: s(r.data),
26
+ ...r.kind === "container" ? { children: [...r.children] } : {},
27
+ ...o(r),
28
+ ...r.dependsOn === void 0 ? {} : { dependsOn: s(r.dependsOn) },
29
+ ...i(r),
30
+ ...a(l, r, "jsonKey")
31
+ }), r.kind === "container")) for (let n of c.childrenOf(t(e))) m(n);
32
+ };
33
+ for (let e of n) c.ancestorsOf(t(e)).some((e) => u.has(e)) || m(e, !0);
34
+ return { items: f };
35
+ }
36
+ var u = (e) => typeof e == "function" || typeof e == "object" && !!e && Object.values(e).some((e) => typeof e == "function");
37
+ function d(e, t) {
38
+ let r = {}, i = e.registry;
39
+ for (let e of n) {
40
+ if (e.containersOnly && t.kind !== "container") continue;
41
+ let n = t[e.jsonKey], a = (typeof n == "string" ? i[e.field]?.[n] : void 0) ?? (u(t[e.field]) ? t[e.field] : void 0);
42
+ a !== void 0 && (r[e.field] = a);
43
+ }
44
+ return r;
45
+ }
46
+ function f(e, t) {
47
+ let n = /* @__PURE__ */ new Map(), r = new Set(e.map((e) => e.id));
48
+ for (let i = !0; i;) {
49
+ i = !1;
50
+ for (let a of e) {
51
+ if (n.has(a.id)) continue;
52
+ let e, o = c(a), s = o.filter((e) => !r.has(e)), l = t.get(a.id);
53
+ a.parent !== null && n.has(a.parent) ? e = {
54
+ id: a.id,
55
+ reason: "container-not-pasted"
56
+ } : s.length > 0 ? e = {
57
+ id: a.id,
58
+ reason: "dependency-not-copied",
59
+ missing: s
60
+ } : o.length > 0 && l.derivePath === void 0 && l.derivePose === void 0 && (e = {
61
+ id: a.id,
62
+ reason: "derivation-not-registered"
63
+ }), e !== void 0 && (n.set(a.id, e), r.delete(a.id), i = !0);
64
+ }
65
+ }
66
+ return n;
67
+ }
68
+ function p(t, n, r, i) {
69
+ let a = n.items;
70
+ if (a.length === 0) return [];
71
+ let l = new Map(a.map((e) => [e.id, d(t.scene, e)])), u = f(a, l);
72
+ if (i?.onOmit) for (let e of a) {
73
+ let t = u.get(e.id);
74
+ t && i.onOmit(t);
75
+ }
76
+ let p = u.size === 0 ? a : a.filter((e) => !u.has(e.id)), m = /* @__PURE__ */ new Map();
77
+ for (let e of p) m.set(e.id, t.scene.mintId());
78
+ let h = (e) => e.parent === null || !m.has(e.parent), g = new Map(p.map((e) => [e.id, e])), _ = (n) => {
79
+ if (!t.composes) return !1;
80
+ let r = n.parent === null ? void 0 : g.get(n.parent);
81
+ for (; r !== void 0;) {
82
+ if (e(r)) return !0;
83
+ r = r.parent === null ? void 0 : g.get(r.parent);
84
+ }
85
+ return !1;
86
+ }, v = r.dx, y = r.dy;
87
+ if (i?.dropPoint) {
88
+ let e = Infinity, n = Infinity;
89
+ for (let r of p) {
90
+ if (!h(r)) continue;
91
+ let i = t.poseBounds(r.pose, r);
92
+ i.x < e && (e = i.x), i.y < n && (n = i.y);
93
+ }
94
+ Number.isFinite(e) && Number.isFinite(n) && (v = i.dropPoint.worldX - e, y = i.dropPoint.worldY - n);
95
+ }
96
+ return p.map((e) => ({
97
+ id: m.get(e.id),
98
+ kind: e.kind,
99
+ layer: e.layer,
100
+ parent: h(e) ? null : m.get(e.parent),
101
+ pose: _(e) ? s(e.pose) : t.translate(s(e.pose), v, y, e),
102
+ data: s(e.data),
103
+ ...o(e),
104
+ ...e.kind === "container" ? { children: e.children.filter((e) => m.has(e)).map((e) => m.get(e)) } : {},
105
+ ...e.dependsOn === "children" ? { dependsOn: "children" } : c(e).length > 0 ? { dependsOn: c(e).map((e) => m.get(e)) } : {},
106
+ ...l.get(e.id)
107
+ }));
108
+ }
109
+ //#endregion
110
+ export { p as pasteSceneSnapshot, l as snapshotSceneSelection };
111
+
112
+ //# sourceMappingURL=sceneClipboard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sceneClipboard.js","names":["copyField","value","dependencyList","item","snapshotSceneSelection","env","fnFields","createNodeFnFields","scene","idSet","ids","taken","items","poseFor","n","isRoot","frame","capture","id","asNodeId","pickability","fnFieldsOfNode","fnKeysOf","cid","a","isLive","member","restoredFnFields","out","registry","spec","NODE_FN_FIELDS","key","fn","omissions","present","src","changed","omission","deps","missing","dep","fns","pasteSceneSnapshot","all","clipboard","omitted","ctx","idMap","byId","ridesPastedFrame","p","definesFrame","dx","offset","dy","minX","minY","b","c"],"sources":["../../src/canvas/sceneClipboard.ts"],"sourcesContent":["/**\n * The scene adapter's clipboard seam: what a copy captures and what a paste\n * mints from it.\n *\n * `snapshotSceneSelection` captures adapter-shaped node copies;\n * `pasteSceneSnapshot` is a pure factory — it mints fresh nodes and never\n * touches the scene. Insertion happens through the caller's InsertOps (one per\n * created node, parents before children), which is what makes a whole paste a\n * single undo entry.\n *\n * A snapshot item carries its node's function fields twice: live, for a paste\n * in the same session, and as the scene's registry keys, for a snapshot that\n * crossed JSON on the way back.\n */\nimport type { ClipboardSnapshot, PasteCtx, PasteOmission } from 'core/adapters/types';\nimport type { Node, NodeId, Scene } from 'core/scene/types';\nimport { asNodeId } from 'core/scene/types';\nimport { definesFrame } from 'core/scene/effectivePose';\nimport {\n NODE_FN_FIELDS, createNodeFnFields, fnFieldsOfNode, fnKeysOf, type FnBearingNode,\n} from 'core/scene/nodeFnFields';\nimport { pickability } from 'core/scene/pickability';\nimport type { Bounds } from '../core/viewport/fitViewToBounds';\n\n/** What the seam needs from the adapter it serves. */\nexport interface SceneClipboardEnv<TData, TLayer extends string, TPose> {\n scene: Scene<TData, TLayer, TPose>;\n /** Whether a stored pose is relative to its container's frame. */\n composes: boolean;\n worldPoseOf(id: string): TPose;\n /** The nearest frame-defining container at or above `id`. */\n frameAtOrAbove(id: string | null): string | null;\n poseBounds(pose: TPose, node: unknown): Bounds;\n translate(pose: TPose, dx: number, dy: number, node?: unknown): TPose;\n}\n\n// Spread-level copy per the clipboard contract: mutating a snapshot's\n// pose/data/children must not touch the scene.\nfunction copyField<T>(value: T): T {\n if (Array.isArray(value)) return [...value] as T;\n if (value !== null && typeof value === 'object') return { ...(value as object) } as T;\n return value;\n}\n\ntype Item<TData, TLayer extends string, TPose> =\n Node<TData, TLayer, TPose> & Record<string, unknown>;\n\nconst dependencyList = (item: { dependsOn?: readonly NodeId[] | 'children' }): readonly NodeId[] =>\n (Array.isArray(item.dependsOn) ? item.dependsOn : []);\n\nexport function snapshotSceneSelection<TData, TLayer extends string, TPose>(\n env: SceneClipboardEnv<TData, TLayer, TPose>,\n ids: string[],\n): ClipboardSnapshot {\n const { scene } = env;\n const fnFields = createNodeFnFields<TPose>(scene.registry as never);\n const idSet = new Set(ids);\n const taken = new Set<string>();\n const items: Node<TData, TLayer, TPose>[] = [];\n // A stored pose is relative to its frame, and a node whose frame is not\n // copied with it lands somewhere else entirely on paste. Capture those in\n // world coordinates: every root, and under an envelope root, the nodes\n // sharing the frame the root left behind.\n const poseFor = (n: Node<TData, TLayer, TPose>, isRoot: boolean): TPose => {\n if (!env.composes) return n.pose;\n if (isRoot) return env.worldPoseOf(n.id);\n const frame = env.frameAtOrAbove(n.parent);\n return frame !== null && taken.has(frame) ? n.pose : env.worldPoseOf(n.id);\n };\n\n // DFS from one snapshot root: push the node, then its subtree —\n // parents-before-children, so paste can re-insert in array order.\n const capture = (id: string, isRoot = false): void => {\n if (taken.has(id)) return;\n const n = scene.get(asNodeId(id));\n if (!n) return;\n taken.add(id);\n items.push({\n kind: n.kind,\n id: n.id,\n layer: n.layer,\n parent: n.parent,\n pose: copyField(poseFor(n, isRoot)),\n data: copyField(n.data),\n ...(n.kind === 'container' ? { children: [...n.children] } : {}),\n ...pickability(n),\n ...(n.dependsOn !== undefined ? { dependsOn: copyField(n.dependsOn) } : {}),\n ...fnFieldsOfNode(n),\n ...fnKeysOf(fnFields, n as unknown as FnBearingNode, 'jsonKey'),\n } as Node<TData, TLayer, TPose>);\n if (n.kind === 'container') {\n for (const cid of scene.childrenOf(asNodeId(id))) capture(cid);\n }\n };\n for (const id of ids) {\n // Dedupe: an id whose ancestor is also selected is already covered\n // by that ancestor's subtree walk.\n if (scene.ancestorsOf(asNodeId(id)).some((a) => idSet.has(a))) continue;\n capture(id, true);\n }\n return { items };\n}\n\n// JSON drops a function, and turns a layout strategy into an object with no\n// methods on it: neither is something a pasted node can run.\nconst isLive = (value: unknown): boolean =>\n typeof value === 'function'\n || (typeof value === 'object' && value !== null\n && Object.values(value).some((member) => typeof member === 'function'));\n\n/**\n * The item's function fields: for each, what its registry key names in this\n * scene, else the live one it carries, else nothing.\n */\nfunction restoredFnFields<TData, TLayer extends string, TPose>(\n scene: Scene<TData, TLayer, TPose>,\n item: Item<TData, TLayer, TPose>,\n): Record<string, unknown> {\n const out: Record<string, unknown> = {};\n const registry = scene.registry as Record<string, Record<string, unknown> | undefined>;\n for (const spec of NODE_FN_FIELDS) {\n if (spec.containersOnly && item.kind !== 'container') continue;\n const key = item[spec.jsonKey];\n const registered = typeof key === 'string' ? registry[spec.field]?.[key] : undefined;\n const fn = registered ?? (isLive(item[spec.field]) ? item[spec.field] : undefined);\n if (fn !== undefined) out[spec.field] = fn;\n }\n return out;\n}\n\n/**\n * Which items a paste leaves out, and why. A node deriving from an id list is\n * pasted only with everything it depends on, since a copy still naming the\n * originals would follow them rather than the copies beside it; and only with\n * a derivation to run, since without one it is a placeholder that paints\n * nothing. Leaving one out can strand another, so this runs to a fixed point.\n */\nfunction omissions<TData, TLayer extends string, TPose>(\n src: readonly Item<TData, TLayer, TPose>[],\n fns: ReadonlyMap<string, Record<string, unknown>>,\n): Map<string, PasteOmission> {\n const out = new Map<string, PasteOmission>();\n const present = new Set(src.map((item) => item.id as string));\n for (let changed = true; changed;) {\n changed = false;\n for (const item of src) {\n if (out.has(item.id)) continue;\n let omission: PasteOmission | undefined;\n const deps = dependencyList(item);\n const missing = deps.filter((dep) => !present.has(dep));\n const fn = fns.get(item.id)!;\n if (item.parent !== null && out.has(item.parent)) {\n omission = { id: item.id, reason: 'container-not-pasted' };\n } else if (missing.length > 0) {\n omission = { id: item.id, reason: 'dependency-not-copied', missing };\n } else if (deps.length > 0 && fn.derivePath === undefined && fn.derivePose === undefined) {\n omission = { id: item.id, reason: 'derivation-not-registered' };\n }\n if (omission === undefined) continue;\n out.set(item.id, omission);\n present.delete(item.id);\n changed = true;\n }\n }\n return out;\n}\n\nexport function pasteSceneSnapshot<TData, TLayer extends string, TPose>(\n env: SceneClipboardEnv<TData, TLayer, TPose>,\n clipboard: ClipboardSnapshot,\n offset: { dx: number; dy: number },\n ctx?: PasteCtx,\n): Node<TData, TLayer, TPose>[] {\n // Snapshot items are adapter-shaped node copies: what the snapshot captures,\n // and what this returns (`useClipboardOps` feeds `created` back in as the\n // next cascade source).\n const all = clipboard.items as Item<TData, TLayer, TPose>[];\n if (all.length === 0) return [];\n const fns = new Map(all.map((item) => [item.id as string, restoredFnFields(env.scene, item)]));\n const omitted = omissions(all, fns);\n if (ctx?.onOmit) for (const item of all) {\n const omission = omitted.get(item.id);\n if (omission) ctx.onOmit(omission);\n }\n const src = omitted.size === 0 ? all : all.filter((item) => !omitted.has(item.id));\n\n const idMap = new Map<string, NodeId>();\n for (const item of src) idMap.set(item.id, env.scene.mintId());\n // Items whose captured parent isn't part of the snapshot become roots\n // of the pasted cluster.\n const isRoot = (item: Node<TData, TLayer, TPose>): boolean =>\n item.parent === null || !idMap.has(item.parent);\n // Under a composing strategy a node inside a pasted frame rides it, and\n // offsetting it as well would move it twice.\n const byId = new Map(src.map((item) => [item.id as string, item]));\n const ridesPastedFrame = (item: Node<TData, TLayer, TPose>): boolean => {\n if (!env.composes) return false;\n let p = item.parent === null ? undefined : byId.get(item.parent);\n while (p !== undefined) {\n if (definesFrame(p)) return true;\n p = p.parent === null ? undefined : byId.get(p.parent);\n }\n return false;\n };\n // Without composition poses are absolute, so the delta applies to EVERY\n // pasted node — the cluster translates rigidly, descendants staying\n // attached to their parents.\n let dx = offset.dx;\n let dy = offset.dy;\n if (ctx?.dropPoint) {\n // Drop-point policy: land the cluster origin (min corner of the root\n // items' bounds) on the drop point; `offset` is ignored.\n let minX = Infinity;\n let minY = Infinity;\n for (const item of src) {\n if (!isRoot(item)) continue;\n const b = env.poseBounds(item.pose, item);\n if (b.x < minX) minX = b.x;\n if (b.y < minY) minY = b.y;\n }\n if (Number.isFinite(minX) && Number.isFinite(minY)) {\n dx = ctx.dropPoint.worldX - minX;\n dy = ctx.dropPoint.worldY - minY;\n }\n }\n // `src` is parents-before-children and this keeps it, so children re-attach\n // to freshly inserted parents when the caller's InsertOps apply in order.\n return src.map((item) => ({\n id: idMap.get(item.id)!,\n kind: item.kind,\n layer: item.layer,\n parent: isRoot(item) ? null : idMap.get(item.parent as string)!,\n pose: ridesPastedFrame(item)\n ? copyField(item.pose)\n : env.translate(copyField(item.pose), dx, dy, item),\n data: copyField(item.data),\n ...pickability(item),\n ...(item.kind === 'container'\n ? { children: item.children.filter((c) => idMap.has(c)).map((c) => idMap.get(c)!) }\n : {}),\n ...(item.dependsOn === 'children'\n ? { dependsOn: 'children' as const }\n : dependencyList(item).length > 0\n ? { dependsOn: dependencyList(item).map((dep) => idMap.get(dep)!) }\n : {}),\n ...fns.get(item.id),\n } as Node<TData, TLayer, TPose>));\n}\n"],"mappings":"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"}