@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 +1 @@
1
- {"version":3,"file":"ingest.js","names":["ANY_MODS","ingestAction","items","params","ingestion","deps","insert","scene","selection","applyOps","ctx","ops","label","defaultCommitAdapter","err"],"sources":["../../../../src/interactions/actions/defaults/ingest.ts"],"sourcesContent":["/**\n * @experimental\n * `ingest` — routes externally-arrived content (OS drop, clipboard paste,\n * file picker / `CanvasExtensionApi.ingest`) through the content-handler\n * registry (`features/ingestion/contentHandlers`).\n *\n * Registered ambient with both `drop` and `paste` default bindings, so\n * external content works regardless of the active tool. A tool can still\n * bind `{ kind: 'drop', types: [...] }` itself to intercept (active scope\n * beats ambient).\n *\n * Both bindings declare every modifier `'optional'`: strict matching would\n * otherwise reject Cmd+V paste and macOS Option-drag drops outright.\n *\n * The dispatcher merges event data into `params`: `items` (IngestItem[]),\n * `via` ('drop' | 'paste'), plus `worldX`/`worldY` for drops. Absent\n * coords → `point: null`; handlers pick their own placement policy.\n */\nimport type { Action } from '@weasel-js/routing';\nimport { runIngest, type IngestCtx } from 'features/ingestion/contentHandlers';\nimport type { IngestItem } from '@weasel-js/routing';\nimport { defaultCommitAdapter } from '../defaultCommitAdapter';\n\nconst ANY_MODS = {\n alt: 'optional', ctrl: 'optional', meta: 'optional', shift: 'optional',\n} as const;\n\nexport const ingestAction: Action & { requires: string[] } = {\n id: 'ingest',\n label: 'Insert external content',\n defaultBinding: [\n { kind: 'drop', mods: ANY_MODS },\n { kind: 'paste', mods: ANY_MODS },\n ],\n requires: ['scene', 'selection', 'insert', 'applyOps', 'ingestion'],\n invoker: {\n timing: 'immediate',\n run: (deps, params) => {\n const items = params?.items as IngestItem[] | undefined;\n if (!items || items.length === 0) return;\n const ingestion = deps.ingestion;\n const insert = deps.insert;\n const scene = deps.scene;\n const selection = deps.selection;\n if (!ingestion || !insert || !scene || !selection) return;\n const applyOps = deps.applyOps;\n\n const point =\n typeof params?.worldX === 'number' && typeof params?.worldY === 'number'\n ? { x: params.worldX as number, y: params.worldY as number }\n : null;\n\n const ctx: IngestCtx = {\n point,\n viewportWorldRect: () => ingestion.viewportWorldRect(),\n insert,\n applyOps: (ops, label) => {\n if (applyOps) applyOps(ops, label ?? 'Ingest');\n else scene.applyBatch(ops, label ?? 'Ingest', defaultCommitAdapter(scene, selection.adapterMethods));\n },\n scene,\n selection,\n // Snapshot per ingest event — intentional. The dep's live getters are\n // fresh at dispatch time, and one consistent resolver per drop/paste\n // beats half a multi-file drop resolving through a swapped-in one.\n resolveSrc: ingestion.resolveSrc,\n svg: ingestion.svg,\n clipboard: ingestion.clipboard,\n deps,\n };\n // Fire-and-forget: handler errors are caught inside runIngest, but a\n // malformed item (non-string mime via untyped JS) can still throw in\n // the matching path — keep the rejection out of the event loop.\n runIngest(items, ctx).catch((err) => console.warn('weasel ingest:', err));\n },\n },\n // No `eligible` rule (always eligible): external-content arrival is\n // mode-agnostic in v1. Revisit if a capability-restricted mode needs to\n // refuse drops/pastes (the listener-level editable-target guard already\n // keeps text-editing pastes away from the scene).\n enabled: () => true,\n};\n"],"mappings":";;;AAuBA,IAAMA,IAAW;CACf,KAAK;CAAY,MAAM;CAAY,MAAM;CAAY,OAAO;AAC9D,GAEaC,IAAgD;CAC3D,IAAI;CACJ,OAAO;CACP,gBAAgB,CACd;EAAE,MAAM;EAAQ,MAAMD;CAAS,GAC/B;EAAE,MAAM;EAAS,MAAMA;CAAS,CAClC;CACA,UAAU;EAAC;EAAS;EAAa;EAAU;EAAY;CAAW;CAClE,SAAS;EACP,QAAQ;EACR,MAAM,GAAM,MAAW;GACrB,IAAME,IAAQC,GAAQ;GACtB,IAAI,CAACD,KAASA,EAAM,WAAW,GAAG;GAClC,IAAME,IAAYC,EAAK,WACjBC,IAASD,EAAK,QACdE,IAAQF,EAAK,OACbG,IAAYH,EAAK;GACvB,IAAI,CAACD,KAAa,CAACE,KAAU,CAACC,KAAS,CAACC,GAAW;GACnD,IAAMC,IAAWJ,EAAK,UAOhBK,IAAiB;IACrB,OALA,OAAOP,GAAQ,UAAW,YAAY,OAAOA,GAAQ,UAAW,WAC5D;KAAE,GAAGA,EAAO;KAAkB,GAAGA,EAAO;IAAiB,IACzD;IAIJ,yBAAyBC,EAAU,kBAAkB;IACrD;IACA,WAAW,GAAK,MAAU;KACxB,AAAIK,IAAUA,EAASE,GAAKC,KAAS,QAAQ,IACxCL,EAAM,WAAWI,GAAKC,KAAS,UAAUC,EAAqBN,GAAOC,EAAU,cAAc,CAAC;IACrG;IACA;IACA;IAIA,YAAYJ,EAAU;IACtB,KAAKA,EAAU;IACf,WAAWA,EAAU;IACrB;GACF;GAIA,EAAUF,GAAOQ,CAAG,CAAC,CAAC,OAAO,MAAQ,QAAQ,KAAK,kBAAkBI,CAAG,CAAC;EAC1E;CACF;CAKA,eAAe;AACjB"}
1
+ {"version":3,"file":"ingest.js","names":["ANY_INGEST_MODS","INGEST_REQUIRES","ingestFromEvent","items","params","ingestion","deps","insert","scene","selection","applyOps","ctx","ops","label","defaultCommitAdapter","opts","err","ingestAction"],"sources":["../../../../src/interactions/actions/defaults/ingest.ts"],"sourcesContent":["/**\n * @experimental\n * `ingest` — routes externally-arrived content (OS drop, clipboard paste,\n * file picker / `CanvasExtensionApi.ingest`) through the content-handler\n * registry (`features/ingestion/contentHandlers`).\n *\n * Registered ambient with both `drop` and `paste` default bindings, so\n * external content works regardless of the active tool. A tool can still\n * bind `{ kind: 'drop', types: [...] }` itself to intercept (active scope\n * beats ambient).\n *\n * This is the `ingest` preset's action. A canvas with `edit` and without\n * `ingest` answers a paste with `clipboard.pasteEvent` instead, which runs\n * the same `ingestFromEvent` limited to the kit's copied-node payload;\n * `useStandardActions` never registers the two together.\n *\n * Every binding declares every modifier `'optional'`: strict matching would\n * otherwise reject Cmd+V paste and macOS Option-drag drops outright.\n *\n * The dispatcher merges event data into `params`: `items` (IngestItem[]),\n * `via` ('drop' | 'paste'), plus `worldX`/`worldY` for drops. Absent\n * coords → `point: null`; handlers pick their own placement policy.\n */\nimport type { Action } from '@weasel-js/routing';\nimport type { ActionDeps } from '@weasel-js/routing';\nimport { runIngest, type IngestCtx, type RunIngestOptions } from 'features/ingestion/contentHandlers';\nimport type { IngestItem } from '@weasel-js/routing';\nimport { defaultCommitAdapter } from '../defaultCommitAdapter';\n\nexport const ANY_INGEST_MODS = {\n alt: 'optional', ctrl: 'optional', meta: 'optional', shift: 'optional',\n} as const;\n\n/** The deps {@link ingestFromEvent} reads; an action calling it declares these. */\nexport const INGEST_REQUIRES = ['scene', 'selection', 'insert', 'applyOps', 'ingestion'] as const;\n\n/**\n * @experimental\n * Route one drop or paste event's dispatcher params through the content\n * handlers: builds the `IngestCtx` from the action's deps and calls\n * `runIngest`. `opts` is `runIngest`'s, so an action accepting only some\n * content passes `handlers`.\n */\nexport function ingestFromEvent(\n deps: ActionDeps,\n params: Record<string, unknown> | undefined,\n opts?: RunIngestOptions,\n): void {\n const items = params?.items as IngestItem[] | undefined;\n if (!items || items.length === 0) return;\n const ingestion = deps.ingestion;\n const insert = deps.insert;\n const scene = deps.scene;\n const selection = deps.selection;\n if (!ingestion || !insert || !scene || !selection) return;\n const applyOps = deps.applyOps;\n\n const point =\n typeof params?.worldX === 'number' && typeof params?.worldY === 'number'\n ? { x: params.worldX as number, y: params.worldY as number }\n : null;\n\n const ctx: IngestCtx = {\n point,\n viewportWorldRect: () => ingestion.viewportWorldRect(),\n insert,\n applyOps: (ops, label) => {\n if (applyOps) applyOps(ops, label ?? 'Ingest');\n else scene.applyBatch(ops, label ?? 'Ingest', defaultCommitAdapter(scene, selection.adapterMethods));\n },\n scene,\n selection,\n // Snapshot per ingest event — intentional. The dep's live getters are\n // fresh at dispatch time, and one consistent resolver per drop/paste\n // beats half a multi-file drop resolving through a swapped-in one.\n resolveSrc: ingestion.resolveSrc,\n svg: ingestion.svg,\n clipboard: ingestion.clipboard,\n deps,\n };\n // Fire-and-forget: handler errors are caught inside runIngest, but a\n // malformed item (non-string mime via untyped JS) can still throw in\n // the matching path — keep the rejection out of the event loop.\n runIngest(items, ctx, opts).catch((err) => console.warn('weasel ingest:', err));\n}\n\nexport const ingestAction: Action & { requires: string[] } = {\n id: 'ingest',\n label: 'Insert external content',\n defaultBinding: [\n { kind: 'drop', mods: ANY_INGEST_MODS },\n { kind: 'paste', mods: ANY_INGEST_MODS },\n ],\n requires: [...INGEST_REQUIRES],\n invoker: {\n timing: 'immediate',\n run: (deps, params) => ingestFromEvent(deps, params),\n },\n // No `eligible` rule (always eligible): external-content arrival is\n // mode-agnostic in v1. Revisit if a capability-restricted mode needs to\n // refuse drops/pastes (the listener-level editable-target guard already\n // keeps text-editing pastes away from the scene).\n enabled: () => true,\n};\n"],"mappings":";;;AA6BA,IAAaA,IAAkB;CAC7B,KAAK;CAAY,MAAM;CAAY,MAAM;CAAY,OAAO;AAC9D,GAGaC,IAAkB;CAAC;CAAS;CAAa;CAAU;CAAY;AAAW;AASvF,SAAgBC,EACd,GACA,GACA,GACM;CACN,IAAMC,IAAQC,GAAQ;CACtB,IAAI,CAACD,KAASA,EAAM,WAAW,GAAG;CAClC,IAAME,IAAYC,EAAK,WACjBC,IAASD,EAAK,QACdE,IAAQF,EAAK,OACbG,IAAYH,EAAK;CACvB,IAAI,CAACD,KAAa,CAACE,KAAU,CAACC,KAAS,CAACC,GAAW;CACnD,IAAMC,IAAWJ,EAAK,UAOhBK,IAAiB;EACrB,OALA,OAAOP,GAAQ,UAAW,YAAY,OAAOA,GAAQ,UAAW,WAC5D;GAAE,GAAGA,EAAO;GAAkB,GAAGA,EAAO;EAAiB,IACzD;EAIJ,yBAAyBC,EAAU,kBAAkB;EACrD;EACA,WAAW,GAAK,MAAU;GACxB,AAAIK,IAAUA,EAASE,GAAKC,KAAS,QAAQ,IACxCL,EAAM,WAAWI,GAAKC,KAAS,UAAUC,EAAqBN,GAAOC,EAAU,cAAc,CAAC;EACrG;EACA;EACA;EAIA,YAAYJ,EAAU;EACtB,KAAKA,EAAU;EACf,WAAWA,EAAU;EACrB;CACF;CAIA,EAAUF,GAAOQ,GAAKI,CAAI,CAAC,CAAC,OAAO,MAAQ,QAAQ,KAAK,kBAAkBC,CAAG,CAAC;AAChF;AAEA,IAAaC,IAAgD;CAC3D,IAAI;CACJ,OAAO;CACP,gBAAgB,CACd;EAAE,MAAM;EAAQ,MAAMjB;CAAgB,GACtC;EAAE,MAAM;EAAS,MAAMA;CAAgB,CACzC;CACA,UAAU,CAAC,GAAGC,CAAe;CAC7B,SAAS;EACP,QAAQ;EACR,MAAM,GAAM,MAAWC,EAAgBI,GAAMF,CAAM;CACrD;CAKA,eAAe;AACjB"}
@@ -5,12 +5,11 @@ import { defaultCommitAdapter as c } from "../defaultCommitAdapter.js";
5
5
  import { shapeKindInfo as l } from "../../../core/shapeKinds.js";
6
6
  import { resolveParams as u } from "@weasel-js/routing";
7
7
  //#region src/interactions/actions/defaults/insert.ts
8
- var d = null;
9
- function f(e, t) {
8
+ function d(e, t) {
10
9
  let n = e === "center" ? "center" : "corner";
11
10
  return t ? n === "center" ? "corner" : "center" : n;
12
11
  }
13
- function p(e, t, n, r, i) {
12
+ function f(e, t, n, r, i) {
14
13
  if (i === "center") {
15
14
  let i = Math.abs(n - e), a = Math.abs(r - t);
16
15
  return {
@@ -27,7 +26,7 @@ function p(e, t, n, r, i) {
27
26
  height: Math.abs(r - t)
28
27
  };
29
28
  }
30
- function m(e, t) {
29
+ function p(e, t) {
31
30
  let n = t.x - e.x, r = t.y - e.y, i = Math.hypot(n, r);
32
31
  if (i === 0) return t;
33
32
  let a = Math.PI / 12, o = Math.round(Math.atan2(r, n) / a) * a;
@@ -36,25 +35,22 @@ function m(e, t) {
36
35
  y: e.y + i * Math.sin(o)
37
36
  };
38
37
  }
39
- var h = "gesture";
40
- function g(e, t) {
41
- let n = u(e.opts?.params), r = n?.kind ?? "rect", i = e.gestureCtx, a = i.origin.get(h), o = {
38
+ var m = "gesture";
39
+ function h(e, t) {
40
+ let n = u(e.opts?.params), r = n?.kind ?? "rect", i = e.gestureCtx, a = i.origin.get(m), o = {
42
41
  x: e.currentX,
43
42
  y: e.currentY
44
43
  };
45
- if (r === "line" && e.shiftHeld && (o = m({
46
- x: e.startX,
47
- y: e.startY
48
- }, o)), o = e.snap(o), e.behaviors.length > 0) {
44
+ if (r === "line" && e.shiftHeld && (o = p(a, o)), o = e.snap(o), e.behaviors.length > 0) {
49
45
  i.modifiers = { ...t }, i.pointer = {
50
46
  worldX: e.currentX,
51
47
  worldY: e.currentY,
52
48
  clientX: 0,
53
49
  clientY: 0
54
- }, i.view = e.readView(), i.plane = e.readPlane(), i.current.set(h, o);
55
- let r = f(n?.originMode, e.altHeld);
50
+ }, i.view = e.readView(), i.plane = e.readPlane(), i.current.set(m, o);
51
+ let r = d(n?.originMode, e.altHeld);
56
52
  for (let t of e.behaviors) {
57
- let e = p(a.x, a.y, o.x, o.y, r), n = t.onMove?.(i, {
53
+ let e = f(a.x, a.y, o.x, o.y, r), n = t.onMove?.(i, {
58
54
  start: a,
59
55
  current: o,
60
56
  bounds: e,
@@ -62,14 +58,14 @@ function g(e, t) {
62
58
  });
63
59
  n && (n.start && (a = n.start), n.current && (o = n.current));
64
60
  }
65
- i.current.set(h, o);
61
+ i.current.set(m, o);
66
62
  }
67
63
  e.shaped = {
68
64
  start: a,
69
65
  current: o
70
66
  };
71
67
  }
72
- function _(e, t, n) {
68
+ function g(e, t, n) {
73
69
  let { start: r } = e.shaped, { current: i } = e.shaped;
74
70
  return t === "line" && n === "center" && (r = {
75
71
  x: r.x - (i.x - r.x),
@@ -81,7 +77,7 @@ function _(e, t, n) {
81
77
  currentY: i.y
82
78
  };
83
79
  }
84
- function v(e, t, n, r, i, a) {
80
+ function _(e, t, n, r, i, a) {
85
81
  let o = e?.kind ?? "rect";
86
82
  switch (o) {
87
83
  case "rect":
@@ -138,13 +134,14 @@ function v(e, t, n, r, i, a) {
138
134
  };
139
135
  }
140
136
  }
141
- var y = o({
137
+ var v = o({
142
138
  id: "insert",
143
139
  label: "Insert",
144
140
  group: "insert",
145
141
  eligible: { capability: "creates-shapes" },
146
142
  requires: [
147
143
  "insert",
144
+ "insertLive",
148
145
  "selection",
149
146
  "snap",
150
147
  "textEdit",
@@ -155,17 +152,17 @@ var y = o({
155
152
  invoker: {
156
153
  timing: "ongoing",
157
154
  start(o, s) {
158
- let m = o.deps.insert;
159
- if (!m) return {};
160
- let y = o.deps.selection;
161
- y && y.get().length > 0 && y.clear();
155
+ let p = o.deps.insert;
156
+ if (!p) return {};
157
+ let v = o.deps.selection, x = v ? [...v.get()] : [];
158
+ v && x.length > 0 && v.clear();
162
159
  let S = o.deps.snap, C = S ? (e) => S.point(e) : (e) => e, w = s?.behaviors ?? [], T = t(o.deps), E = e(o.deps), D = C({
163
160
  x: o.world.x,
164
161
  y: o.world.y
165
162
  }), O = {
166
- draggedIds: [h],
167
- origin: /* @__PURE__ */ new Map([[h, D]]),
168
- current: /* @__PURE__ */ new Map([[h, D]]),
163
+ draggedIds: [m],
164
+ origin: /* @__PURE__ */ new Map([[m, D]]),
165
+ current: /* @__PURE__ */ new Map([[m, D]]),
169
166
  snap: null,
170
167
  modifiers: { ...o.modifiers },
171
168
  pointer: {
@@ -180,8 +177,8 @@ var y = o({
180
177
  scratch: {}
181
178
  };
182
179
  for (let e of w) e.onStart?.(O);
183
- let k = O.origin.get(h), A = {
184
- dep: m,
180
+ let k = O.origin.get(m), A = {
181
+ dep: p,
185
182
  textEdit: o.deps.textEdit,
186
183
  snap: C,
187
184
  opts: s,
@@ -195,7 +192,7 @@ var y = o({
195
192
  },
196
193
  scene: o.deps.scene,
197
194
  applyOps: o.deps.applyOps,
198
- selection: y,
195
+ selection: v,
199
196
  startX: o.world.x,
200
197
  startY: o.world.y,
201
198
  currentX: o.world.x,
@@ -203,23 +200,24 @@ var y = o({
203
200
  points: o.drag?.points ?? null,
204
201
  altHeld: o.modifiers.alt,
205
202
  shiftHeld: o.modifiers.shift,
203
+ priorSelection: x,
206
204
  open: !0,
207
205
  userRotation: 0
208
- };
209
- return d = A, {
206
+ }, j = o.deps.insertLive;
207
+ return j && (j.gesture = A), {
210
208
  kind: "insert",
211
209
  onMove(e) {
212
- A.currentX = e.world.x, A.currentY = e.world.y, A.shiftHeld = e.modifiers.shift, A.altHeld = e.modifiers.alt, e.drag?.points && (A.points = e.drag.points), g(A, e.modifiers);
210
+ A.currentX = e.world.x, A.currentY = e.world.y, A.shiftHeld = e.modifiers.shift, A.altHeld = e.modifiers.alt, e.drag?.points && (A.points = e.drag.points), h(A, e.modifiers);
213
211
  },
214
212
  overlay() {
215
213
  if (!A.open) return null;
216
214
  let e = u(A.opts?.params), t = e?.kind ?? "rect";
217
215
  if (!l(t)?.insertPreview) return null;
218
- let n = f(e?.originMode, A.altHeld), r = _(A, t, n), i = p(r.startX, r.startY, r.currentX, r.currentY, n), a = v({
216
+ let n = d(e?.originMode, A.altHeld), r = g(A, t, n), i = f(r.startX, r.startY, r.currentX, r.currentY, n), a = _({
219
217
  ...e ?? {},
220
218
  originMode: n
221
219
  }, r.startX, r.startY, r.currentX, r.currentY, A.points);
222
- return x(a, A.userRotation), {
220
+ return b(a, A.userRotation), {
223
221
  kind: "insertPreview",
224
222
  shape: a.kind,
225
223
  bounds: i,
@@ -231,11 +229,11 @@ var y = o({
231
229
  };
232
230
  },
233
231
  onEnd(e, t) {
234
- if (A.open = !1, d === A && (d = null), t === "cancel") {
235
- a(A.behaviors, A.gestureCtx);
232
+ if (A.open = !1, j?.gesture === A && (j.gesture = null), t === "cancel") {
233
+ a(A.behaviors, A.gestureCtx), A.priorSelection.length > 0 && A.selection?.set(A.priorSelection);
236
234
  return;
237
235
  }
238
- let { dep: o, opts: s } = A, l = e.drag?.points ?? A.points, m = u(s?.params);
236
+ let { dep: o, opts: s } = A, l = e.drag?.points ?? A.points, p = u(s?.params);
239
237
  if (A.behaviors.length > 0) {
240
238
  let e = i(A.behaviors, A.gestureCtx);
241
239
  if (e === null) return;
@@ -244,30 +242,30 @@ var y = o({
244
242
  scene: A.scene,
245
243
  applyOps: A.applyOps,
246
244
  adapter: c(A.scene, A.selection?.adapterMethods)
247
- }, r(m, "Insert", A.behaviors), e);
245
+ }, r(p, "Insert", A.behaviors), e);
248
246
  return;
249
247
  }
250
248
  }
251
- let h = m?.kind ?? "rect", g = f(m?.originMode, A.altHeld), { startX: y, startY: S, currentX: C, currentY: w } = _(A, h, g), T = p(y, S, C, w, g), E = v({
252
- ...m ?? {},
253
- originMode: g
254
- }, y, S, C, w, l);
255
- if (x(E, A.userRotation), !b(T, E.kind)) return;
256
- let D = o.commit(T, E);
257
- D !== null && E.kind === "text" && A.textEdit?.startEdit(String(D), { caret: 0 });
249
+ let m = p?.kind ?? "rect", h = d(p?.originMode, A.altHeld), { startX: v, startY: x, currentX: S, currentY: C } = g(A, m, h), w = f(v, x, S, C, h), T = _({
250
+ ...p ?? {},
251
+ originMode: h
252
+ }, v, x, S, C, l);
253
+ if (b(T, A.userRotation), !y(w, T.kind)) return;
254
+ let E = o.commit(w, T);
255
+ E !== null && T.kind === "text" && A.textEdit?.startEdit(String(E), { caret: 0 });
258
256
  }
259
257
  };
260
258
  }
261
259
  },
262
260
  enabled: () => !0
263
261
  }, s);
264
- function b(e, t) {
262
+ function y(e, t) {
265
263
  return t === "pencil" ? !0 : t === "line" ? e.width !== 0 || e.height !== 0 : e.width !== 0 && e.height !== 0;
266
264
  }
267
- function x(e, t) {
265
+ function b(e, t) {
268
266
  t !== 0 && (e.kind === "star" || e.kind === "polygon") && (e.rotation += t);
269
267
  }
270
- var S = Math.PI / 720, C = {
268
+ var x = Math.PI / 720, S = {
271
269
  id: "insert.adjustRotation",
272
270
  label: "Insert — rotate",
273
271
  group: "insert",
@@ -275,14 +273,15 @@ var S = Math.PI / 720, C = {
275
273
  invoker: {
276
274
  timing: "immediate",
277
275
  run: (e, t) => {
278
- let n = d;
276
+ let n = e.insertLive?.gesture;
279
277
  if (!n || !n.open) return;
280
278
  let r = t?.deltaY ?? 0;
281
- r !== 0 && (n.userRotation += r * S);
279
+ r !== 0 && (n.userRotation += r * x);
282
280
  }
283
- }
281
+ },
282
+ requires: ["insertLive"]
284
283
  };
285
284
  //#endregion
286
- export { y as insertAction, C as insertRotateAction };
285
+ export { v as insertAction, S as insertRotateAction };
287
286
 
288
287
  //# sourceMappingURL=insert.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"insert.js","names":["liveInsertScratch","effectiveOriginMode","nominal","paramsOrigin","altHeld","computeBounds","originMode","dx","currentX","startX","dy","currentY","startY","snapTo15Degrees","end","start","len","step","snapped","GESTURE_KEY","shapeEndpoints","resolved","resolveParams","scratch","kind","\"kind\"","gctx","current","modifiers","mode","\"originMode\"","b","bounds","r","resolveEndpoints","buildExtras","params","sides","\"sides\"","dragAngle","extras","\"rotation\"","\"center\"","\"radius\"","pts","\"points\"","ir","\"innerRadiusRatio\"","\"outerRadius\"","\"samples\"","points","insertAction","inPlane","dep","ctx","selection","snapDep","snap","p","behaviors","opts","readView","gestureViewReader","readPlane","gesturePlaneReader","origin","gestureCtx","startPoint","moveCtx","shapeKindInfo","effectiveExtras","applyUserRotation","reason","d","o","endCtx","reduceBehaviorEnd","commitGestureOps","defaultCommitAdapter","readGestureLifecycle","isCommittableExtent","id","insertLayer","userRotation","ROTATION_SENSITIVITY","insertRotateAction","deltaY"],"sources":["../../../../src/interactions/actions/defaults/insert.ts"],"sourcesContent":["/**\n * `insertAction` — ongoing Action descriptor for drag-to-insert.\n *\n * ## Status: REAL\n *\n * Implements the drag-rect insert logic from `useInsert`:\n * - `start`: validates the `insert` dep and records the drag start point.\n * - `onMove`: tracks the live drag bounds (no scene writes).\n * - `onEnd('commit')`: derives final bounds from drag.start + drag.current;\n * calls `deps.insert.commit(bounds, kind)` to materialise the new node.\n * `kind` comes from `opts.params.kind` (set by the active tool's binding).\n * - `onEnd('cancel')`: no-op.\n *\n * ## Dependencies\n *\n * Requires `insert` dep from DepSchema:\n * `{ commit(bounds, kind): NodeId | null }`\n *\n * `<SceneCanvas>` / `<StandardActionsRegistrar>` should source this dep by\n * delegating to the scene's `add()` with a sensible default data payload for\n * the given `kind`. Override per-consumer for custom node factories.\n *\n * ## Modifiers and snapping\n *\n * Grid snapping comes from the optional `snap` dep, applied to the drag's\n * start and current point (never to freehand pencil samples). The `line`\n * kind additionally honors Shift (constrain to 15°) and reads Alt/center as\n * \"mirror the start around the pointer\" rather than \"grow a symmetric AABB\".\n * Behaviors from the binding's `opts.behaviors` (`InsertBehavior[]` — e.g.\n * `@weasel-js/guides`' `snapToGrid` and `alignInsertBehavior`) run over the two\n * points after those, the way `moveAction` runs its own: `onStart` on the\n * start point, `onMove` on each frame's proposal, `onEnd` on release, where\n * the first answer wins (`null` aborts, `Op[]` commits in place of the\n * insert). `shapeEndpoints` folds them each pump event and `resolveEndpoints`\n * reads the result, so the live preview and the committed node can't\n * disagree.\n *\n * ## What this does NOT wire (vs `useInsert`)\n *\n * - `pointInsert` fallback for click / sub-threshold drags — not wired; a\n * sub-threshold drag produces no insert.\n * - `clickOnly` mode — not applicable to the descriptor model.\n *\n * ## Live preview\n *\n * Insert produces a brand-new node that has no scene id until commit, so\n * the preview-ghost layer (`usePreviewGhostLayer`, keyed by node id) can't\n * paint a silhouette for it. Instead, the action exposes its in-flight\n * geometry via the `overlay()` surface with `kind: 'insertPreview'`. The\n * canvas's `useDispatcherOverlayLayer` rebuilds the shape using the same\n * path builders the commit-time factory uses (`rectPath`, `ellipsePath`,\n * `linePath`, `regularPolygonPath`, `starPath`, polyline / `polygonFromPoints`),\n * so the preview is geometry-faithful to the eventual node.\n *\n * Consumer-defined insert kinds (kinds the kit doesn't know how to draw)\n * skip the preview but still commit normally on release.\n *\n * ## Relationship to `useInsert`\n *\n * `useInsert` calls `adapter.commitInsert(bounds)` which returns a node and\n * dispatches a `createInsertOp`. This descriptor delegates to `deps.insert.commit`\n * which encapsulates both factory + op dispatch in one call. This keeps the\n * dep contract thin and avoids importing `createInsertOp` into the descriptor.\n */\n\nimport type { Action } from '@weasel-js/routing';\nimport type { InvocationCtx, OngoingHandle, BindingOpts, OngoingOverlay, DragSample } from '@weasel-js/routing';\nimport { resolveParams } from '@weasel-js/routing';\nimport type { InsertDep, InsertExtras } from '../depSchema';\nimport type { Op } from 'core/ops/types';\nimport type { Scene } from 'core/scene/types';\nimport type { GestureContext, InsertBehavior, InsertPoint } from '../../gestures/types';\nimport { gesturePlaneReader, gestureViewReader } from '../../gestures/shared/screenTolerance';\nimport type { View } from 'core/viewport/view';\nimport { commitGestureOps, readGestureLifecycle, reduceBehaviorEnd, runBehaviorCancel } from '../gestureLifecycle';\nimport { defaultCommitAdapter } from '../defaultCommitAdapter';\nimport type { TextEditDep } from '../depSchema';\nimport type { SelectionApi } from 'core/selection/useSelection';\nimport { shapeKindInfo } from 'core/shapeKinds';\nimport type { KitInsertShape } from 'core/shapeKinds';\nimport { inPlane, insertLayer } from '../planeInput';\nimport type { PlaneMap } from 'core/viewport/parallax';\n\n// ---------------------------------------------------------------------------\n// Internal scratch\n// ---------------------------------------------------------------------------\n\ninterface InsertScratch {\n dep: InsertDep;\n /** Text-edit dep captured at gesture start, for the text kind's\n * drop-into-the-caret step. Stashed rather than read at commit because\n * the dispatcher only builds the deps bag once, on `start` — every later\n * pump event carries `deps: {}`. */\n textEdit: TextEditDep | undefined;\n /** World-space point snapper from the `snap` dep, or identity when the\n * dep isn't registered. Applied to the drag's start and current point so\n * the live preview and the committed geometry agree. Freehand pencil\n * samples are deliberately NOT snapped — a grid-quantized freehand trail\n * is a staircase, not a stroke. */\n snap: (p: { x: number; y: number }) => { x: number; y: number };\n /** The active binding's opts — re-resolved at commit time so thunked\n * params see the latest tool state (e.g. polygon `sides` after ArrowUp). */\n opts: BindingOpts | undefined;\n /** RAW (unsnapped) drag endpoints in world space. `shapeEndpoints`\n * constrains the angle first, THEN aligns the endpoint to the grid, so\n * the documented modifier ordering holds for the preview and the commit. */\n startX: number;\n startY: number;\n currentX: number;\n currentY: number;\n /** Pointer trail accumulated by the dispatcher in world space. Same array\n * reference as `ctx.drag.points`; pencil-kind commits read from this. */\n points: ReadonlyArray<DragSample> | null;\n /** Live Alt-key state from the most recent pump event. Alt INVERTS the\n * binding's nominal `originMode` (corner → center and vice versa), so\n * the user can press / release Alt mid-drag and the preview/commit\n * flip without needing the dispatcher to re-route to a different\n * binding. Captured per-onMove from `ctx.modifiers.alt`. */\n altHeld: boolean;\n /** Live Shift-key state from the most recent pump event. Constrains the\n * `line` kind to 15° increments (the modifier the line tool documents).\n * Captured per-onMove from `ctx.modifiers.shift`. */\n shiftHeld: boolean;\n /** Cleared once `onEnd` runs so subsequent `overlay()` calls report no\n * in-flight preview (mirrors the areaSelect/lasso convention). */\n open: boolean;\n /** Behaviors from `opts.behaviors`; empty when none were bound. */\n behaviors: InsertBehavior<unknown>[];\n /** Reused gesture context handed to behaviors. Its `origin` holds the\n * start point under {@link GESTURE_KEY}, after `onStart` shaped it. */\n gestureCtx: GestureContext<unknown>;\n readView: () => View | null;\n readPlane: () => PlaneMap | null;\n /** The endpoints after Shift-constrain, the `snap` dep and the behaviors,\n * recomputed on every pump event so each behavior runs once per frame. */\n shaped: { start: InsertPoint; current: InsertPoint };\n /** Captured at `start` for committing a behavior's `Op[]`. */\n scene: Scene<unknown, string, unknown> | undefined;\n applyOps: ((ops: Op[], label: string) => void) | undefined;\n selection: SelectionApi | undefined;\n /** Accumulated user-driven rotation (radians) layered on top of any\n * drag-direction / params rotation. Driven by `insert.adjustRotation`\n * (Shift+wheel during engaged phase). Only consulted for kinds that\n * carry a `rotation` field on their extras (star / polygon today). */\n userRotation: number;\n}\n\n// Module-scoped pointer to the in-flight insert scratch. There is at most\n// one insert gesture at a time (single primary pointer) so a single ref\n// is sufficient. `insert.adjustRotation` reads this to mutate the live\n// scratch without needing handle-passing plumbing through the dispatcher.\nlet liveInsertScratch: InsertScratch | null = null;\n\n/** Resolve the effective origin mode from the binding's nominal opt\n * and live Alt state. Alt inverts: `corner` ⇄ `center`. Applies to\n * every shape kind — radial shapes (polygon/star) included; the\n * overlay paints an `anchorPoint` dot at the click so corner mode\n * reads as anchored even though no polygon vertex sits there.\n */\nfunction effectiveOriginMode(\n paramsOrigin: unknown,\n altHeld: boolean,\n): 'corner' | 'center' {\n const nominal: 'corner' | 'center' = paramsOrigin === 'center' ? 'center' : 'corner';\n if (!altHeld) return nominal;\n return nominal === 'center' ? 'corner' : 'center';\n}\n\n/** Compute the insert AABB from drag endpoints.\n * - `'corner'` (default): bounds = drag rect (top-left → bottom-right of cursor sweep).\n * - `'center'`: bounds = symmetric AABB anchored on the start point.\n * Used when the tool's Alt-modifier binding passes\n * `originMode: 'center'` (Illustrator/Figma convention). */\nfunction computeBounds(\n startX: number, startY: number,\n currentX: number, currentY: number,\n originMode: 'corner' | 'center',\n): { x: number; y: number; width: number; height: number } {\n if (originMode === 'center') {\n const dx = Math.abs(currentX - startX);\n const dy = Math.abs(currentY - startY);\n return { x: startX - dx, y: startY - dy, width: dx * 2, height: dy * 2 };\n }\n return {\n x: Math.min(startX, currentX),\n y: Math.min(startY, currentY),\n width: Math.abs(currentX - startX),\n height: Math.abs(currentY - startY),\n };\n}\n\n/** Constrain `end` to the nearest 15° increment around `start`, preserving\n * the drag length. The line tool's documented Shift behavior. */\nfunction snapTo15Degrees(\n start: { x: number; y: number },\n end: { x: number; y: number },\n): { x: number; y: number } {\n const dx = end.x - start.x;\n const dy = end.y - start.y;\n const len = Math.hypot(dx, dy);\n if (len === 0) return end;\n const step = Math.PI / 12; // 15°\n const snapped = Math.round(Math.atan2(dy, dx) / step) * step;\n return { x: start.x + len * Math.cos(snapped), y: start.y + len * Math.sin(snapped) };\n}\n\n/** The key an insert's single gesture point rides under in the behaviors'\n * `draggedIds` / `origin` / `current` — insert has no node id yet. */\nconst GESTURE_KEY = 'gesture';\n\n/**\n * Shape the raw drag endpoints, in order: the line tool's Shift-constrain\n * (on raw coords, so the locked angle survives), the `snap` dep, then each\n * behavior's `onMove`, each seeing the points the one before it returned.\n * Stored on `scratch.shaped`; `resolveEndpoints` reads it.\n */\nfunction shapeEndpoints(scratch: InsertScratch, modifiers: GestureContext<unknown>['modifiers']): void {\n const resolved = resolveParams(scratch.opts?.params);\n const kind = (resolved?.['kind'] as string | undefined) ?? 'rect';\n const gctx = scratch.gestureCtx;\n let start = gctx.origin.get(GESTURE_KEY) as InsertPoint;\n let current = { x: scratch.currentX, y: scratch.currentY };\n if (kind === 'line' && scratch.shiftHeld) {\n current = snapTo15Degrees({ x: scratch.startX, y: scratch.startY }, current);\n }\n current = scratch.snap(current);\n\n if (scratch.behaviors.length > 0) {\n gctx.modifiers = { ...modifiers };\n gctx.pointer = { worldX: scratch.currentX, worldY: scratch.currentY, clientX: 0, clientY: 0 };\n gctx.view = scratch.readView();\n gctx.plane = scratch.readPlane();\n gctx.current.set(GESTURE_KEY, current);\n const mode = effectiveOriginMode(resolved?.['originMode'], scratch.altHeld);\n for (const b of scratch.behaviors) {\n const bounds = computeBounds(start.x, start.y, current.x, current.y, mode);\n const r = b.onMove?.(gctx, { start, current, bounds, pose: bounds });\n if (!r) continue;\n if (r.start) start = r.start;\n if (r.current) current = r.current;\n }\n gctx.current.set(GESTURE_KEY, current);\n }\n scratch.shaped = { start, current };\n}\n\n/**\n * The effective endpoints: `scratch.shaped`, plus — for the `line` kind\n * only — the alt/center reading as \"mirror the start around the pointer\"\n * rather than \"grow a symmetric AABB\".\n *\n * Every geometry consumer (bounds, extras, preview) goes through this, so\n * the live overlay and the committed node can't disagree.\n */\nfunction resolveEndpoints(\n scratch: InsertScratch,\n kind: string,\n mode: 'corner' | 'center',\n): { startX: number; startY: number; currentX: number; currentY: number } {\n let { start } = scratch.shaped;\n const { current } = scratch.shaped;\n\n // A line has no area, so \"from center\" means the drag is a half-line:\n // mirror the start to the far side of the pointer.\n if (kind === 'line' && mode === 'center') {\n start = { x: start.x - (current.x - start.x), y: start.y - (current.y - start.y) };\n }\n\n return { startX: start.x, startY: start.y, currentX: current.x, currentY: current.y };\n}\n\n/** Build a typed `InsertExtras` from the static params + gesture context.\n * Kit-built-in kinds (line / polygon / star / pencil) read kind-specific\n * fields; unknown kinds pass the raw params through as `{ kind, ... }`. */\nfunction buildExtras(\n params: Record<string, unknown> | undefined,\n startX: number,\n startY: number,\n currentX: number,\n currentY: number,\n points: ReadonlyArray<DragSample> | null,\n): InsertExtras {\n const kind = ((params?.['kind'] as string | undefined) ?? 'rect');\n switch (kind) {\n case 'rect':\n case 'ellipse':\n return { kind } as InsertExtras;\n case 'line':\n // Use the live drag endpoints (not AABB) so the line preserves the\n // user's drag direction — drag from bottom-left to top-right makes a\n // line that slopes up, not the bounds diagonal.\n return { kind: 'line', a: { x: startX, y: startY }, b: { x: currentX, y: currentY } };\n case 'polygon': {\n const sides = Number(params?.['sides'] ?? 6);\n // When the tool omits rotation, point the first vertex along the\n // drag vector so dragging in a direction orients the shape that\n // way. Sub-pixel drags (no direction yet) fall back to 0.\n const dragAngle = (currentX === startX && currentY === startY)\n ? 0\n : Math.atan2(currentY - startY, currentX - startX);\n const rotation = params?.['rotation'] !== undefined\n ? Number(params['rotation'])\n : dragAngle;\n const extras: InsertExtras = { kind: 'polygon', sides, rotation };\n // Drag-from-center: tool's Alt binding passes `originMode:'center'`.\n // Compute polygon center + radius from the drag vector so the shape\n // anchors on the click point. Without this, the dep falls back to\n // inscribing in the AABB (drag-from-corner default).\n if (params?.['originMode'] === 'center') {\n const dx = currentX - startX;\n const dy = currentY - startY;\n (extras as { center?: unknown }).center = { x: startX, y: startY };\n (extras as { radius?: unknown }).radius = Math.hypot(dx, dy);\n } else {\n if (params?.['center'] !== undefined) (extras as { center?: unknown }).center = params['center'];\n if (params?.['radius'] !== undefined) (extras as { radius?: unknown }).radius = params['radius'];\n }\n return extras;\n }\n case 'star': {\n const pts = Number(params?.['points'] ?? 5);\n const ir = Number(params?.['innerRadiusRatio'] ?? 0.5);\n const dragAngle = (currentX === startX && currentY === startY)\n ? 0\n : Math.atan2(currentY - startY, currentX - startX);\n const rotation = params?.['rotation'] !== undefined\n ? Number(params['rotation'])\n : dragAngle;\n const extras: InsertExtras = { kind: 'star', points: pts, innerRadiusRatio: ir, rotation };\n if (params?.['originMode'] === 'center') {\n const dx = currentX - startX;\n const dy = currentY - startY;\n (extras as { center?: unknown }).center = { x: startX, y: startY };\n (extras as { outerRadius?: unknown }).outerRadius = Math.hypot(dx, dy);\n } else {\n if (params?.['center'] !== undefined) (extras as { center?: unknown }).center = params['center'];\n if (params?.['outerRadius'] !== undefined) (extras as { outerRadius?: unknown }).outerRadius = params['outerRadius'];\n }\n return extras;\n }\n case 'pencil':\n // Prefer tool-supplied samples (param) when present — pencil tools may\n // capture richer per-sample data (pressure/tilt). Fall back to the\n // dispatcher's accumulated pointer trail.\n return {\n kind: 'pencil',\n samples: (params?.['samples'] as ReadonlyArray<DragSample> | undefined)\n ?? points\n ?? [],\n };\n default:\n // Consumer-defined kind: pass everything through so a custom insert\n // dep can read its own fields.\n return { ...(params ?? {}), kind } as InsertExtras;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Descriptor\n// ---------------------------------------------------------------------------\n\n/**\n * @experimental\n * Static descriptor for the `insert` Action.\n *\n * Requires dep-schema entry: `insert`.\n * Node `kind` is read from `opts.params.kind`; defaults to `'rect'` when absent.\n *\n * @see useInsert — the React hook this descriptor mirrors for the simple case.\n */\nexport const insertAction: Action & { requires: string[] } = inPlane({\n id: 'insert',\n label: 'Insert',\n group: 'insert',\n eligible: { capability: 'creates-shapes' },\n requires: ['insert', 'selection', 'snap', 'textEdit', 'scene', 'applyOps', 'view'],\n invoker: {\n timing: 'ongoing',\n start(ctx: InvocationCtx, opts?: BindingOpts): OngoingHandle {\n const dep = ctx.deps.insert;\n if (!dep) return {};\n\n // Starting a draw retires any prior selection — the lingering halo\n // around an unrelated node while the user is drawing a new shape is\n // just visual noise, and it primes the UX bug where a drag that\n // continues over the selected node would otherwise drive the move\n // action via fall-through. The clear is unconditional: the user has\n // committed to \"I'm making a new thing\" by engaging a creation tool.\n const selection = ctx.deps.selection;\n if (selection && selection.get().length > 0) {\n selection.clear();\n }\n\n const snapDep = ctx.deps.snap;\n const snap = snapDep\n ? (p: { x: number; y: number }) => snapDep.point(p)\n : (p: { x: number; y: number }) => p;\n const behaviors = (opts?.behaviors ?? []) as InsertBehavior<unknown>[];\n const readView = gestureViewReader(ctx.deps);\n const readPlane = gesturePlaneReader(ctx.deps);\n const origin = snap({ x: ctx.world.x, y: ctx.world.y });\n const gestureCtx: GestureContext<unknown> = {\n draggedIds: [GESTURE_KEY],\n origin: new Map<string, unknown>([[GESTURE_KEY, origin]]),\n current: new Map<string, unknown>([[GESTURE_KEY, origin]]),\n snap: null,\n modifiers: { ...ctx.modifiers },\n pointer: { worldX: ctx.world.x, worldY: ctx.world.y, clientX: 0, clientY: 0 },\n view: readView(),\n plane: readPlane(),\n // No node exists to adapt until commit; insert behaviors read points.\n adapter: undefined as unknown as GestureContext<unknown>['adapter'],\n scratch: {},\n };\n for (const b of behaviors) b.onStart?.(gestureCtx);\n const startPoint = gestureCtx.origin.get(GESTURE_KEY) as InsertPoint;\n\n const scratch: InsertScratch = {\n dep,\n textEdit: ctx.deps.textEdit,\n snap,\n opts,\n behaviors,\n gestureCtx,\n readView,\n readPlane,\n shaped: { start: startPoint, current: startPoint },\n scene: ctx.deps.scene,\n applyOps: ctx.deps.applyOps,\n selection,\n startX: ctx.world.x,\n startY: ctx.world.y,\n currentX: ctx.world.x,\n currentY: ctx.world.y,\n points: ctx.drag?.points ?? null,\n altHeld: ctx.modifiers.alt,\n shiftHeld: ctx.modifiers.shift,\n open: true,\n userRotation: 0,\n };\n liveInsertScratch = scratch;\n\n return {\n kind: 'insert',\n onMove(moveCtx: InvocationCtx): void {\n scratch.currentX = moveCtx.world.x;\n scratch.currentY = moveCtx.world.y;\n scratch.shiftHeld = moveCtx.modifiers.shift;\n // Track live Alt state for the corner ⇄ center toggle. Each\n // pointermove carries fresh modifier state from the dispatcher;\n // releasing / pressing Alt mid-drag flips the bounds mode on\n // the next move tick (true modifier-only events don't fire\n // without a cursor change).\n scratch.altHeld = moveCtx.modifiers.alt;\n // The dispatcher mutates its own per-gesture trail in place but\n // attaches the array reference to each InvocationCtx.drag — keep\n // the latest reference in case the dispatcher swaps it.\n if (moveCtx.drag?.points) scratch.points = moveCtx.drag.points;\n shapeEndpoints(scratch, moveCtx.modifiers);\n },\n overlay(): OngoingOverlay | null {\n if (!scratch.open) return null;\n // Resolve params on every overlay() so thunked params (polygon\n // sides ticking via ArrowUp mid-drag) reflect in the live preview.\n const resolved = resolveParams(scratch.opts?.params);\n const kind = (resolved?.['kind'] as string | undefined) ?? 'rect';\n // Consumer-defined kinds aren't renderable by the kit overlay —\n // skip the preview rather than emit something half-faithful.\n if (!shapeKindInfo(kind)?.insertPreview) return null;\n const mode = effectiveOriginMode(resolved?.['originMode'], scratch.altHeld);\n const pts = resolveEndpoints(scratch, kind, mode);\n const bounds = computeBounds(\n pts.startX, pts.startY, pts.currentX, pts.currentY, mode,\n );\n // Derive extras with the *effective* mode so polygon/star\n // center+radius reflect the live Alt toggle, not the binding's\n // nominal originMode.\n const effectiveExtras = buildExtras(\n { ...(resolved ?? {}), originMode: mode },\n pts.startX, pts.startY, pts.currentX, pts.currentY,\n scratch.points,\n );\n applyUserRotation(effectiveExtras, scratch.userRotation);\n return {\n kind: 'insertPreview',\n shape: effectiveExtras.kind as KitInsertShape,\n bounds,\n extras: effectiveExtras,\n // Anchor dot at the click point — chrome that sells \"this\n // is where the drag started.\" Useful for radial shapes\n // (no vertex at click) and for center mode (dot marks the\n // growth axis).\n anchorPoint: { x: pts.startX, y: pts.startY },\n };\n },\n onEnd(endCtx: InvocationCtx, reason: 'commit' | 'cancel'): void {\n scratch.open = false;\n if (liveInsertScratch === scratch) liveInsertScratch = null;\n if (reason === 'cancel') {\n runBehaviorCancel(scratch.behaviors, scratch.gestureCtx);\n return;\n }\n\n const { dep: d, opts: o } = scratch;\n const points = endCtx.drag?.points ?? scratch.points;\n\n // Resolve params at commit time so thunked params (polygon\n // `sides` adjusted mid-drag, etc.) see the latest tool state.\n const resolved = resolveParams(o?.params);\n\n if (scratch.behaviors.length > 0) {\n const r = reduceBehaviorEnd(scratch.behaviors, scratch.gestureCtx);\n if (r === null) return;\n if (r !== undefined) {\n if (scratch.scene) {\n commitGestureOps(\n {\n scene: scratch.scene,\n applyOps: scratch.applyOps,\n adapter: defaultCommitAdapter(scratch.scene, scratch.selection?.adapterMethods),\n },\n readGestureLifecycle(resolved, 'Insert', scratch.behaviors),\n r,\n );\n }\n return;\n }\n }\n\n const kind = (resolved?.['kind'] as string | undefined) ?? 'rect';\n const mode = effectiveOriginMode(resolved?.['originMode'], scratch.altHeld);\n const { startX, startY, currentX, currentY } = resolveEndpoints(scratch, kind, mode);\n const bounds = computeBounds(startX, startY, currentX, currentY, mode);\n const extras = buildExtras(\n { ...(resolved ?? {}), originMode: mode },\n startX, startY, currentX, currentY, points,\n );\n applyUserRotation(extras, scratch.userRotation);\n\n // Sub-threshold drag — no insert. The test is kind-aware because\n // \"zero size\" isn't one shape:\n // - pencil: a sample trail can be meaningful even when start ≈ end\n // (a closed loop), so no guard at all.\n // - line: has no area by construction. An axis-aligned line has a\n // zero-height (or zero-width) AABB and is perfectly valid — only\n // a zero-LENGTH drag is degenerate. (Shift-constrain makes\n // axis-aligned the common case, which is how this surfaced.)\n // - everything else: a zero extent in either axis is degenerate.\n if (!isCommittableExtent(bounds, extras.kind)) return;\n\n const id = d.commit(bounds, extras);\n\n // A freshly dragged text box is empty, so it draws nothing and the\n // tool's own `click on selected body → enterTextEdit` binding has\n // nothing visible to click. Drop straight into the caret instead —\n // which is also what every other editor does with a text tool.\n // `textEdit` is optional: without it the box is still committed,\n // exactly as before.\n //\n // Read from the scratch, not `endCtx.deps`: the dispatcher builds\n // the deps bag once, at `start`, and passes `deps: {}` on every\n // later pump event. Same reason the insert dep itself is stashed.\n if (id !== null && extras.kind === 'text') {\n scratch.textEdit?.startEdit(String(id), { caret: 0 });\n }\n },\n };\n },\n },\n /**\n * Insert is always available — no selection required. Returns `true` so the\n * dispatcher allows the action through on every drag-on-empty gesture.\n *\n * Fixed from the stale `ActionDisabledReason.SelectionRequired`\n * placeholder that was silently blocking all dispatcher-routed inserts.\n */\n enabled: () => true as const,\n}, insertLayer);\n\n/** Whether a drag produced enough extent to be worth committing, per kind.\n * See the call site in `onEnd` for why this isn't one uniform test. */\nfunction isCommittableExtent(\n bounds: { width: number; height: number },\n kind: string,\n): boolean {\n if (kind === 'pencil') return true;\n if (kind === 'line') return bounds.width !== 0 || bounds.height !== 0;\n return bounds.width !== 0 && bounds.height !== 0;\n}\n\n/** Add a user-driven rotation offset onto kinds that carry rotation. Rect\n * / ellipse / line / pencil don't expose a rotation field on their\n * extras today, so they ignore the offset. */\nfunction applyUserRotation(extras: InsertExtras, userRotation: number): void {\n if (userRotation === 0) return;\n if (extras.kind === 'star' || extras.kind === 'polygon') {\n (extras as { rotation: number }).rotation += userRotation;\n }\n}\n\n/** Radians per unit of wheel deltaY. Tuned so a typical mouse-wheel click\n * (deltaY ≈ 100) yields ~25°, while a trackpad event (deltaY ≈ 1–10)\n * yields a smooth 0.25–2.5° increment. */\nconst ROTATION_SENSITIVITY = Math.PI / 720;\n\n/**\n * @experimental\n * Companion to `insertAction` — adjusts the live insert gesture's\n * `userRotation` based on wheel deltaY. Intended to be bound to\n * Shift+wheel during the insert tool's engaged phase. No-op when no\n * insert is in flight.\n */\nexport const insertRotateAction: Action = {\n id: 'insert.adjustRotation',\n label: 'Insert — rotate',\n group: 'insert',\n eligible: { capability: 'creates-shapes' },\n invoker: {\n timing: 'immediate' as const,\n run: (_deps, params) => {\n const scratch = liveInsertScratch;\n if (!scratch || !scratch.open) return;\n const deltaY = (params as { deltaY?: number } | undefined)?.deltaY ?? 0;\n if (deltaY === 0) return;\n scratch.userRotation += deltaY * ROTATION_SENSITIVITY;\n },\n },\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"insert.js","names":["effectiveOriginMode","nominal","paramsOrigin","altHeld","computeBounds","originMode","dx","currentX","startX","dy","currentY","startY","snapTo15Degrees","end","start","len","step","snapped","GESTURE_KEY","shapeEndpoints","resolved","resolveParams","scratch","kind","\"kind\"","gctx","current","modifiers","mode","\"originMode\"","b","bounds","r","resolveEndpoints","buildExtras","params","sides","\"sides\"","dragAngle","extras","\"rotation\"","\"center\"","\"radius\"","pts","\"points\"","ir","\"innerRadiusRatio\"","\"outerRadius\"","\"samples\"","points","insertAction","inPlane","dep","ctx","selection","priorSelection","snapDep","snap","p","behaviors","opts","readView","gestureViewReader","readPlane","gesturePlaneReader","origin","gestureCtx","startPoint","live","moveCtx","shapeKindInfo","effectiveExtras","applyUserRotation","reason","runBehaviorCancel","d","o","endCtx","reduceBehaviorEnd","commitGestureOps","defaultCommitAdapter","readGestureLifecycle","isCommittableExtent","id","insertLayer","userRotation","ROTATION_SENSITIVITY","insertRotateAction","deps","deltaY"],"sources":["../../../../src/interactions/actions/defaults/insert.ts"],"sourcesContent":["/**\n * `insertAction` — ongoing Action descriptor for drag-to-insert.\n *\n * The drag-rect insert:\n * - `start`: validates the `insert` dep and records the drag start point.\n * - `onMove`: tracks the live drag bounds (no scene writes).\n * - `onEnd('commit')`: derives final bounds from drag.start + drag.current;\n * calls `deps.insert.commit(bounds, kind)` to materialise the new node.\n * `kind` comes from `opts.params.kind` (set by the active tool's binding).\n * - `onEnd('cancel')`: no-op.\n *\n * ## Dependencies\n *\n * Requires `insert` dep from DepSchema:\n * `{ commit(bounds, kind): NodeId | null }`\n *\n * `<SceneCanvas>` / `<StandardActionsRegistrar>` should source this dep by\n * delegating to the scene's `add()` with a sensible default data payload for\n * the given `kind`. Override per-consumer for custom node factories.\n *\n * ## Modifiers and snapping\n *\n * Grid snapping comes from the optional `snap` dep, applied to the drag's\n * start and current point (never to freehand pencil samples). The `line`\n * kind additionally honors Shift (constrain to 15°) and reads Alt/center as\n * \"mirror the start around the pointer\" rather than \"grow a symmetric AABB\".\n * Behaviors from the binding's `opts.behaviors` (`InsertBehavior[]` — e.g.\n * `@weasel-js/guides`' `snapToGrid` and `alignInsertBehavior`) run over the two\n * points after those, the way `moveAction` runs its own: `onStart` on the\n * start point, `onMove` on each frame's proposal, `onEnd` on release, where\n * the first answer wins (`null` aborts, `Op[]` commits in place of the\n * insert). `shapeEndpoints` folds them each pump event and `resolveEndpoints`\n * reads the result, so the live preview and the committed node can't\n * disagree.\n *\n * ## What this does not wire\n *\n * - `pointInsert` fallback for click / sub-threshold drags — not wired; a\n * sub-threshold drag produces no insert.\n * - `clickOnly` mode — not applicable to the descriptor model.\n *\n * ## Live preview\n *\n * Insert produces a brand-new node that has no scene id until commit, so\n * the preview-ghost layer (`usePreviewGhostLayer`, keyed by node id) can't\n * paint a silhouette for it. Instead, the action exposes its in-flight\n * geometry via the `overlay()` surface with `kind: 'insertPreview'`. The\n * canvas's `useDispatcherOverlayLayer` rebuilds the shape using the same\n * path builders the commit-time factory uses (`rectPath`, `ellipsePath`,\n * `linePath`, `regularPolygonPath`, `starPath`, polyline / `polygonFromPoints`),\n * so the preview is geometry-faithful to the eventual node.\n *\n * Consumer-defined insert kinds (kinds the kit doesn't know how to draw)\n * skip the preview but still commit normally on release.\n */\n\nimport type { Action } from '@weasel-js/routing';\nimport type { InvocationCtx, OngoingHandle, BindingOpts, OngoingOverlay, DragSample } from '@weasel-js/routing';\nimport { resolveParams } from '@weasel-js/routing';\nimport type { InsertDep, InsertExtras } from '../depSchema';\nimport type { Op } from 'core/ops/types';\nimport type { Scene } from 'core/scene/types';\nimport type { GestureContext, InsertBehavior, InsertPoint } from '../../gestures/types';\nimport { gesturePlaneReader, gestureViewReader } from '../../gestures/shared/screenTolerance';\nimport type { View } from 'core/viewport/view';\nimport { commitGestureOps, readGestureLifecycle, reduceBehaviorEnd, runBehaviorCancel } from '../gestureLifecycle';\nimport { defaultCommitAdapter } from '../defaultCommitAdapter';\nimport type { TextEditDep } from '../depSchema';\nimport type { SelectionApi } from 'core/selection/useSelection';\nimport type { NodeId } from 'core/scene/types';\nimport { shapeKindInfo } from 'core/shapeKinds';\nimport type { KitInsertShape } from 'core/shapeKinds';\nimport { inPlane, insertLayer } from '../planeInput';\nimport type { PlaneMap } from 'core/viewport/parallax';\n\n// ---------------------------------------------------------------------------\n// Internal scratch\n// ---------------------------------------------------------------------------\n\ninterface InsertScratch {\n dep: InsertDep;\n /** Text-edit dep captured at gesture start, for the text kind's\n * drop-into-the-caret step. Stashed rather than read at commit because\n * the dispatcher only builds the deps bag once, on `start` — every later\n * pump event carries `deps: {}`. */\n textEdit: TextEditDep | undefined;\n /** World-space point snapper from the `snap` dep, or identity when the\n * dep isn't registered. Applied to the drag's start and current point so\n * the live preview and the committed geometry agree. Freehand pencil\n * samples are deliberately NOT snapped — a grid-quantized freehand trail\n * is a staircase, not a stroke. */\n snap: (p: { x: number; y: number }) => { x: number; y: number };\n /** The active binding's opts — re-resolved at commit time so thunked\n * params see the latest tool state (e.g. polygon `sides` after ArrowUp). */\n opts: BindingOpts | undefined;\n /** RAW (unsnapped) drag endpoints in world space. `shapeEndpoints`\n * constrains the angle first, THEN aligns the endpoint to the grid, so\n * the documented modifier ordering holds for the preview and the commit. */\n startX: number;\n startY: number;\n currentX: number;\n currentY: number;\n /** Pointer trail accumulated by the dispatcher in world space. Same array\n * reference as `ctx.drag.points`; pencil-kind commits read from this. */\n points: ReadonlyArray<DragSample> | null;\n /** Live Alt-key state from the most recent pump event. Alt INVERTS the\n * binding's nominal `originMode` (corner → center and vice versa), so\n * the user can press / release Alt mid-drag and the preview/commit\n * flip without needing the dispatcher to re-route to a different\n * binding. Captured per-onMove from `ctx.modifiers.alt`. */\n altHeld: boolean;\n /** Live Shift-key state from the most recent pump event. Constrains the\n * `line` kind to 15° increments (the modifier the line tool documents).\n * Captured per-onMove from `ctx.modifiers.shift`. */\n shiftHeld: boolean;\n /** What was selected before the draw cleared it, to put back on cancel. */\n priorSelection: NodeId[];\n /** Cleared once `onEnd` runs so subsequent `overlay()` calls report no\n * in-flight preview (mirrors the areaSelect/lasso convention). */\n open: boolean;\n /** Behaviors from `opts.behaviors`; empty when none were bound. */\n behaviors: InsertBehavior<unknown>[];\n /** Reused gesture context handed to behaviors. Its `origin` holds the\n * start point under {@link GESTURE_KEY}, after `onStart` shaped it. */\n gestureCtx: GestureContext<unknown>;\n readView: () => View | null;\n readPlane: () => PlaneMap | null;\n /** The endpoints after Shift-constrain, the `snap` dep and the behaviors,\n * recomputed on every pump event so each behavior runs once per frame. */\n shaped: { start: InsertPoint; current: InsertPoint };\n /** Captured at `start` for committing a behavior's `Op[]`. */\n scene: Scene<unknown, string, unknown> | undefined;\n applyOps: ((ops: Op[], label: string) => void) | undefined;\n selection: SelectionApi | undefined;\n /** Accumulated user-driven rotation (radians) layered on top of any\n * drag-direction / params rotation. Driven by `insert.adjustRotation`\n * (Shift+wheel during engaged phase). Only consulted for kinds that\n * carry a `rotation` field on their extras (star / polygon today). */\n userRotation: number;\n}\n\n/** Resolve the effective origin mode from the binding's nominal opt\n * and live Alt state. Alt inverts: `corner` ⇄ `center`. Applies to\n * every shape kind — radial shapes (polygon/star) included; the\n * overlay paints an `anchorPoint` dot at the click so corner mode\n * reads as anchored even though no polygon vertex sits there.\n */\nfunction effectiveOriginMode(\n paramsOrigin: unknown,\n altHeld: boolean,\n): 'corner' | 'center' {\n const nominal: 'corner' | 'center' = paramsOrigin === 'center' ? 'center' : 'corner';\n if (!altHeld) return nominal;\n return nominal === 'center' ? 'corner' : 'center';\n}\n\n/** Compute the insert AABB from drag endpoints.\n * - `'corner'` (default): bounds = drag rect (top-left → bottom-right of cursor sweep).\n * - `'center'`: bounds = symmetric AABB anchored on the start point.\n * Used when the tool's Alt-modifier binding passes\n * `originMode: 'center'` (Illustrator/Figma convention). */\nfunction computeBounds(\n startX: number, startY: number,\n currentX: number, currentY: number,\n originMode: 'corner' | 'center',\n): { x: number; y: number; width: number; height: number } {\n if (originMode === 'center') {\n const dx = Math.abs(currentX - startX);\n const dy = Math.abs(currentY - startY);\n return { x: startX - dx, y: startY - dy, width: dx * 2, height: dy * 2 };\n }\n return {\n x: Math.min(startX, currentX),\n y: Math.min(startY, currentY),\n width: Math.abs(currentX - startX),\n height: Math.abs(currentY - startY),\n };\n}\n\n/** Constrain `end` to the nearest 15° increment around `start`, preserving\n * the drag length. The line tool's documented Shift behavior. */\nfunction snapTo15Degrees(\n start: { x: number; y: number },\n end: { x: number; y: number },\n): { x: number; y: number } {\n const dx = end.x - start.x;\n const dy = end.y - start.y;\n const len = Math.hypot(dx, dy);\n if (len === 0) return end;\n const step = Math.PI / 12; // 15°\n const snapped = Math.round(Math.atan2(dy, dx) / step) * step;\n return { x: start.x + len * Math.cos(snapped), y: start.y + len * Math.sin(snapped) };\n}\n\n/** The key an insert's single gesture point rides under in the behaviors'\n * `draggedIds` / `origin` / `current` — insert has no node id yet. */\nconst GESTURE_KEY = 'gesture';\n\n/**\n * Shape the raw drag endpoints, in order: the line tool's Shift-constrain\n * (on the raw pointer, around the shaped start, so the locked angle\n * survives), the `snap` dep, then each behavior's `onMove`, each seeing the points the one before it returned.\n * Stored on `scratch.shaped`; `resolveEndpoints` reads it.\n */\nfunction shapeEndpoints(scratch: InsertScratch, modifiers: GestureContext<unknown>['modifiers']): void {\n const resolved = resolveParams(scratch.opts?.params);\n const kind = (resolved?.['kind'] as string | undefined) ?? 'rect';\n const gctx = scratch.gestureCtx;\n let start = gctx.origin.get(GESTURE_KEY) as InsertPoint;\n let current = { x: scratch.currentX, y: scratch.currentY };\n if (kind === 'line' && scratch.shiftHeld) {\n current = snapTo15Degrees(start, current);\n }\n current = scratch.snap(current);\n\n if (scratch.behaviors.length > 0) {\n gctx.modifiers = { ...modifiers };\n gctx.pointer = { worldX: scratch.currentX, worldY: scratch.currentY, clientX: 0, clientY: 0 };\n gctx.view = scratch.readView();\n gctx.plane = scratch.readPlane();\n gctx.current.set(GESTURE_KEY, current);\n const mode = effectiveOriginMode(resolved?.['originMode'], scratch.altHeld);\n for (const b of scratch.behaviors) {\n const bounds = computeBounds(start.x, start.y, current.x, current.y, mode);\n const r = b.onMove?.(gctx, { start, current, bounds, pose: bounds });\n if (!r) continue;\n if (r.start) start = r.start;\n if (r.current) current = r.current;\n }\n gctx.current.set(GESTURE_KEY, current);\n }\n scratch.shaped = { start, current };\n}\n\n/**\n * The effective endpoints: `scratch.shaped`, plus — for the `line` kind\n * only — the alt/center reading as \"mirror the start around the pointer\"\n * rather than \"grow a symmetric AABB\".\n *\n * Every geometry consumer (bounds, extras, preview) goes through this, so\n * the live overlay and the committed node can't disagree.\n */\nfunction resolveEndpoints(\n scratch: InsertScratch,\n kind: string,\n mode: 'corner' | 'center',\n): { startX: number; startY: number; currentX: number; currentY: number } {\n let { start } = scratch.shaped;\n const { current } = scratch.shaped;\n\n // A line has no area, so \"from center\" means the drag is a half-line:\n // mirror the start to the far side of the pointer.\n if (kind === 'line' && mode === 'center') {\n start = { x: start.x - (current.x - start.x), y: start.y - (current.y - start.y) };\n }\n\n return { startX: start.x, startY: start.y, currentX: current.x, currentY: current.y };\n}\n\n/** Build a typed `InsertExtras` from the static params + gesture context.\n * Kit-built-in kinds (line / polygon / star / pencil) read kind-specific\n * fields; unknown kinds pass the raw params through as `{ kind, ... }`. */\nfunction buildExtras(\n params: Record<string, unknown> | undefined,\n startX: number,\n startY: number,\n currentX: number,\n currentY: number,\n points: ReadonlyArray<DragSample> | null,\n): InsertExtras {\n const kind = ((params?.['kind'] as string | undefined) ?? 'rect');\n switch (kind) {\n case 'rect':\n case 'ellipse':\n return { kind } as InsertExtras;\n case 'line':\n // Use the live drag endpoints (not AABB) so the line preserves the\n // user's drag direction — drag from bottom-left to top-right makes a\n // line that slopes up, not the bounds diagonal.\n return { kind: 'line', a: { x: startX, y: startY }, b: { x: currentX, y: currentY } };\n case 'polygon': {\n const sides = Number(params?.['sides'] ?? 6);\n // When the tool omits rotation, point the first vertex along the\n // drag vector so dragging in a direction orients the shape that\n // way. Sub-pixel drags (no direction yet) fall back to 0.\n const dragAngle = (currentX === startX && currentY === startY)\n ? 0\n : Math.atan2(currentY - startY, currentX - startX);\n const rotation = params?.['rotation'] !== undefined\n ? Number(params['rotation'])\n : dragAngle;\n const extras: InsertExtras = { kind: 'polygon', sides, rotation };\n // Drag-from-center: tool's Alt binding passes `originMode:'center'`.\n // Compute polygon center + radius from the drag vector so the shape\n // anchors on the click point. Without this, the dep falls back to\n // inscribing in the AABB (drag-from-corner default).\n if (params?.['originMode'] === 'center') {\n const dx = currentX - startX;\n const dy = currentY - startY;\n (extras as { center?: unknown }).center = { x: startX, y: startY };\n (extras as { radius?: unknown }).radius = Math.hypot(dx, dy);\n } else {\n if (params?.['center'] !== undefined) (extras as { center?: unknown }).center = params['center'];\n if (params?.['radius'] !== undefined) (extras as { radius?: unknown }).radius = params['radius'];\n }\n return extras;\n }\n case 'star': {\n const pts = Number(params?.['points'] ?? 5);\n const ir = Number(params?.['innerRadiusRatio'] ?? 0.5);\n const dragAngle = (currentX === startX && currentY === startY)\n ? 0\n : Math.atan2(currentY - startY, currentX - startX);\n const rotation = params?.['rotation'] !== undefined\n ? Number(params['rotation'])\n : dragAngle;\n const extras: InsertExtras = { kind: 'star', points: pts, innerRadiusRatio: ir, rotation };\n if (params?.['originMode'] === 'center') {\n const dx = currentX - startX;\n const dy = currentY - startY;\n (extras as { center?: unknown }).center = { x: startX, y: startY };\n (extras as { outerRadius?: unknown }).outerRadius = Math.hypot(dx, dy);\n } else {\n if (params?.['center'] !== undefined) (extras as { center?: unknown }).center = params['center'];\n if (params?.['outerRadius'] !== undefined) (extras as { outerRadius?: unknown }).outerRadius = params['outerRadius'];\n }\n return extras;\n }\n case 'pencil':\n // Prefer tool-supplied samples (param) when present — pencil tools may\n // capture richer per-sample data (pressure/tilt). Fall back to the\n // dispatcher's accumulated pointer trail.\n return {\n kind: 'pencil',\n samples: (params?.['samples'] as ReadonlyArray<DragSample> | undefined)\n ?? points\n ?? [],\n };\n default:\n // Consumer-defined kind: pass everything through so a custom insert\n // dep can read its own fields.\n return { ...(params ?? {}), kind } as InsertExtras;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Descriptor\n// ---------------------------------------------------------------------------\n\n/**\n * @experimental\n * Static descriptor for the `insert` Action.\n *\n * Requires dep-schema entry: `insert`.\n * Node `kind` is read from `opts.params.kind`; defaults to `'rect'` when absent.\n *\n * @see useInsert — the React hook this descriptor mirrors for the simple case.\n */\nexport const insertAction: Action & { requires: string[] } = inPlane({\n id: 'insert',\n label: 'Insert',\n group: 'insert',\n eligible: { capability: 'creates-shapes' },\n requires: ['insert', 'insertLive', 'selection', 'snap', 'textEdit', 'scene', 'applyOps', 'view'],\n invoker: {\n timing: 'ongoing',\n start(ctx: InvocationCtx, opts?: BindingOpts): OngoingHandle {\n const dep = ctx.deps.insert;\n if (!dep) return {};\n\n // Starting a draw retires any prior selection — the lingering halo\n // around an unrelated node while the user is drawing a new shape is\n // just visual noise, and it primes the UX bug where a drag that\n // continues over the selected node would otherwise drive the move\n // action via fall-through. The clear is unconditional: the user has\n // committed to \"I'm making a new thing\" by engaging a creation tool.\n const selection = ctx.deps.selection;\n const priorSelection = selection ? [...selection.get()] : [];\n if (selection && priorSelection.length > 0) {\n selection.clear();\n }\n\n const snapDep = ctx.deps.snap;\n const snap = snapDep\n ? (p: { x: number; y: number }) => snapDep.point(p)\n : (p: { x: number; y: number }) => p;\n const behaviors = (opts?.behaviors ?? []) as InsertBehavior<unknown>[];\n const readView = gestureViewReader(ctx.deps);\n const readPlane = gesturePlaneReader(ctx.deps);\n const origin = snap({ x: ctx.world.x, y: ctx.world.y });\n const gestureCtx: GestureContext<unknown> = {\n draggedIds: [GESTURE_KEY],\n origin: new Map<string, unknown>([[GESTURE_KEY, origin]]),\n current: new Map<string, unknown>([[GESTURE_KEY, origin]]),\n snap: null,\n modifiers: { ...ctx.modifiers },\n pointer: { worldX: ctx.world.x, worldY: ctx.world.y, clientX: 0, clientY: 0 },\n view: readView(),\n plane: readPlane(),\n // No node exists to adapt until commit; insert behaviors read points.\n adapter: undefined as unknown as GestureContext<unknown>['adapter'],\n scratch: {},\n };\n for (const b of behaviors) b.onStart?.(gestureCtx);\n const startPoint = gestureCtx.origin.get(GESTURE_KEY) as InsertPoint;\n\n const scratch: InsertScratch = {\n dep,\n textEdit: ctx.deps.textEdit,\n snap,\n opts,\n behaviors,\n gestureCtx,\n readView,\n readPlane,\n shaped: { start: startPoint, current: startPoint },\n scene: ctx.deps.scene,\n applyOps: ctx.deps.applyOps,\n selection,\n startX: ctx.world.x,\n startY: ctx.world.y,\n currentX: ctx.world.x,\n currentY: ctx.world.y,\n points: ctx.drag?.points ?? null,\n altHeld: ctx.modifiers.alt,\n shiftHeld: ctx.modifiers.shift,\n priorSelection,\n open: true,\n userRotation: 0,\n };\n const live = ctx.deps.insertLive;\n if (live) live.gesture = scratch;\n\n return {\n kind: 'insert',\n onMove(moveCtx: InvocationCtx): void {\n scratch.currentX = moveCtx.world.x;\n scratch.currentY = moveCtx.world.y;\n scratch.shiftHeld = moveCtx.modifiers.shift;\n // Track live Alt state for the corner ⇄ center toggle. Each\n // pointermove carries fresh modifier state from the dispatcher;\n // releasing / pressing Alt mid-drag flips the bounds mode on\n // the next move tick (true modifier-only events don't fire\n // without a cursor change).\n scratch.altHeld = moveCtx.modifiers.alt;\n // The dispatcher mutates its own per-gesture trail in place but\n // attaches the array reference to each InvocationCtx.drag — keep\n // the latest reference in case the dispatcher swaps it.\n if (moveCtx.drag?.points) scratch.points = moveCtx.drag.points;\n shapeEndpoints(scratch, moveCtx.modifiers);\n },\n overlay(): OngoingOverlay | null {\n if (!scratch.open) return null;\n // Resolve params on every overlay() so thunked params (polygon\n // sides ticking via ArrowUp mid-drag) reflect in the live preview.\n const resolved = resolveParams(scratch.opts?.params);\n const kind = (resolved?.['kind'] as string | undefined) ?? 'rect';\n // Consumer-defined kinds aren't renderable by the kit overlay —\n // skip the preview rather than emit something half-faithful.\n if (!shapeKindInfo(kind)?.insertPreview) return null;\n const mode = effectiveOriginMode(resolved?.['originMode'], scratch.altHeld);\n const pts = resolveEndpoints(scratch, kind, mode);\n const bounds = computeBounds(\n pts.startX, pts.startY, pts.currentX, pts.currentY, mode,\n );\n // Derive extras with the *effective* mode so polygon/star\n // center+radius reflect the live Alt toggle, not the binding's\n // nominal originMode.\n const effectiveExtras = buildExtras(\n { ...(resolved ?? {}), originMode: mode },\n pts.startX, pts.startY, pts.currentX, pts.currentY,\n scratch.points,\n );\n applyUserRotation(effectiveExtras, scratch.userRotation);\n return {\n kind: 'insertPreview',\n shape: effectiveExtras.kind as KitInsertShape,\n bounds,\n extras: effectiveExtras,\n // Anchor dot at the click point — chrome that sells \"this\n // is where the drag started.\" Useful for radial shapes\n // (no vertex at click) and for center mode (dot marks the\n // growth axis).\n anchorPoint: { x: pts.startX, y: pts.startY },\n };\n },\n onEnd(endCtx: InvocationCtx, reason: 'commit' | 'cancel'): void {\n scratch.open = false;\n if (live?.gesture === scratch) live.gesture = null;\n if (reason === 'cancel') {\n runBehaviorCancel(scratch.behaviors, scratch.gestureCtx);\n if (scratch.priorSelection.length > 0) scratch.selection?.set(scratch.priorSelection);\n return;\n }\n\n const { dep: d, opts: o } = scratch;\n const points = endCtx.drag?.points ?? scratch.points;\n\n // Resolve params at commit time so thunked params (polygon\n // `sides` adjusted mid-drag, etc.) see the latest tool state.\n const resolved = resolveParams(o?.params);\n\n if (scratch.behaviors.length > 0) {\n const r = reduceBehaviorEnd(scratch.behaviors, scratch.gestureCtx);\n if (r === null) return;\n if (r !== undefined) {\n if (scratch.scene) {\n commitGestureOps(\n {\n scene: scratch.scene,\n applyOps: scratch.applyOps,\n adapter: defaultCommitAdapter(scratch.scene, scratch.selection?.adapterMethods),\n },\n readGestureLifecycle(resolved, 'Insert', scratch.behaviors),\n r,\n );\n }\n return;\n }\n }\n\n const kind = (resolved?.['kind'] as string | undefined) ?? 'rect';\n const mode = effectiveOriginMode(resolved?.['originMode'], scratch.altHeld);\n const { startX, startY, currentX, currentY } = resolveEndpoints(scratch, kind, mode);\n const bounds = computeBounds(startX, startY, currentX, currentY, mode);\n const extras = buildExtras(\n { ...(resolved ?? {}), originMode: mode },\n startX, startY, currentX, currentY, points,\n );\n applyUserRotation(extras, scratch.userRotation);\n\n // Sub-threshold drag — no insert. The test is kind-aware because\n // \"zero size\" isn't one shape:\n // - pencil: a sample trail can be meaningful even when start ≈ end\n // (a closed loop), so no guard at all.\n // - line: has no area by construction. An axis-aligned line has a\n // zero-height (or zero-width) AABB and is perfectly valid — only\n // a zero-LENGTH drag is degenerate. (Shift-constrain makes\n // axis-aligned the common case, which is how this surfaced.)\n // - everything else: a zero extent in either axis is degenerate.\n if (!isCommittableExtent(bounds, extras.kind)) return;\n\n const id = d.commit(bounds, extras);\n\n // A freshly dragged text box is empty, so it draws nothing and the\n // tool's own `click on selected body → enterTextEdit` binding has\n // nothing visible to click. Drop straight into the caret instead —\n // which is also what every other editor does with a text tool.\n // `textEdit` is optional: without it the box is still committed,\n // exactly as before.\n //\n // Read from the scratch, not `endCtx.deps`: the dispatcher builds\n // the deps bag once, at `start`, and passes `deps: {}` on every\n // later pump event. Same reason the insert dep itself is stashed.\n if (id !== null && extras.kind === 'text') {\n scratch.textEdit?.startEdit(String(id), { caret: 0 });\n }\n },\n };\n },\n },\n /**\n * Insert is always available — no selection required. Returns `true` so the\n * dispatcher allows the action through on every drag-on-empty gesture.\n *\n * Fixed from the stale `ActionDisabledReason.SelectionRequired`\n * placeholder that was silently blocking all dispatcher-routed inserts.\n */\n enabled: () => true as const,\n}, insertLayer);\n\n/** Whether a drag produced enough extent to be worth committing, per kind.\n * See the call site in `onEnd` for why this isn't one uniform test. */\nfunction isCommittableExtent(\n bounds: { width: number; height: number },\n kind: string,\n): boolean {\n if (kind === 'pencil') return true;\n if (kind === 'line') return bounds.width !== 0 || bounds.height !== 0;\n return bounds.width !== 0 && bounds.height !== 0;\n}\n\n/** Add a user-driven rotation offset onto kinds that carry rotation. Rect\n * / ellipse / line / pencil don't expose a rotation field on their\n * extras today, so they ignore the offset. */\nfunction applyUserRotation(extras: InsertExtras, userRotation: number): void {\n if (userRotation === 0) return;\n if (extras.kind === 'star' || extras.kind === 'polygon') {\n (extras as { rotation: number }).rotation += userRotation;\n }\n}\n\n/** Radians per unit of wheel deltaY. Tuned so a typical mouse-wheel click\n * (deltaY ≈ 100) yields ~25°, while a trackpad event (deltaY ≈ 1–10)\n * yields a smooth 0.25–2.5° increment. */\nconst ROTATION_SENSITIVITY = Math.PI / 720;\n\n/**\n * @experimental\n * Companion to `insertAction` — adjusts the live insert gesture's\n * `userRotation` based on wheel deltaY. Intended to be bound to\n * Shift+wheel during the insert tool's engaged phase. No-op when no\n * insert is in flight.\n */\nexport const insertRotateAction: Action = {\n id: 'insert.adjustRotation',\n label: 'Insert — rotate',\n group: 'insert',\n eligible: { capability: 'creates-shapes' },\n invoker: {\n timing: 'immediate' as const,\n run: (deps, params) => {\n const scratch = deps.insertLive?.gesture as InsertScratch | null | undefined;\n if (!scratch || !scratch.open) return;\n const deltaY = (params as { deltaY?: number } | undefined)?.deltaY ?? 0;\n if (deltaY === 0) return;\n scratch.userRotation += deltaY * ROTATION_SENSITIVITY;\n },\n },\n requires: ['insertLive'],\n};\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
- import { editingLayer as e, inPlane as t } from "../planeInput.js";
2
- import { pathToAnchors as n } from "../../../features/paths/anchors.js";
1
+ import { pathToAnchors as e } from "../../../features/paths/anchors.js";
2
+ import { editingLayer as t, inPlane as n } from "../planeInput.js";
3
3
  import { editAnchorSet as r, insertAnchorOnSegment as i, segmentAt as a } from "../../../features/paths/anchorEdits.js";
4
4
  import { ActionDisabledReason as o } from "@weasel-js/routing";
5
5
  //#region src/interactions/actions/defaults/insertPathAnchor.ts
@@ -7,12 +7,12 @@ var s = 8, c = {
7
7
  glyph: "penPlus",
8
8
  fallback: "crosshair"
9
9
  };
10
- function l(e, t, r) {
11
- let i = e?.editAnchors;
10
+ function l(t, n, r) {
11
+ let i = t?.editAnchors;
12
12
  if (!i?.editingId) return null;
13
13
  let o = i.getEditablePath(i.editingId);
14
14
  if (!o || o.kind !== "polygon") return null;
15
- let c = e?.view?.get().scale, l = a(n(o), t, r, {
15
+ let c = t?.view?.get().scale, l = a(e(o), n, r, {
16
16
  tolerancePx: s,
17
17
  ...c ? { scale: c } : {}
18
18
  });
@@ -21,7 +21,7 @@ function l(e, t, r) {
21
21
  hit: l
22
22
  } : null;
23
23
  }
24
- var u = t({
24
+ var u = n({
25
25
  id: "insertPathAnchor",
26
26
  label: "Insert anchor",
27
27
  defaultBinding: {
@@ -43,7 +43,7 @@ var u = t({
43
43
  }
44
44
  },
45
45
  enabled: (e, t) => !e?.editAnchors?.editingId || t && !l(e, t.x, t.y) ? o.NotApplicable : !0
46
- }, e);
46
+ }, t);
47
47
  //#endregion
48
48
  export { u as insertPathAnchorAction };
49
49