@weasel-js/core 1.13.0 → 1.14.0

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 (741) hide show
  1. package/CHANGELOG.md +300 -0
  2. package/README.md +8 -12
  3. package/dist/affordances/hitAffordanceRegions.js +1 -1
  4. package/dist/affordances/hitAffordanceRegions.js.map +1 -1
  5. package/dist/affordances/pathAnchors.js.map +1 -1
  6. package/dist/animation/clipTargets.js +1 -1
  7. package/dist/animation/clipTargets.js.map +1 -1
  8. package/dist/animation/poseTarget.js +5 -32
  9. package/dist/animation/poseTarget.js.map +1 -1
  10. package/dist/{autoPoseDescriptor-CZ1eXbzY.d.ts → autoPoseDescriptor-C25QVb0W.d.ts} +1 -1
  11. package/dist/barrel/canvas.js +8 -8
  12. package/dist/barrel/chrome.js +9 -9
  13. package/dist/barrel/input.js +1 -1
  14. package/dist/barrel/interactions.js +3 -3
  15. package/dist/barrel/paint.js +2 -2
  16. package/dist/barrel/paths.js +19 -17
  17. package/dist/barrel/renderer.js +11 -7
  18. package/dist/barrel/routing.js +4 -1
  19. package/dist/barrel/scene.js +16 -12
  20. package/dist/barrel/text.js +5 -5
  21. package/dist/barrel/viewport.js +8 -8
  22. package/dist/canvas/Canvas.js +2 -2
  23. package/dist/canvas/Canvas.js.map +1 -1
  24. package/dist/canvas/CanvasView.js +20 -14
  25. package/dist/canvas/CanvasView.js.map +1 -1
  26. package/dist/canvas/GestureReason.js +64 -0
  27. package/dist/canvas/GestureReason.js.map +1 -0
  28. package/dist/canvas/GestureReason.module.js +7 -0
  29. package/dist/canvas/GestureReason.module.js.map +1 -0
  30. package/dist/canvas/LeanSceneCanvas.js +3 -1
  31. package/dist/canvas/LeanSceneCanvas.js.map +1 -1
  32. package/dist/canvas/NodeShape.js +2 -0
  33. package/dist/canvas/NodeShape.js.map +1 -1
  34. package/dist/canvas/PickHud.js +7 -3
  35. package/dist/canvas/PickHud.js.map +1 -1
  36. package/dist/canvas/SceneCanvas/CanvasKitProviders.js +1 -1
  37. package/dist/canvas/SceneCanvas/CanvasKitProviders.js.map +1 -1
  38. package/dist/canvas/SceneCanvas/DevHuds.js +2 -2
  39. package/dist/canvas/SceneCanvas/DevHuds.js.map +1 -1
  40. package/dist/canvas/SceneCanvas/PointerProviderIfRoot.js +4 -2
  41. package/dist/canvas/SceneCanvas/PointerProviderIfRoot.js.map +1 -1
  42. package/dist/canvas/SceneCanvas/SceneCanvasInput.js +3 -1
  43. package/dist/canvas/SceneCanvas/SceneCanvasInput.js.map +1 -1
  44. package/dist/canvas/SceneCanvas/brushOverlay.js.map +1 -1
  45. package/dist/canvas/SceneCanvas/builtinToolSets.js +17 -9
  46. package/dist/canvas/SceneCanvas/builtinToolSets.js.map +1 -1
  47. package/dist/canvas/SceneCanvas/canvasPassThrough.js +2 -1
  48. package/dist/canvas/SceneCanvas/canvasPassThrough.js.map +1 -1
  49. package/dist/canvas/SceneCanvas/defaultNodeProperties.js +75 -19
  50. package/dist/canvas/SceneCanvas/defaultNodeProperties.js.map +1 -1
  51. package/dist/canvas/SceneCanvas/defaultNodeRouting.js +7 -1
  52. package/dist/canvas/SceneCanvas/defaultNodeRouting.js.map +1 -1
  53. package/dist/canvas/SceneCanvas/defaultTextEditor.js +108 -0
  54. package/dist/canvas/SceneCanvas/defaultTextEditor.js.map +1 -0
  55. package/dist/canvas/SceneCanvas/describePresets.js +47 -0
  56. package/dist/canvas/SceneCanvas/describePresets.js.map +1 -0
  57. package/dist/canvas/SceneCanvas/features.js +57 -16
  58. package/dist/canvas/SceneCanvas/features.js.map +1 -1
  59. package/dist/canvas/SceneCanvas/mergeLayers.js +10 -1
  60. package/dist/canvas/SceneCanvas/mergeLayers.js.map +1 -1
  61. package/dist/canvas/SceneCanvas/namedPresets.js +52 -24
  62. package/dist/canvas/SceneCanvas/namedPresets.js.map +1 -1
  63. package/dist/canvas/SceneCanvas/presets/arrange.js +35 -10
  64. package/dist/canvas/SceneCanvas/presets/arrange.js.map +1 -1
  65. package/dist/canvas/SceneCanvas/presets/baseline.js +9 -0
  66. package/dist/canvas/SceneCanvas/presets/baseline.js.map +1 -0
  67. package/dist/canvas/SceneCanvas/presets/chrome.js.map +1 -1
  68. package/dist/canvas/SceneCanvas/presets/composites.js +43 -0
  69. package/dist/canvas/SceneCanvas/presets/composites.js.map +1 -0
  70. package/dist/canvas/SceneCanvas/presets/edit.js +79 -26
  71. package/dist/canvas/SceneCanvas/presets/edit.js.map +1 -1
  72. package/dist/canvas/SceneCanvas/presets/ingest.js +1 -0
  73. package/dist/canvas/SceneCanvas/presets/ingest.js.map +1 -1
  74. package/dist/canvas/SceneCanvas/presets/paths.js +58 -16
  75. package/dist/canvas/SceneCanvas/presets/paths.js.map +1 -1
  76. package/dist/canvas/SceneCanvas/presets/select.js +4 -2
  77. package/dist/canvas/SceneCanvas/presets/select.js.map +1 -1
  78. package/dist/canvas/SceneCanvas/presets/tools.js +24 -0
  79. package/dist/canvas/SceneCanvas/presets/tools.js.map +1 -0
  80. package/dist/canvas/SceneCanvas/presets/transform.js +4 -0
  81. package/dist/canvas/SceneCanvas/presets/transform.js.map +1 -1
  82. package/dist/canvas/SceneCanvas/presets/view.js +3 -1
  83. package/dist/canvas/SceneCanvas/presets/view.js.map +1 -1
  84. package/dist/canvas/SceneCanvas/props.js.map +1 -1
  85. package/dist/canvas/SceneCanvas/shapeGeneratorProperties.js +1 -1
  86. package/dist/canvas/SceneCanvas/shapeGeneratorProperties.js.map +1 -1
  87. package/dist/canvas/SceneCanvas/toolRegistry.js +5 -4
  88. package/dist/canvas/SceneCanvas/toolRegistry.js.map +1 -1
  89. package/dist/canvas/SceneCanvas/useCanvasTools.js +26 -10
  90. package/dist/canvas/SceneCanvas/useCanvasTools.js.map +1 -1
  91. package/dist/canvas/SceneCanvas/useContributionRoles.js +15 -2
  92. package/dist/canvas/SceneCanvas/useContributionRoles.js.map +1 -1
  93. package/dist/canvas/SceneCanvas/useDepartureGhostLayer.js +5 -4
  94. package/dist/canvas/SceneCanvas/useDepartureGhostLayer.js.map +1 -1
  95. package/dist/canvas/SceneCanvas/useDispatcherOverlayLayer.js +1 -1
  96. package/dist/canvas/SceneCanvas/useNodeAtPoint.js.map +1 -1
  97. package/dist/canvas/SceneCanvas/useSceneCanvasLayers.js +9 -8
  98. package/dist/canvas/SceneCanvas/useSceneCanvasLayers.js.map +1 -1
  99. package/dist/canvas/SceneCanvas/useSceneCanvasPathEdit.js +2 -2
  100. package/dist/canvas/SceneCanvas/useSceneCanvasPathEdit.js.map +1 -1
  101. package/dist/canvas/SceneCanvas/useSceneCanvasTools.js +4 -1
  102. package/dist/canvas/SceneCanvas/useSceneCanvasTools.js.map +1 -1
  103. package/dist/canvas/SceneCanvas/useSceneChrome.js +7 -4
  104. package/dist/canvas/SceneCanvas/useSceneChrome.js.map +1 -1
  105. package/dist/canvas/SceneCanvas/useSceneGestureDispatcher.js +9 -9
  106. package/dist/canvas/SceneCanvas/useSceneGestureDispatcher.js.map +1 -1
  107. package/dist/canvas/SceneCanvas/useScenePicking.js +4 -7
  108. package/dist/canvas/SceneCanvas/useScenePicking.js.map +1 -1
  109. package/dist/canvas/SceneCanvas/useSceneRedrawSources.js +2 -1
  110. package/dist/canvas/SceneCanvas/useSceneRedrawSources.js.map +1 -1
  111. package/dist/canvas/SceneCanvas/useSceneSelectTool.js +6 -6
  112. package/dist/canvas/SceneCanvas/useSceneSelectTool.js.map +1 -1
  113. package/dist/canvas/SceneCanvas/useSceneStandardActions.js +2 -2
  114. package/dist/canvas/SceneCanvas/useSceneStandardActions.js.map +1 -1
  115. package/dist/canvas/SceneCanvas/useSelectionOverlayLayer.js +1 -1
  116. package/dist/canvas/SceneCanvas/useSelectionOverlayLayer.js.map +1 -1
  117. package/dist/canvas/SceneCanvas/useSurfaceViewInputs.js.map +1 -1
  118. package/dist/canvas/SceneCanvas/useToolKeybindings.js +2 -2
  119. package/dist/canvas/SceneCanvas/useToolKeybindings.js.map +1 -1
  120. package/dist/canvas/SceneCanvas/useViewportActions.js +5 -2
  121. package/dist/canvas/SceneCanvas/useViewportActions.js.map +1 -1
  122. package/dist/canvas/SceneCanvas/worldPointAt.js.map +1 -1
  123. package/dist/canvas/SceneCanvas.js +22 -11
  124. package/dist/canvas/SceneCanvas.js.map +1 -1
  125. package/dist/canvas/SceneViewCanvas.js +1 -0
  126. package/dist/canvas/SceneViewCanvas.js.map +1 -1
  127. package/dist/canvas/ViewMarker.js.map +1 -1
  128. package/dist/canvas/accentColor.js +14 -1
  129. package/dist/canvas/accentColor.js.map +1 -1
  130. package/dist/canvas/affordanceAt.js +2 -2
  131. package/dist/canvas/affordanceAt.js.map +1 -1
  132. package/dist/canvas/buildSceneTree.js +5 -3
  133. package/dist/canvas/buildSceneTree.js.map +1 -1
  134. package/dist/canvas/deps/editAnchors.js +4 -4
  135. package/dist/canvas/deps/editAnchors.js.map +1 -1
  136. package/dist/canvas/deps/enteredGroup.js +14 -5
  137. package/dist/canvas/deps/enteredGroup.js.map +1 -1
  138. package/dist/canvas/deps/ingestion.js +5 -1
  139. package/dist/canvas/deps/ingestion.js.map +1 -1
  140. package/dist/canvas/deps/insert.js.map +1 -1
  141. package/dist/canvas/deps/insertSite.js +5 -3
  142. package/dist/canvas/deps/insertSite.js.map +1 -1
  143. package/dist/canvas/deps/nodeAtPoint.js +1 -12
  144. package/dist/canvas/deps/nodeAtPoint.js.map +1 -1
  145. package/dist/canvas/deps/pathEditCommits.js +3 -3
  146. package/dist/canvas/deps/pathEditCommits.js.map +1 -1
  147. package/dist/canvas/deps/slice.js +16 -2
  148. package/dist/canvas/deps/slice.js.map +1 -1
  149. package/dist/canvas/deps/snap.js +5 -5
  150. package/dist/canvas/deps/snap.js.map +1 -1
  151. package/dist/canvas/deps/textEdit.js +5 -6
  152. package/dist/canvas/deps/textEdit.js.map +1 -1
  153. package/dist/canvas/derivedPath.js +8 -3
  154. package/dist/canvas/derivedPath.js.map +1 -1
  155. package/dist/canvas/getNodeAtPoint.js +2 -2
  156. package/dist/canvas/getNodeAtPoint.js.map +1 -1
  157. package/dist/canvas/insertPreviewExtent.js.map +1 -1
  158. package/dist/canvas/layerSlots.js.map +1 -1
  159. package/dist/canvas/nodeShapes/measurePainter.js +1 -1
  160. package/dist/canvas/nodeShapes/measurePainter.js.map +1 -1
  161. package/dist/canvas/nodeShapes/strokedBounds.js +5 -3
  162. package/dist/canvas/nodeShapes/strokedBounds.js.map +1 -1
  163. package/dist/canvas/overlayRoleStrokes.js +6 -0
  164. package/dist/canvas/overlayRoleStrokes.js.map +1 -1
  165. package/dist/canvas/pickIndex/scenePickIndex.js +10 -12
  166. package/dist/canvas/pickIndex/scenePickIndex.js.map +1 -1
  167. package/dist/canvas/sceneAdapter.js +10 -19
  168. package/dist/canvas/sceneAdapter.js.map +1 -1
  169. package/dist/canvas/sceneClipboard.js +17 -4
  170. package/dist/canvas/sceneClipboard.js.map +1 -1
  171. package/dist/canvas/sceneViewRender.js +3 -2
  172. package/dist/canvas/sceneViewRender.js.map +1 -1
  173. package/dist/canvas/surfaceContribution.js.map +1 -1
  174. package/dist/canvas/useCanvasPaint.js +10 -4
  175. package/dist/canvas/useCanvasPaint.js.map +1 -1
  176. package/dist/canvas/useHitObserver.js +1 -1
  177. package/dist/canvas/useHitObserver.js.map +1 -1
  178. package/dist/canvas/useViewAim.js +1 -1
  179. package/dist/canvas/useViewAim.js.map +1 -1
  180. package/dist/canvas/useViewHelpers.js +8 -5
  181. package/dist/canvas/useViewHelpers.js.map +1 -1
  182. package/dist/canvas/useViewNesting.js +39 -12
  183. package/dist/canvas/useViewNesting.js.map +1 -1
  184. package/dist/canvas/viewInputs.js.map +1 -1
  185. package/dist/canvas/viewMarkers.js +2 -2
  186. package/dist/canvas/viewMarkers.js.map +1 -1
  187. package/dist/canvas/viewRegistry.js +2 -2
  188. package/dist/canvas/viewRegistry.js.map +1 -1
  189. package/dist/canvas/viewSnap.js +67 -0
  190. package/dist/canvas/viewSnap.js.map +1 -0
  191. package/dist/clipboard.d.ts +6 -12
  192. package/dist/{clone-qb2e1F5p.d.ts → clone-Bz4iqGfE.d.ts} +10 -5
  193. package/dist/clone.d.ts +5 -5
  194. package/dist/core/geometry/booleanOfPaths.js +23 -0
  195. package/dist/core/geometry/booleanOfPaths.js.map +1 -0
  196. package/dist/core/geometry/pathPoseDescriptor.js +12 -9
  197. package/dist/core/geometry/pathPoseDescriptor.js.map +1 -1
  198. package/dist/core/geometry/poseDescriptor.js +12 -3
  199. package/dist/core/geometry/poseDescriptor.js.map +1 -1
  200. package/dist/core/geometry/targetFrame.js +2 -13
  201. package/dist/core/geometry/targetFrame.js.map +1 -1
  202. package/dist/core/layers/render.js +2 -1
  203. package/dist/core/layers/render.js.map +1 -1
  204. package/dist/core/layers/retain.js +5 -3
  205. package/dist/core/layers/retain.js.map +1 -1
  206. package/dist/core/ops/setPath.js +3 -0
  207. package/dist/core/ops/setPath.js.map +1 -1
  208. package/dist/core/paint/meshKindLazy.js.map +1 -1
  209. package/dist/core/paint/paintKindEntry.js.map +1 -1
  210. package/dist/core/paint/paintKinds.js +8 -1
  211. package/dist/core/paint/paintKinds.js.map +1 -1
  212. package/dist/core/scene/NodeProperties.js.map +1 -1
  213. package/dist/core/scene/NodeRouting.js.map +1 -1
  214. package/dist/core/scene/booleanGroup.js +33 -0
  215. package/dist/core/scene/booleanGroup.js.map +1 -0
  216. package/dist/core/scene/booleanOfChildren.js +53 -0
  217. package/dist/core/scene/booleanOfChildren.js.map +1 -0
  218. package/dist/core/scene/carryDescendants.js +18 -6
  219. package/dist/core/scene/carryDescendants.js.map +1 -1
  220. package/dist/core/scene/composeFrame.js +42 -5
  221. package/dist/core/scene/composeFrame.js.map +1 -1
  222. package/dist/core/scene/composePose.js +35 -16
  223. package/dist/core/scene/composePose.js.map +1 -1
  224. package/dist/core/scene/depMemo.js +36 -18
  225. package/dist/core/scene/depMemo.js.map +1 -1
  226. package/dist/core/scene/derivedParts.js +2 -23
  227. package/dist/core/scene/derivedParts.js.map +1 -1
  228. package/dist/core/scene/effectivePose.js +10 -0
  229. package/dist/core/scene/effectivePose.js.map +1 -1
  230. package/dist/core/scene/historyForm.js +5 -4
  231. package/dist/core/scene/historyForm.js.map +1 -1
  232. package/dist/core/scene/kitOps.js +5 -71
  233. package/dist/core/scene/kitOps.js.map +1 -1
  234. package/dist/core/scene/kitRegistry.js +5 -0
  235. package/dist/core/scene/kitRegistry.js.map +1 -1
  236. package/dist/core/scene/layerOps.js +82 -0
  237. package/dist/core/scene/layerOps.js.map +1 -0
  238. package/dist/core/scene/layoutPass.js +14 -12
  239. package/dist/core/scene/layoutPass.js.map +1 -1
  240. package/dist/core/scene/lockGuard.js +9 -3
  241. package/dist/core/scene/lockGuard.js.map +1 -1
  242. package/dist/core/scene/nestedHit.js +5 -5
  243. package/dist/core/scene/nestedHit.js.map +1 -1
  244. package/dist/core/scene/nodeFlags.js +8 -2
  245. package/dist/core/scene/nodeFlags.js.map +1 -1
  246. package/dist/core/scene/nodeGates.js +31 -2
  247. package/dist/core/scene/nodeGates.js.map +1 -1
  248. package/dist/core/scene/pathEffects/effects.js +22 -3
  249. package/dist/core/scene/pathEffects/effects.js.map +1 -1
  250. package/dist/core/scene/pathEffects/textAlong.js +16 -3
  251. package/dist/core/scene/pathEffects/textAlong.js.map +1 -1
  252. package/dist/core/scene/pathEffects/textAlongBands.js +65 -0
  253. package/dist/core/scene/pathEffects/textAlongBands.js.map +1 -0
  254. package/dist/core/scene/reconcileSpecs.js +1 -1
  255. package/dist/core/scene/reconcileSpecs.js.map +1 -1
  256. package/dist/core/scene/scene.js +11 -5
  257. package/dist/core/scene/scene.js.map +1 -1
  258. package/dist/core/scene/sceneEdits.js +5 -2
  259. package/dist/core/scene/sceneEdits.js.map +1 -1
  260. package/dist/core/scene/scenePoseAdapter.js +10 -1
  261. package/dist/core/scene/scenePoseAdapter.js.map +1 -1
  262. package/dist/core/scene/scrollOffsets.js +93 -0
  263. package/dist/core/scene/scrollOffsets.js.map +1 -0
  264. package/dist/core/scene/serialization.js +15 -5
  265. package/dist/core/scene/serialization.js.map +1 -1
  266. package/dist/core/scene/statedFields.js +2 -1
  267. package/dist/core/scene/statedFields.js.map +1 -1
  268. package/dist/core/scene/strategyView.js +35 -0
  269. package/dist/core/scene/strategyView.js.map +1 -0
  270. package/dist/core/scene/types.js.map +1 -1
  271. package/dist/core/scene/useScene.js +2 -0
  272. package/dist/core/scene/useScene.js.map +1 -1
  273. package/dist/core/scene/worldSave.js +87 -0
  274. package/dist/core/scene/worldSave.js.map +1 -0
  275. package/dist/core/selection/selectionTarget.js +1 -1
  276. package/dist/core/selection/selectionTarget.js.map +1 -1
  277. package/dist/{cornerHandles-CNCb7aTY.d.ts → cornerHandles-DpmQM_z5.d.ts} +1 -1
  278. package/dist/{depSchema-CpIQzKWQ.d.ts → depSchema-C3BwxitB.d.ts} +119 -99
  279. package/dist/devtools-protocol.d.ts +2 -2
  280. package/dist/devtools.d.ts +2 -2
  281. package/dist/{features → domains}/chrome-caps/buildChromeCtx.js +1 -1
  282. package/dist/domains/chrome-caps/buildChromeCtx.js.map +1 -0
  283. package/dist/{features → domains}/chrome-caps/conditions.js +1 -1
  284. package/dist/domains/chrome-caps/conditions.js.map +1 -0
  285. package/dist/{features → domains}/chrome-caps/defaults.js +1 -1
  286. package/dist/domains/chrome-caps/defaults.js.map +1 -0
  287. package/dist/{features → domains}/chrome-caps/resolve.js +1 -1
  288. package/dist/domains/chrome-caps/resolve.js.map +1 -0
  289. package/dist/{features → domains}/chrome-caps/useChromeCaps.js +1 -1
  290. package/dist/domains/chrome-caps/useChromeCaps.js.map +1 -0
  291. package/dist/{features → domains}/chrome-caps/useHoverTracking.js +1 -1
  292. package/dist/domains/chrome-caps/useHoverTracking.js.map +1 -0
  293. package/dist/{features → domains}/ingestion/contentHandlers.js +20 -3
  294. package/dist/domains/ingestion/contentHandlers.js.map +1 -0
  295. package/dist/domains/ingestion/ghost.js +56 -0
  296. package/dist/domains/ingestion/ghost.js.map +1 -0
  297. package/dist/{features → domains}/ingestion/imageHandler.js +1 -1
  298. package/dist/domains/ingestion/imageHandler.js.map +1 -0
  299. package/dist/domains/ingestion/kitHandlers.js +22 -0
  300. package/dist/domains/ingestion/kitHandlers.js.map +1 -0
  301. package/dist/{features → domains}/ingestion/openFilePicker.js +1 -1
  302. package/dist/domains/ingestion/openFilePicker.js.map +1 -0
  303. package/dist/{features → domains}/ingestion/placement.js +1 -1
  304. package/dist/domains/ingestion/placement.js.map +1 -0
  305. package/dist/{features → domains}/ingestion/svgHandler.js +1 -1
  306. package/dist/domains/ingestion/svgHandler.js.map +1 -0
  307. package/dist/{features → domains}/ingestion/textHandler.js +9 -7
  308. package/dist/domains/ingestion/textHandler.js.map +1 -0
  309. package/dist/{features → domains}/ingestion/useCanvasIngestion.js +13 -15
  310. package/dist/domains/ingestion/useCanvasIngestion.js.map +1 -0
  311. package/dist/{features → domains}/ingestion/weaselJsonHandler.js +1 -1
  312. package/dist/domains/ingestion/weaselJsonHandler.js.map +1 -0
  313. package/dist/{features → domains}/longPress/longPressFeedback.js +1 -1
  314. package/dist/domains/longPress/longPressFeedback.js.map +1 -0
  315. package/dist/{features → domains}/measure/actionIds.js +1 -1
  316. package/dist/domains/measure/actionIds.js.map +1 -0
  317. package/dist/{features → domains}/measure/measureCommands.js +1 -1
  318. package/dist/domains/measure/measureCommands.js.map +1 -0
  319. package/dist/{features → domains}/measure/measureContribution.js +1 -1
  320. package/dist/domains/measure/measureContribution.js.map +1 -0
  321. package/dist/{features → domains}/measure/measureEdits.js +1 -1
  322. package/dist/domains/measure/measureEdits.js.map +1 -0
  323. package/dist/{features → domains}/measure/measureGestures.js +4 -7
  324. package/dist/domains/measure/measureGestures.js.map +1 -0
  325. package/dist/{features → domains}/measure/measureHit.js +1 -1
  326. package/dist/domains/measure/measureHit.js.map +1 -0
  327. package/dist/{features → domains}/measure/measureLayer.js +1 -1
  328. package/dist/domains/measure/measureLayer.js.map +1 -0
  329. package/dist/{features → domains}/measure/measurement.js +1 -1
  330. package/dist/domains/measure/measurement.js.map +1 -0
  331. package/dist/{features → domains}/measure/measurements.js +2 -2
  332. package/dist/domains/measure/measurements.js.map +1 -0
  333. package/dist/{features → domains}/modes/modeLayers.js +1 -1
  334. package/dist/domains/modes/modeLayers.js.map +1 -0
  335. package/dist/{features → domains}/modes/modeTriggers.js +3 -6
  336. package/dist/domains/modes/modeTriggers.js.map +1 -0
  337. package/dist/{features → domains}/pathEffects/effectSources.js +1 -1
  338. package/dist/domains/pathEffects/effectSources.js.map +1 -0
  339. package/dist/{features → domains}/pathEffects/index.js +1 -1
  340. package/dist/domains/pathEffects/index.js.map +1 -0
  341. package/dist/{features → domains}/pathEffects/readSource.js +1 -1
  342. package/dist/domains/pathEffects/readSource.js.map +1 -0
  343. package/dist/{features → domains}/pathEffects/textItems.js +11 -2
  344. package/dist/domains/pathEffects/textItems.js.map +1 -0
  345. package/dist/{features → domains}/pathEffects/useEffectSourcesLayer.js +1 -1
  346. package/dist/domains/pathEffects/useEffectSourcesLayer.js.map +1 -0
  347. package/dist/{features → domains}/paths/anchorData.js +1 -1
  348. package/dist/domains/paths/anchorData.js.map +1 -0
  349. package/dist/{features → domains}/paths/anchorMarkers.js +9 -7
  350. package/dist/domains/paths/anchorMarkers.js.map +1 -0
  351. package/dist/{features → domains}/paths/editablePath.js +1 -1
  352. package/dist/domains/paths/editablePath.js.map +1 -0
  353. package/dist/{features → domains}/paths/index.js +3 -3
  354. package/dist/{features → domains}/paths/originProjection.js +1 -1
  355. package/dist/domains/paths/originProjection.js.map +1 -0
  356. package/dist/{features → domains}/paths/pathEditExtension.js +1 -1
  357. package/dist/domains/paths/pathEditExtension.js.map +1 -0
  358. package/dist/{features → domains}/paths/pathEditState.js +1 -1
  359. package/dist/domains/paths/pathEditState.js.map +1 -0
  360. package/dist/{features → domains}/paths/pathEditingOverlayLayer.js +1 -1
  361. package/dist/domains/paths/pathEditingOverlayLayer.js.map +1 -0
  362. package/dist/{features → domains}/paths/pathLayer.js +1 -1
  363. package/dist/domains/paths/pathLayer.js.map +1 -0
  364. package/dist/{features → domains}/paths/pathRepresentation.js +1 -1
  365. package/dist/domains/paths/pathRepresentation.js.map +1 -0
  366. package/dist/{features → domains}/paths/pathSnap/glyphs.js +1 -1
  367. package/dist/domains/paths/pathSnap/glyphs.js.map +1 -0
  368. package/dist/{features → domains}/paths/pathSnap/pathSnapSource.js +1 -1
  369. package/dist/domains/paths/pathSnap/pathSnapSource.js.map +1 -0
  370. package/dist/{features → domains}/paths/pathSnap/sceneIndex.js +1 -1
  371. package/dist/domains/paths/pathSnap/sceneIndex.js.map +1 -0
  372. package/dist/{features → domains}/paths/pathSnap/snapGeometry.js +3 -2
  373. package/dist/domains/paths/pathSnap/snapGeometry.js.map +1 -0
  374. package/dist/{features → domains}/paths/penPreviewLayer.js +1 -1
  375. package/dist/domains/paths/penPreviewLayer.js.map +1 -0
  376. package/dist/{features → domains}/paths/shapeGenerator.js +6 -4
  377. package/dist/domains/paths/shapeGenerator.js.map +1 -0
  378. package/dist/{features → domains}/paths/strokeOutline.js +1 -1
  379. package/dist/domains/paths/strokeOutline.js.map +1 -0
  380. package/dist/{features → domains}/paths/useAnchorFields.js +1 -1
  381. package/dist/domains/paths/useAnchorFields.js.map +1 -0
  382. package/dist/{features → domains}/paths/usePathEdit.js +1 -1
  383. package/dist/domains/paths/usePathEdit.js.map +1 -0
  384. package/dist/{features → domains}/poseRun/usePoseRun.js +1 -1
  385. package/dist/domains/poseRun/usePoseRun.js.map +1 -0
  386. package/dist/{features → domains}/selection/enteredGroupFrame.js +49 -10
  387. package/dist/domains/selection/enteredGroupFrame.js.map +1 -0
  388. package/dist/{features → domains}/selection/enteredGroupScope.js +1 -1
  389. package/dist/domains/selection/enteredGroupScope.js.map +1 -0
  390. package/dist/domains/selection/enteredOperands.js +29 -0
  391. package/dist/domains/selection/enteredOperands.js.map +1 -0
  392. package/dist/{features → domains}/selection/handleCommands.js +1 -1
  393. package/dist/domains/selection/handleCommands.js.map +1 -0
  394. package/dist/{features → domains}/selection/overlay.js +1 -1
  395. package/dist/domains/selection/overlay.js.map +1 -0
  396. package/dist/{features → domains}/selection/selectionPose.js +1 -1
  397. package/dist/domains/selection/selectionPose.js.map +1 -0
  398. package/dist/{features → domains}/snap/angle2d.js +1 -1
  399. package/dist/domains/snap/angle2d.js.map +1 -0
  400. package/dist/{features → domains}/snap/debugCandidates.js +1 -1
  401. package/dist/domains/snap/debugCandidates.js.map +1 -0
  402. package/dist/{features → domains}/snap/gather.js +1 -1
  403. package/dist/domains/snap/gather.js.map +1 -0
  404. package/dist/{features → domains}/snap/inputSubspace.js +1 -1
  405. package/dist/domains/snap/inputSubspace.js.map +1 -0
  406. package/dist/{features → domains}/snap/lazySession.js +1 -1
  407. package/dist/domains/snap/lazySession.js.map +1 -0
  408. package/dist/{features → domains}/snap/marks.js +1 -1
  409. package/dist/domains/snap/marks.js.map +1 -0
  410. package/dist/{features → domains}/snap/outcomeStore.js +1 -1
  411. package/dist/domains/snap/outcomeStore.js.map +1 -0
  412. package/dist/{features → domains}/snap/pointSnap.js +1 -1
  413. package/dist/domains/snap/pointSnap.js.map +1 -0
  414. package/dist/{features → domains}/snap/probes2d.js +1 -1
  415. package/dist/domains/snap/probes2d.js.map +1 -0
  416. package/dist/{features → domains}/snap/readoutDraw.js +1 -1
  417. package/dist/domains/snap/readoutDraw.js.map +1 -0
  418. package/dist/{features → domains}/snap/readoutLayer.js +1 -1
  419. package/dist/domains/snap/readoutLayer.js.map +1 -0
  420. package/dist/{features → domains}/snap/registry.js +1 -1
  421. package/dist/domains/snap/registry.js.map +1 -0
  422. package/dist/{features → domains}/snap/resizeBox.js +1 -1
  423. package/dist/domains/snap/resizeBox.js.map +1 -0
  424. package/dist/{features → domains}/snap/roles.js +1 -1
  425. package/dist/domains/snap/roles.js.map +1 -0
  426. package/dist/{features → domains}/snap/rotationSource.js +1 -1
  427. package/dist/domains/snap/rotationSource.js.map +1 -0
  428. package/dist/{features → domains}/snap/sceneReads.js +24 -3
  429. package/dist/domains/snap/sceneReads.js.map +1 -0
  430. package/dist/{features → domains}/snap/sceneSession2d.js +3 -2
  431. package/dist/domains/snap/sceneSession2d.js.map +1 -0
  432. package/dist/{features → domains}/snap/screen.js +1 -1
  433. package/dist/domains/snap/screen.js.map +1 -0
  434. package/dist/{features → domains}/snap/session2d.js +3 -2
  435. package/dist/domains/snap/session2d.js.map +1 -0
  436. package/dist/{features → domains}/snap/spanSnap.js +1 -1
  437. package/dist/domains/snap/spanSnap.js.map +1 -0
  438. package/dist/{features → domains}/snap/stepAngles.js +1 -1
  439. package/dist/domains/snap/stepAngles.js.map +1 -0
  440. package/dist/{features → domains}/text/editingDrawOne.js +4 -4
  441. package/dist/domains/text/editingDrawOne.js.map +1 -0
  442. package/dist/domains/text/hostTextEditors.js +24 -0
  443. package/dist/domains/text/hostTextEditors.js.map +1 -0
  444. package/dist/{features → domains}/text/index.js +1 -1
  445. package/dist/{features → domains}/text/sceneTextDrafts.js +1 -1
  446. package/dist/domains/text/sceneTextDrafts.js.map +1 -0
  447. package/dist/{features → domains}/text/textHitAt.js +18 -2
  448. package/dist/domains/text/textHitAt.js.map +1 -0
  449. package/dist/{features → domains}/text/textLayer.js +1 -1
  450. package/dist/domains/text/textLayer.js.map +1 -0
  451. package/dist/{features → domains}/text/useSceneTextEdit.js +11 -3
  452. package/dist/domains/text/useSceneTextEdit.js.map +1 -0
  453. package/dist/{features → domains}/viewports/aim.js +1 -1
  454. package/dist/domains/viewports/aim.js.map +1 -0
  455. package/dist/{features → domains}/viewports/viewMarker.js +23 -5
  456. package/dist/domains/viewports/viewMarker.js.map +1 -0
  457. package/dist/{features → domains}/viewports/viewMarkerDrag.js +3 -3
  458. package/dist/domains/viewports/viewMarkerDrag.js.map +1 -0
  459. package/dist/{features → domains}/viewports/viewResolver.js +1 -1
  460. package/dist/domains/viewports/viewResolver.js.map +1 -0
  461. package/dist/{features → domains}/viewports/viewportLayer.js +1 -1
  462. package/dist/domains/viewports/viewportLayer.js.map +1 -0
  463. package/dist/icons.table.js +1 -1
  464. package/dist/icons.table.js.map +1 -1
  465. package/dist/icons.table.json +106 -6
  466. package/dist/index.d.ts +1441 -1050
  467. package/dist/index.js +90 -77
  468. package/dist/interactions/actions/admitsChild.js +6 -2
  469. package/dist/interactions/actions/admitsChild.js.map +1 -1
  470. package/dist/interactions/actions/align/align.js +1 -4
  471. package/dist/interactions/actions/align/align.js.map +1 -1
  472. package/dist/interactions/actions/booleans/booleanGroupAction.js +66 -0
  473. package/dist/interactions/actions/booleans/booleanGroupAction.js.map +1 -0
  474. package/dist/interactions/actions/booleans/keymap.js +52 -0
  475. package/dist/interactions/actions/booleans/keymap.js.map +1 -0
  476. package/dist/interactions/actions/booleans/operands.js +1 -1
  477. package/dist/interactions/actions/booleans/pieces.js +4 -11
  478. package/dist/interactions/actions/booleans/pieces.js.map +1 -1
  479. package/dist/interactions/actions/clipboard/action.js +3 -7
  480. package/dist/interactions/actions/clipboard/action.js.map +1 -1
  481. package/dist/interactions/actions/clipboard/clipboardOps.js +1 -1
  482. package/dist/interactions/actions/clipboard/clipboardOps.js.map +1 -1
  483. package/dist/interactions/actions/clipboard/materializePaste.js.map +1 -1
  484. package/dist/interactions/actions/defaults/anchorEditing.js +6 -6
  485. package/dist/interactions/actions/defaults/anchorEditing.js.map +1 -1
  486. package/dist/interactions/actions/defaults/bendSegment.js +1 -1
  487. package/dist/interactions/actions/defaults/bendSegment.js.map +1 -1
  488. package/dist/interactions/actions/defaults/containerScroll.js +170 -0
  489. package/dist/interactions/actions/defaults/containerScroll.js.map +1 -0
  490. package/dist/interactions/actions/defaults/contextMenu.js +2 -5
  491. package/dist/interactions/actions/defaults/contextMenu.js.map +1 -1
  492. package/dist/interactions/actions/defaults/delete.js +1 -1
  493. package/dist/interactions/actions/defaults/delete.js.map +1 -1
  494. package/dist/interactions/actions/defaults/duplicate.js +1 -3
  495. package/dist/interactions/actions/defaults/duplicate.js.map +1 -1
  496. package/dist/interactions/actions/defaults/enterGroup.js +7 -12
  497. package/dist/interactions/actions/defaults/enterGroup.js.map +1 -1
  498. package/dist/interactions/actions/defaults/enterPathEdit.js +4 -8
  499. package/dist/interactions/actions/defaults/enterPathEdit.js.map +1 -1
  500. package/dist/interactions/actions/defaults/group.js +12 -24
  501. package/dist/interactions/actions/defaults/group.js.map +1 -1
  502. package/dist/interactions/actions/defaults/ingest.js +18 -10
  503. package/dist/interactions/actions/defaults/ingest.js.map +1 -1
  504. package/dist/interactions/actions/defaults/insertPathAnchor.js +3 -3
  505. package/dist/interactions/actions/defaults/insertPathAnchor.js.map +1 -1
  506. package/dist/interactions/actions/defaults/nudgeSteps.js +3 -21
  507. package/dist/interactions/actions/defaults/nudgeSteps.js.map +1 -1
  508. package/dist/interactions/actions/defaults/pathEditMarks.js.map +1 -1
  509. package/dist/interactions/actions/defaults/selectDeep.js +2 -2
  510. package/dist/interactions/actions/defaults/selectDeep.js.map +1 -1
  511. package/dist/interactions/actions/distribute/distribute.js.map +1 -1
  512. package/dist/interactions/actions/dropVerdict.js +9 -0
  513. package/dist/interactions/actions/dropVerdict.js.map +1 -0
  514. package/dist/interactions/actions/edit-anchors/action.js +2 -2
  515. package/dist/interactions/actions/edit-anchors/action.js.map +1 -1
  516. package/dist/interactions/actions/edit-anchors/extensionDrags.js.map +1 -1
  517. package/dist/interactions/actions/edit-anchors/geometry.js +8 -6
  518. package/dist/interactions/actions/edit-anchors/geometry.js.map +1 -1
  519. package/dist/interactions/actions/edit-anchors/handleDrag.js.map +1 -1
  520. package/dist/interactions/actions/edit-anchors/preview.js +1 -1
  521. package/dist/interactions/actions/edit-anchors/preview.js.map +1 -1
  522. package/dist/interactions/actions/flip/action.js +3 -2
  523. package/dist/interactions/actions/flip/action.js.map +1 -1
  524. package/dist/interactions/actions/geometryProjection.js +8 -3
  525. package/dist/interactions/actions/geometryProjection.js.map +1 -1
  526. package/dist/interactions/actions/gestureFrames.js +1 -0
  527. package/dist/interactions/actions/gestureFrames.js.map +1 -1
  528. package/dist/interactions/actions/insert/action.js +6 -2
  529. package/dist/interactions/actions/insert/action.js.map +1 -1
  530. package/dist/interactions/actions/insert/frame.js +1 -1
  531. package/dist/interactions/actions/insert/frame.js.map +1 -1
  532. package/dist/interactions/actions/insert/placeAction.js +6 -8
  533. package/dist/interactions/actions/insert/placeAction.js.map +1 -1
  534. package/dist/interactions/actions/insert/session.js +2 -2
  535. package/dist/interactions/actions/insert/session.js.map +1 -1
  536. package/dist/interactions/actions/move/action.js +6 -15
  537. package/dist/interactions/actions/move/action.js.map +1 -1
  538. package/dist/interactions/actions/move/behaviors/layoutDrop.js +12 -2
  539. package/dist/interactions/actions/move/behaviors/layoutDrop.js.map +1 -1
  540. package/dist/interactions/actions/move/behaviors/reparentOnDrop.js +29 -10
  541. package/dist/interactions/actions/move/behaviors/reparentOnDrop.js.map +1 -1
  542. package/dist/interactions/actions/move/behaviors/snapToContainer.js +42 -6
  543. package/dist/interactions/actions/move/behaviors/snapToContainer.js.map +1 -1
  544. package/dist/interactions/actions/move/capture.js +4 -8
  545. package/dist/interactions/actions/move/capture.js.map +1 -1
  546. package/dist/interactions/actions/move/commit/index.js.map +1 -1
  547. package/dist/interactions/actions/move/commit/layoutDrop.js +4 -3
  548. package/dist/interactions/actions/move/commit/layoutDrop.js.map +1 -1
  549. package/dist/interactions/actions/move/commit/layoutRelease.js +15 -9
  550. package/dist/interactions/actions/move/commit/layoutRelease.js.map +1 -1
  551. package/dist/interactions/actions/move/commit/reparent.js +19 -13
  552. package/dist/interactions/actions/move/commit/reparent.js.map +1 -1
  553. package/dist/interactions/actions/move/delta.js +51 -5
  554. package/dist/interactions/actions/move/delta.js.map +1 -1
  555. package/dist/interactions/actions/move/frame.js +8 -4
  556. package/dist/interactions/actions/move/frame.js.map +1 -1
  557. package/dist/interactions/actions/move/layout/container.js +19 -9
  558. package/dist/interactions/actions/move/layout/container.js.map +1 -1
  559. package/dist/interactions/actions/move/layout/dragged.js +2 -2
  560. package/dist/interactions/actions/move/layout/dragged.js.map +1 -1
  561. package/dist/interactions/actions/move/layout/dropPass.js +36 -18
  562. package/dist/interactions/actions/move/layout/dropPass.js.map +1 -1
  563. package/dist/interactions/actions/move/layout/exits.js +2 -2
  564. package/dist/interactions/actions/move/layout/exits.js.map +1 -1
  565. package/dist/interactions/actions/move/layout/glide.js +5 -5
  566. package/dist/interactions/actions/move/layout/glide.js.map +1 -1
  567. package/dist/interactions/actions/move/layout/view.js +55 -0
  568. package/dist/interactions/actions/move/layout/view.js.map +1 -0
  569. package/dist/interactions/actions/move/refusal.js +52 -0
  570. package/dist/interactions/actions/move/refusal.js.map +1 -0
  571. package/dist/interactions/actions/move/session.js +9 -8
  572. package/dist/interactions/actions/move/session.js.map +1 -1
  573. package/dist/interactions/actions/move/translate.js +10 -4
  574. package/dist/interactions/actions/move/translate.js.map +1 -1
  575. package/dist/interactions/actions/moveNodes.js +21 -5
  576. package/dist/interactions/actions/moveNodes.js.map +1 -1
  577. package/dist/interactions/actions/pathCommands/pathNodes.js +3 -3
  578. package/dist/interactions/actions/pathCommands/pathNodes.js.map +1 -1
  579. package/dist/interactions/actions/planeInput.js +14 -13
  580. package/dist/interactions/actions/planeInput.js.map +1 -1
  581. package/dist/interactions/actions/poseFrame.js +21 -8
  582. package/dist/interactions/actions/poseFrame.js.map +1 -1
  583. package/dist/interactions/actions/resize/action.js +1 -1
  584. package/dist/interactions/actions/resize/action.js.map +1 -1
  585. package/dist/interactions/actions/resize/aspect.js +1 -1
  586. package/dist/interactions/actions/resize/aspect.js.map +1 -1
  587. package/dist/interactions/actions/resize/commit.js +10 -1
  588. package/dist/interactions/actions/resize/commit.js.map +1 -1
  589. package/dist/interactions/actions/resize/frame.js +3 -2
  590. package/dist/interactions/actions/resize/frame.js.map +1 -1
  591. package/dist/interactions/actions/resize/held.js +44 -0
  592. package/dist/interactions/actions/resize/held.js.map +1 -0
  593. package/dist/interactions/actions/resize/session.js +3 -1
  594. package/dist/interactions/actions/resize/session.js.map +1 -1
  595. package/dist/interactions/actions/resolveOverlays.js +9 -0
  596. package/dist/interactions/actions/resolveOverlays.js.map +1 -1
  597. package/dist/interactions/actions/resolvePreviews.js +23 -7
  598. package/dist/interactions/actions/resolvePreviews.js.map +1 -1
  599. package/dist/interactions/actions/rotate/action.js +1 -1
  600. package/dist/interactions/actions/rotate/action.js.map +1 -1
  601. package/dist/interactions/actions/rotate/frame.js +1 -1
  602. package/dist/interactions/actions/rotate/frame.js.map +1 -1
  603. package/dist/interactions/actions/rotate/session.js +2 -2
  604. package/dist/interactions/actions/rotate/session.js.map +1 -1
  605. package/dist/interactions/actions/selectionSubtree.js +2 -4
  606. package/dist/interactions/actions/selectionSubtree.js.map +1 -1
  607. package/dist/interactions/actions/spatialReference.js +4 -9
  608. package/dist/interactions/actions/spatialReference.js.map +1 -1
  609. package/dist/interactions/gestures/dragRadial/dragRadial.js.map +1 -1
  610. package/dist/interactions/gestures/dragRect/dragRect.js.map +1 -1
  611. package/dist/kitSettingsSchema.js +2 -2
  612. package/dist/kitSettingsSchema.js.map +1 -1
  613. package/dist/{math-C_elShP_.d.ts → math-B_unOnF4.d.ts} +2 -2
  614. package/dist/math.d.ts +3 -3
  615. package/dist/move.d.ts +6 -6
  616. package/dist/{options-ClEm3SEl.d.ts → options-DAjkhbcs.d.ts} +5 -5
  617. package/dist/{poseDescriptor-DN2yfnq_.d.ts → poseDescriptor-CvSxVhCd.d.ts} +17 -4
  618. package/dist/resize.d.ts +6 -6
  619. package/dist/style.css +14 -0
  620. package/dist/test-seams.d.ts +11 -15
  621. package/dist/test-seams.js +1 -1
  622. package/dist/tools/builtin/eyedropper/useEyedropperTool.js +3 -6
  623. package/dist/tools/builtin/eyedropper/useEyedropperTool.js.map +1 -1
  624. package/dist/tools/builtin/line/useLineTool.js.map +1 -1
  625. package/dist/tools/builtin/measure/useMeasureTool.js +2 -2
  626. package/dist/tools/builtin/measure/useMeasureTool.js.map +1 -1
  627. package/dist/tools/builtin/pen/penHandle.js +2 -2
  628. package/dist/tools/builtin/pen/penHandle.js.map +1 -1
  629. package/dist/tools/builtin/pen/usePenTool.js +13 -19
  630. package/dist/tools/builtin/pen/usePenTool.js.map +1 -1
  631. package/dist/tools/builtin/polygon/usePolygonTool.js +1 -1
  632. package/dist/tools/builtin/polygon/usePolygonTool.js.map +1 -1
  633. package/dist/tools/builtin/select/groupEntry.js +1 -1
  634. package/dist/tools/builtin/select/groupEntry.js.map +1 -1
  635. package/dist/tools/builtin/select/selectionContributions.js +1 -1
  636. package/dist/tools/builtin/select/selectionContributions.js.map +1 -1
  637. package/dist/tools/builtin/select/useSelectTool.js +7 -7
  638. package/dist/tools/builtin/select/useSelectTool.js.map +1 -1
  639. package/dist/tools/builtin/slice/useSliceTool.js +5 -8
  640. package/dist/tools/builtin/slice/useSliceTool.js.map +1 -1
  641. package/dist/tools/builtin/star/useStarTool.js +1 -1
  642. package/dist/tools/builtin/star/useStarTool.js.map +1 -1
  643. package/dist/tools/index.js +2 -1
  644. package/dist/{types-49uYJN3j.d.ts → types-A_sNJYRd.d.ts} +8 -0
  645. package/dist/{types-BEdRIhNc.d.ts → types-DW14eu9B.d.ts} +131 -36
  646. package/dist/{types-p2alu-R1.d.ts → types-VCtfchp-.d.ts} +4 -6
  647. package/dist/util/color.js +12 -14
  648. package/dist/util/color.js.map +1 -1
  649. package/dist/version.js +1 -1
  650. package/package.json +25 -24
  651. package/dist/canvas/poseCascade.js +0 -65
  652. package/dist/canvas/poseCascade.js.map +0 -1
  653. package/dist/features/chrome-caps/buildChromeCtx.js.map +0 -1
  654. package/dist/features/chrome-caps/conditions.js.map +0 -1
  655. package/dist/features/chrome-caps/defaults.js.map +0 -1
  656. package/dist/features/chrome-caps/resolve.js.map +0 -1
  657. package/dist/features/chrome-caps/useChromeCaps.js.map +0 -1
  658. package/dist/features/chrome-caps/useHoverTracking.js.map +0 -1
  659. package/dist/features/ingestion/contentHandlers.js.map +0 -1
  660. package/dist/features/ingestion/imageHandler.js.map +0 -1
  661. package/dist/features/ingestion/openFilePicker.js.map +0 -1
  662. package/dist/features/ingestion/placement.js.map +0 -1
  663. package/dist/features/ingestion/registerKitHandlers.js +0 -43
  664. package/dist/features/ingestion/registerKitHandlers.js.map +0 -1
  665. package/dist/features/ingestion/svgHandler.js.map +0 -1
  666. package/dist/features/ingestion/textHandler.js.map +0 -1
  667. package/dist/features/ingestion/useCanvasIngestion.js.map +0 -1
  668. package/dist/features/ingestion/weaselJsonHandler.js.map +0 -1
  669. package/dist/features/longPress/longPressFeedback.js.map +0 -1
  670. package/dist/features/measure/actionIds.js.map +0 -1
  671. package/dist/features/measure/measureCommands.js.map +0 -1
  672. package/dist/features/measure/measureContribution.js.map +0 -1
  673. package/dist/features/measure/measureEdits.js.map +0 -1
  674. package/dist/features/measure/measureGestures.js.map +0 -1
  675. package/dist/features/measure/measureHit.js.map +0 -1
  676. package/dist/features/measure/measureLayer.js.map +0 -1
  677. package/dist/features/measure/measurement.js.map +0 -1
  678. package/dist/features/measure/measurements.js.map +0 -1
  679. package/dist/features/modes/modeLayers.js.map +0 -1
  680. package/dist/features/modes/modeTriggers.js.map +0 -1
  681. package/dist/features/pathEffects/effectSources.js.map +0 -1
  682. package/dist/features/pathEffects/index.js.map +0 -1
  683. package/dist/features/pathEffects/readSource.js.map +0 -1
  684. package/dist/features/pathEffects/textItems.js.map +0 -1
  685. package/dist/features/pathEffects/useEffectSourcesLayer.js.map +0 -1
  686. package/dist/features/paths/anchorData.js.map +0 -1
  687. package/dist/features/paths/anchorMarkers.js.map +0 -1
  688. package/dist/features/paths/editablePath.js.map +0 -1
  689. package/dist/features/paths/originProjection.js.map +0 -1
  690. package/dist/features/paths/pathEditExtension.js.map +0 -1
  691. package/dist/features/paths/pathEditState.js.map +0 -1
  692. package/dist/features/paths/pathEditingOverlayLayer.js.map +0 -1
  693. package/dist/features/paths/pathLayer.js.map +0 -1
  694. package/dist/features/paths/pathRepresentation.js.map +0 -1
  695. package/dist/features/paths/pathSnap/glyphs.js.map +0 -1
  696. package/dist/features/paths/pathSnap/pathSnapSource.js.map +0 -1
  697. package/dist/features/paths/pathSnap/sceneIndex.js.map +0 -1
  698. package/dist/features/paths/pathSnap/snapGeometry.js.map +0 -1
  699. package/dist/features/paths/penPreviewLayer.js.map +0 -1
  700. package/dist/features/paths/shapeGenerator.js.map +0 -1
  701. package/dist/features/paths/strokeOutline.js.map +0 -1
  702. package/dist/features/paths/useAnchorFields.js.map +0 -1
  703. package/dist/features/paths/usePathEdit.js.map +0 -1
  704. package/dist/features/poseRun/usePoseRun.js.map +0 -1
  705. package/dist/features/selection/enteredGroupFrame.js.map +0 -1
  706. package/dist/features/selection/enteredGroupScope.js.map +0 -1
  707. package/dist/features/selection/handleCommands.js.map +0 -1
  708. package/dist/features/selection/overlay.js.map +0 -1
  709. package/dist/features/selection/selectionPose.js.map +0 -1
  710. package/dist/features/snap/angle2d.js.map +0 -1
  711. package/dist/features/snap/debugCandidates.js.map +0 -1
  712. package/dist/features/snap/gather.js.map +0 -1
  713. package/dist/features/snap/inputSubspace.js.map +0 -1
  714. package/dist/features/snap/lazySession.js.map +0 -1
  715. package/dist/features/snap/marks.js.map +0 -1
  716. package/dist/features/snap/outcomeStore.js.map +0 -1
  717. package/dist/features/snap/pointSnap.js.map +0 -1
  718. package/dist/features/snap/probes2d.js.map +0 -1
  719. package/dist/features/snap/readoutDraw.js.map +0 -1
  720. package/dist/features/snap/readoutLayer.js.map +0 -1
  721. package/dist/features/snap/registry.js.map +0 -1
  722. package/dist/features/snap/resizeBox.js.map +0 -1
  723. package/dist/features/snap/roles.js.map +0 -1
  724. package/dist/features/snap/rotationSource.js.map +0 -1
  725. package/dist/features/snap/sceneReads.js.map +0 -1
  726. package/dist/features/snap/sceneSession2d.js.map +0 -1
  727. package/dist/features/snap/screen.js.map +0 -1
  728. package/dist/features/snap/session2d.js.map +0 -1
  729. package/dist/features/snap/spanSnap.js.map +0 -1
  730. package/dist/features/snap/stepAngles.js.map +0 -1
  731. package/dist/features/text/editingDrawOne.js.map +0 -1
  732. package/dist/features/text/sceneTextDrafts.js.map +0 -1
  733. package/dist/features/text/textHitAt.js.map +0 -1
  734. package/dist/features/text/textLayer.js.map +0 -1
  735. package/dist/features/text/useSceneTextEdit.js.map +0 -1
  736. package/dist/features/viewports/aim.js.map +0 -1
  737. package/dist/features/viewports/viewMarker.js.map +0 -1
  738. package/dist/features/viewports/viewMarkerDrag.js.map +0 -1
  739. package/dist/features/viewports/viewResolver.js.map +0 -1
  740. package/dist/features/viewports/viewportLayer.js.map +0 -1
  741. /package/dist/{features → domains}/chrome-caps/index.js +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"align.js","names":[],"sources":["../../../../src/interactions/actions/align/align.ts"],"sourcesContent":["import { useCallback } from 'react';\nimport { useLatest } from '@weasel-js/react';\nimport { createTransformOp } from 'core/ops/transform';\nimport type { Op } from 'core/ops/types';\nimport { dispatchApplyBatch } from 'core/applyOps';\nimport type { NodeId } from 'core/scene/types';\nimport { RECT_POSE_DESCRIPTOR, type PoseDescriptor } from '../resize/geometry';\nimport type { Bounds } from 'core/viewport/fitViewToBounds';\nimport { unionAABB } from 'core/geometry/unionBounds';\nimport { poseFrame } from '../poseFrame';\nimport { IDENTITY_POSE_COMPOSITION, type PoseComposition } from 'core/scene/composePose';\nimport { usePointerContext } from '@weasel-js/routing/react';\nimport type { Scale2 } from '@weasel-js/geom';\nimport { drawnAABBOf, type DrawnBoundsOptions, type DrawnBoundsScene } from 'canvas/drawnBounds';\nimport { resolveSpatialReference, type SpatialReference, type SpatialReferenceSources } from '../spatialReference';\n\nexport { visualBoundsViaDescriptor, translatePoseViaDescriptor } from '../resize/geometry';\nimport { visualBoundsViaDescriptor, translatePoseViaDescriptor } from '../resize/geometry';\n\n/** Edge or center the selection should align to within the reference's\n * bounds (rotated members contribute their ink extent). */\nexport type AlignEdge = 'left' | 'right' | 'top' | 'bottom' | 'center-x' | 'center-y';\n\n/** What the selection aligns to: `'union'` — the selection's\n * own visual union AABB, the default — or a {@link SpatialReference}. */\nexport type AlignReference = 'union' | SpatialReference;\n\n/** The bounds each member of `bounds` aligns to under `to`, or\n * `null` when there is nothing to align: a union of fewer than two members,\n * an empty selection, or a reference that names nothing right now. */\nexport function alignTargetBounds(\n bounds: readonly Bounds[],\n to: AlignReference | undefined,\n src: SpatialReferenceSources,\n): Bounds | null {\n if (to === undefined || to === 'union') return bounds.length < 2 ? null : unionAABB([...bounds]);\n if (bounds.length === 0) return null;\n return resolveSpatialReference(to, src);\n}\n\n/** Adapter for `useAlign`. */\nexport interface AlignAdapter<TPose> {\n getSelection(): NodeId[];\n /** The pose as stored — local to the node's parent. */\n getPose(id: NodeId): TPose;\n /** The node's container, `null` for a root: the chain a pose is composed\n * through when container poses define a frame. */\n getParent(id: NodeId): NodeId | null;\n applyOps?(ops: Op[], label?: string): void;\n}\n\n/** Options for `useAlign`. */\nexport interface UseAlignOptions<TPose> {\n /** Projection between `TPose` and bounds. Defaults to `RECT_POSE_DESCRIPTOR`\n * for `{x,y,width,height}` poses. Pass `pathPoseDescriptor` for `Path`\n * poses so polygon coords translate correctly. */\n geometry?: PoseDescriptor<TPose>;\n /** Label passed to applyOps. Default 'Align'. */\n label?: string;\n /** How local poses fold up to world. Default IDENTITY, where the two are\n * the same value and the alignment runs entirely in stored coordinates. */\n composition?: PoseComposition<TPose>;\n /** The nodes behind the adapter's ids. With it, a stroked node aligns by\n * the box it is drawn with (`drawnBoundsOf`); without, by its pose box.\n * Pass a `Scene` through `drawnBoundsScene` so a path-derived node is\n * boxed by its path. */\n scene?: DrawnBoundsScene;\n /** View scale a screen-pixel stroke is resolved at. Default 1. */\n viewScale?: () => number | Scale2;\n}\n\n/** Return shape of `useAlign`. */\nexport interface UseAlignReturn {\n /** Imperative trigger. `to` defaults to `'union'`, which needs two items;\n * any other reference aligns a single item too. `'pointer'` reads the\n * surrounding `<PointerContextProvider>`. */\n align(edge: AlignEdge, to?: AlignReference): void;\n}\n\n/** Compute the (dx, dy) translation that moves AABB `b` so that the requested\n * `edge`/center matches the corresponding feature of the union AABB `u`. */\nexport function alignDeltaFor(b: Bounds, u: Bounds, edge: AlignEdge): { dx: number; dy: number } {\n switch (edge) {\n case 'left': return { dx: u.x - b.x, dy: 0 };\n case 'right': return { dx: (u.x + u.width) - (b.x + b.width), dy: 0 };\n case 'top': return { dx: 0, dy: u.y - b.y };\n case 'bottom': return { dx: 0, dy: (u.y + u.height) - (b.y + b.height) };\n case 'center-x': return { dx: (u.x + u.width / 2) - (b.x + b.width / 2), dy: 0 };\n case 'center-y': return { dx: 0, dy: (u.y + u.height / 2) - (b.y + b.height / 2) };\n }\n}\n\n/** The axis-aligned box `useAlign` measures an id at a world pose by. */\nfunction alignBoxReader<TPose>(\n o: UseAlignOptions<TPose>,\n geom: PoseDescriptor<TPose>,\n worldPoseOf: (id: NodeId) => TPose,\n): (id: string, pose: TPose) => Bounds {\n const scene = o.scene;\n if (!scene) return (_id, pose) => visualBoundsViaDescriptor(pose, geom);\n const scale = o.viewScale?.();\n const opts: DrawnBoundsOptions = {\n descriptor: geom as PoseDescriptor<unknown>,\n worldPoseOf: (id) => worldPoseOf(id),\n ...(scale !== undefined ? { scale } : {}),\n };\n return (id, pose) => drawnAABBOf(scene, id as NodeId, pose, opts);\n}\n\n/** Align the current selection to a shared edge or center of the selection's\n * union AABB, or of another reference. Single batch — one undo step.\n *\n * The edge is a world edge: bounds are measured and translated in world, and\n * each result is stored back in its own parent's frame. */\nexport function useAlign<TPose>(\n adapter: AlignAdapter<TPose>,\n options: UseAlignOptions<TPose> = {},\n): UseAlignReturn {\n const adapterRef = useLatest(adapter);\n const optsRef = useLatest(options);\n const pointer = usePointerContext();\n const pointerRef = useLatest(pointer);\n\n const align = useCallback((edge: AlignEdge, to?: AlignReference): void => {\n const a = adapterRef.current;\n const o = optsRef.current;\n const sel = a.getSelection();\n const geom =\n o.geometry ??\n (RECT_POSE_DESCRIPTOR as unknown as PoseDescriptor<TPose>);\n const frame = poseFrame<TPose>(\n {\n getPose: (id) => a.getPose(id as NodeId),\n getParent: (id) => a.getParent(id as NodeId) as string | null,\n },\n o.composition ?? (IDENTITY_POSE_COMPOSITION as PoseComposition<TPose>),\n );\n const boxOf = alignBoxReader(o, geom, frame.world);\n const poses = sel.map((id) => frame.world(id));\n const bounds = poses.map((p, i) => boxOf(sel[i]!, p));\n const target = alignTargetBounds(bounds, to, {\n pointer: () => {\n const p = pointerRef.current?.get();\n return p ? { x: p.worldX, y: p.worldY } : null;\n },\n nodeBounds: (id) => boxOf(id, frame.world(id)),\n });\n if (target === null) return;\n const ops: Op[] = [];\n for (let i = 0; i < sel.length; i++) {\n const { dx, dy } = alignDeltaFor(bounds[i], target, edge);\n if (dx === 0 && dy === 0) continue;\n const to = translatePoseViaDescriptor(poses[i], dx, dy, geom);\n ops.push(createTransformOp<TPose>({\n id: sel[i],\n from: a.getPose(sel[i]),\n to: frame.local(sel[i], to),\n }));\n }\n if (ops.length === 0) return;\n dispatchApplyBatch(a, ops, o.label ?? 'Align');\n }, [adapterRef, optsRef, pointerRef]);\n\n return { align };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"align.js","names":[],"sources":["../../../../src/interactions/actions/align/align.ts"],"sourcesContent":["import { useCallback } from 'react';\nimport { useLatest } from '@weasel-js/react';\nimport { createTransformOp } from 'core/ops/transform';\nimport type { Op } from 'core/ops/types';\nimport { dispatchApplyBatch } from 'core/applyOps';\nimport type { NodeId } from 'core/scene/types';\nimport { RECT_POSE_DESCRIPTOR, type PoseDescriptor } from '../resize/geometry';\nimport type { Bounds } from 'core/viewport/fitViewToBounds';\nimport { unionAABB } from 'core/geometry/unionBounds';\nimport { poseFrame } from '../poseFrame';\nimport { IDENTITY_POSE_COMPOSITION, type PoseComposition } from 'core/scene/composePose';\nimport { usePointerContext } from '@weasel-js/routing/react';\nimport type { Scale2 } from '@weasel-js/geom';\nimport { drawnAABBOf, type DrawnBoundsOptions, type DrawnBoundsScene } from 'canvas/drawnBounds';\nimport { resolveSpatialReference, type SpatialReference, type SpatialReferenceSources } from '../spatialReference';\n\nexport { visualBoundsViaDescriptor, translatePoseViaDescriptor } from '../resize/geometry';\nimport { visualBoundsViaDescriptor, translatePoseViaDescriptor } from '../resize/geometry';\n\n/** Edge or center the selection should align to within the reference's\n * bounds (rotated members contribute their ink extent). */\nexport type AlignEdge = 'left' | 'right' | 'top' | 'bottom' | 'center-x' | 'center-y';\n\n/** What the selection aligns to: `'union'` — the selection's\n * own visual union AABB, the default — or a {@link SpatialReference}. */\nexport type AlignReference = 'union' | SpatialReference;\n\n/** The bounds each member of `bounds` aligns to under `to`, or\n * `null` when there is nothing to align: a union of fewer than two members,\n * an empty selection, or a reference that names nothing right now. */\nexport function alignTargetBounds(\n bounds: readonly Bounds[],\n to: AlignReference | undefined,\n src: SpatialReferenceSources,\n): Bounds | null {\n if (to === undefined || to === 'union') return bounds.length < 2 ? null : unionAABB([...bounds]);\n if (bounds.length === 0) return null;\n return resolveSpatialReference(to, src);\n}\n\n/** Adapter for `useAlign`. */\nexport interface AlignAdapter<TPose> {\n getSelection(): NodeId[];\n /** The pose as stored — local to the node's parent. */\n getPose(id: NodeId): TPose;\n /** The node's container, `null` for a root: the chain a pose is composed\n * through when container poses define a frame. */\n getParent(id: NodeId): NodeId | null;\n applyOps?(ops: Op[], label?: string): void;\n}\n\n/** Options for `useAlign`. */\nexport interface UseAlignOptions<TPose> {\n /** Projection between `TPose` and bounds. Defaults to `RECT_POSE_DESCRIPTOR`\n * for `{x,y,width,height}` poses. Pass `pathPoseDescriptor` for `Path`\n * poses so polygon coords translate correctly. */\n geometry?: PoseDescriptor<TPose>;\n /** Label passed to applyOps. Default 'Align'. */\n label?: string;\n /** How local poses fold up to world. Default IDENTITY, which takes every\n * pose the adapter answers as world; over a scene's adapter, pass\n * `scene.composition`. */\n composition?: PoseComposition<TPose>;\n /** The nodes behind the adapter's ids. With it, a stroked node aligns by\n * the box it is drawn with (`drawnBoundsOf`); without, by its pose box.\n * Pass a `Scene` through `drawnBoundsScene` so a path-derived node is\n * boxed by its path. */\n scene?: DrawnBoundsScene;\n /** View scale a screen-pixel stroke is resolved at. Default 1. */\n viewScale?: () => number | Scale2;\n}\n\n/** Return shape of `useAlign`. */\nexport interface UseAlignReturn {\n /** Imperative trigger. `to` defaults to `'union'`, which needs two items;\n * any other reference aligns a single item too. `'pointer'` reads the\n * surrounding `<PointerContextProvider>`. */\n align(edge: AlignEdge, to?: AlignReference): void;\n}\n\n/** Compute the (dx, dy) translation that moves AABB `b` so that the requested\n * `edge`/center matches the corresponding feature of the union AABB `u`. */\nexport function alignDeltaFor(b: Bounds, u: Bounds, edge: AlignEdge): { dx: number; dy: number } {\n switch (edge) {\n case 'left': return { dx: u.x - b.x, dy: 0 };\n case 'right': return { dx: (u.x + u.width) - (b.x + b.width), dy: 0 };\n case 'top': return { dx: 0, dy: u.y - b.y };\n case 'bottom': return { dx: 0, dy: (u.y + u.height) - (b.y + b.height) };\n case 'center-x': return { dx: (u.x + u.width / 2) - (b.x + b.width / 2), dy: 0 };\n case 'center-y': return { dx: 0, dy: (u.y + u.height / 2) - (b.y + b.height / 2) };\n }\n}\n\n/** The axis-aligned box `useAlign` measures an id at a world pose by. */\nfunction alignBoxReader<TPose>(\n o: UseAlignOptions<TPose>,\n geom: PoseDescriptor<TPose>,\n worldPoseOf: (id: NodeId) => TPose,\n): (id: string, pose: TPose) => Bounds {\n const scene = o.scene;\n if (!scene) return (_id, pose) => visualBoundsViaDescriptor(pose, geom);\n const scale = o.viewScale?.();\n const opts: DrawnBoundsOptions = {\n descriptor: geom as PoseDescriptor<unknown>,\n worldPoseOf: (id) => worldPoseOf(id),\n ...(scale !== undefined ? { scale } : {}),\n };\n return (id, pose) => drawnAABBOf(scene, id as NodeId, pose, opts);\n}\n\n/** Align the current selection to a shared edge or center of the selection's\n * union AABB, or of another reference. Single batch — one undo step.\n *\n * The edge is a world edge: bounds are measured and translated in world, and\n * each result is stored back in its own parent's frame. */\nexport function useAlign<TPose>(\n adapter: AlignAdapter<TPose>,\n options: UseAlignOptions<TPose> = {},\n): UseAlignReturn {\n const adapterRef = useLatest(adapter);\n const optsRef = useLatest(options);\n const pointer = usePointerContext();\n const pointerRef = useLatest(pointer);\n\n const align = useCallback((edge: AlignEdge, to?: AlignReference): void => {\n const a = adapterRef.current;\n const o = optsRef.current;\n const sel = a.getSelection();\n const geom =\n o.geometry ??\n (RECT_POSE_DESCRIPTOR as unknown as PoseDescriptor<TPose>);\n const frame = poseFrame<TPose>(\n {\n getPose: (id) => a.getPose(id as NodeId),\n getParent: (id) => a.getParent(id as NodeId) as string | null,\n },\n o.composition ?? (IDENTITY_POSE_COMPOSITION as PoseComposition<TPose>),\n );\n const boxOf = alignBoxReader(o, geom, frame.world);\n const poses = sel.map((id) => frame.world(id));\n const bounds = poses.map((p, i) => boxOf(sel[i]!, p));\n const target = alignTargetBounds(bounds, to, {\n pointer: () => {\n const p = pointerRef.current?.get();\n return p ? p.world : null;\n },\n nodeBounds: (id) => boxOf(id, frame.world(id)),\n });\n if (target === null) return;\n const ops: Op[] = [];\n for (let i = 0; i < sel.length; i++) {\n const { dx, dy } = alignDeltaFor(bounds[i], target, edge);\n if (dx === 0 && dy === 0) continue;\n const to = translatePoseViaDescriptor(poses[i], dx, dy, geom);\n ops.push(createTransformOp<TPose>({\n id: sel[i],\n from: a.getPose(sel[i]),\n to: frame.local(sel[i], to),\n }));\n }\n if (ops.length === 0) return;\n dispatchApplyBatch(a, ops, o.label ?? 'Align');\n }, [adapterRef, optsRef, pointerRef]);\n\n return { align };\n}\n"],"mappings":"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"}
@@ -0,0 +1,66 @@
1
+ import { scenePoseFrame } from "../poseFrame.js";
2
+ import { booleanGroupFields } from "../../../core/scene/booleanGroup.js";
3
+ import { ActionDisabledReason } from "@weasel-js/routing";
4
+
5
+ //#region src/interactions/actions/booleans/booleanGroupAction.ts
6
+ var PAINT_KEYS = ["fill", "stroke"];
7
+ /**
8
+ * Put `ids` under a new boolean group of `op`, in the frontmost one's place, as
9
+ * one undo entry; nothing moves on screen. The group wears the frontmost
10
+ * operand's `fill` and `stroke`. Returns its id, or `null` when fewer than two
11
+ * of `ids` are nodes on one layer.
12
+ */
13
+ function makeBooleanGroup(scene, ids, op = "union") {
14
+ const order = new Map([...scene.renderOrder()].map((id, i) => [id, i]));
15
+ const nodes = ids.map((id) => scene.get(id)).filter((n) => n !== void 0).sort((a, b) => (order.get(a.id) ?? 0) - (order.get(b.id) ?? 0));
16
+ if (nodes.length < 2 || new Set(nodes.map((n) => n.layer)).size > 1) return null;
17
+ const front = nodes.at(-1);
18
+ const parent = new Set(nodes.map((n) => n.parent ?? null)).size === 1 ? front.parent ?? null : null;
19
+ const at = (parent === null ? scene.roots : scene.childrenOf(parent)).indexOf(front.id);
20
+ const own = front.data ?? {};
21
+ const data = {
22
+ boolean: op,
23
+ ...Object.fromEntries(PAINT_KEYS.filter((k) => k in own).map((k) => [k, own[k]]))
24
+ };
25
+ const frame = scenePoseFrame(scene);
26
+ let group = null;
27
+ scene.batch("Make Boolean Group", () => {
28
+ const worlds = new Map(nodes.map((n) => [n.id, frame.world(n.id)]));
29
+ group = scene.add({
30
+ ...booleanGroupFields(),
31
+ layer: front.layer,
32
+ pose: front.pose,
33
+ data,
34
+ parent,
35
+ ...at >= 0 ? { index: at + 1 } : {}
36
+ });
37
+ nodes.forEach((n, i) => {
38
+ scene.move(n.id, group, i);
39
+ scene.setPose(n.id, frame.localUnder(group, worlds.get(n.id)));
40
+ });
41
+ });
42
+ return group;
43
+ }
44
+ /** Put the selection under a new boolean group, a union until its operation is changed. */
45
+ var makeBooleanGroupAction = {
46
+ id: "pathfinder.booleanGroup",
47
+ label: "Make Boolean Group",
48
+ icon: /* @icon */ "core:booleanGroup",
49
+ group: "pathfinder",
50
+ eligible: { capability: "creates-shapes" },
51
+ requires: ["scene", "selection"],
52
+ invoker: {
53
+ timing: "immediate",
54
+ run: (deps) => {
55
+ const { scene, selection } = deps;
56
+ if (!scene || !selection) return;
57
+ const id = makeBooleanGroup(scene, selection.get());
58
+ if (id !== null) selection.set([id]);
59
+ }
60
+ },
61
+ enabled: (deps) => (deps?.selection?.get().length ?? 0) >= 2 ? true : ActionDisabledReason.SelectionRequired
62
+ };
63
+
64
+ //#endregion
65
+ export { makeBooleanGroup, makeBooleanGroupAction };
66
+ //# sourceMappingURL=booleanGroupAction.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"booleanGroupAction.js","names":[],"sources":["../../../../src/interactions/actions/booleans/booleanGroupAction.ts"],"sourcesContent":["import type { BooleanShapeOp } from 'core/geometry/booleanOfPaths';\nimport { booleanGroupFields } from 'core/scene/booleanGroup';\nimport type { Node, NodeId, Scene } from 'core/scene/types';\nimport { ActionDisabledReason, type Action } from '@weasel-js/routing';\nimport { scenePoseFrame } from '../poseFrame';\nimport { icon } from '../../../icons.gen';\n\ntype AnyScene = Scene<unknown, string, unknown>;\n\nconst PAINT_KEYS = ['fill', 'stroke'] as const;\n\n/**\n * Put `ids` under a new boolean group of `op`, in the frontmost one's place, as\n * one undo entry; nothing moves on screen. The group wears the frontmost\n * operand's `fill` and `stroke`. Returns its id, or `null` when fewer than two\n * of `ids` are nodes on one layer.\n */\nexport function makeBooleanGroup(scene: AnyScene, ids: readonly string[], op: BooleanShapeOp = 'union'): NodeId | null {\n const order = new Map([...scene.renderOrder()].map((id, i) => [id as string, i]));\n const nodes = ids\n .map((id) => scene.get(id as NodeId))\n .filter((n): n is Node<unknown, string, unknown> => n !== undefined)\n .sort((a, b) => (order.get(a.id) ?? 0) - (order.get(b.id) ?? 0));\n if (nodes.length < 2 || new Set(nodes.map((n) => n.layer)).size > 1) return null;\n const front = nodes.at(-1)!;\n const parents = new Set(nodes.map((n) => n.parent ?? null));\n const parent = parents.size === 1 ? front.parent ?? null : null;\n const siblings = parent === null ? scene.roots : scene.childrenOf(parent);\n const at = siblings.indexOf(front.id);\n const own = (front.data ?? {}) as Record<string, unknown>;\n const data = { boolean: op, ...Object.fromEntries(PAINT_KEYS.filter((k) => k in own).map((k) => [k, own[k]])) };\n const frame = scenePoseFrame(scene);\n let group: NodeId | null = null;\n scene.batch('Make Boolean Group', () => {\n const worlds = new Map(nodes.map((n) => [n.id, frame.world(n.id)]));\n group = scene.add({\n ...booleanGroupFields(), layer: front.layer, pose: front.pose, data, parent,\n ...(at >= 0 ? { index: at + 1 } : {}),\n });\n nodes.forEach((n, i) => {\n scene.move(n.id, group, i);\n scene.setPose(n.id, frame.localUnder(group, worlds.get(n.id)!) as never);\n });\n });\n return group;\n}\n\n/** Put the selection under a new boolean group, a union until its operation is changed. */\nexport const makeBooleanGroupAction: Action & { requires: string[] } = {\n id: 'pathfinder.booleanGroup',\n label: 'Make Boolean Group',\n icon: icon('booleanGroup'),\n group: 'pathfinder',\n eligible: { capability: 'creates-shapes' },\n requires: ['scene', 'selection'],\n invoker: {\n timing: 'immediate',\n run: (deps) => {\n const { scene, selection } = deps;\n if (!scene || !selection) return;\n const id = makeBooleanGroup(scene as AnyScene, selection.get());\n if (id !== null) selection.set([id]);\n },\n },\n enabled: (deps) => ((deps?.selection?.get().length ?? 0) >= 2 ? true : ActionDisabledReason.SelectionRequired),\n};\n"],"mappings":"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"}
@@ -0,0 +1,52 @@
1
+ import { pathfinderCropAction, pathfinderDivideAction, pathfinderExcludeAction, pathfinderIntersectAction, pathfinderMergeAction, pathfinderSubtractAction, pathfinderTrimAction, pathfinderUnionAction } from "./action.js";
2
+ import { holdPreview, holdPreviewId, keymapContribution } from "@weasel-js/routing";
3
+
4
+ //#region src/interactions/actions/booleans/keymap.ts
5
+ /** The Pathfinder keymap's id; its leader action is `keymap.pathfinder`. */
6
+ var PATHFINDER_KEYMAP_ID = "pathfinder";
7
+ /** Alt+P, by the physical key too, since with Alt held on a Mac it types `π`. */
8
+ var PATHFINDER_LEADER = {
9
+ kind: "key",
10
+ key: "p",
11
+ code: "KeyP",
12
+ mods: { alt: true }
13
+ };
14
+ var heldKey = (letter) => ({
15
+ kind: "key-held",
16
+ key: letter,
17
+ code: `Key${letter.toUpperCase()}`,
18
+ mods: { alt: "optional" }
19
+ });
20
+ var KEYS = [
21
+ [pathfinderUnionAction, "u"],
22
+ [pathfinderIntersectAction, "i"],
23
+ [pathfinderSubtractAction, "m"],
24
+ [pathfinderExcludeAction, "x"],
25
+ [pathfinderDivideAction, "d"],
26
+ [pathfinderCropAction, "c"],
27
+ [pathfinderTrimAction, "t"],
28
+ [pathfinderMergeAction, "r"]
29
+ ];
30
+ /**
31
+ * The Pathfinder operations on held keys, behind the leader Alt+P: holding
32
+ * an operation's key previews it on the selection, releasing runs it, and
33
+ * Escape while it is held cancels it. Each binding's id is its hold's action
34
+ * id (`pathfinder.union.hold`), which is what a host rebinds it by. The
35
+ * operations themselves come from the `paths` preset; this carries only their
36
+ * holds. Install it with `<SceneCanvas ambient>`.
37
+ */
38
+ var PATHFINDER_KEYMAP = keymapContribution({
39
+ id: PATHFINDER_KEYMAP_ID,
40
+ label: "Pathfinder",
41
+ leader: PATHFINDER_LEADER,
42
+ bindings: KEYS.map(([action, letter]) => ({
43
+ spec: heldKey(letter),
44
+ actionId: holdPreviewId(action.id),
45
+ opts: { id: holdPreviewId(action.id) }
46
+ })),
47
+ actions: KEYS.map(([action]) => holdPreview(action))
48
+ });
49
+
50
+ //#endregion
51
+ export { PATHFINDER_KEYMAP, PATHFINDER_KEYMAP_ID, PATHFINDER_LEADER };
52
+ //# sourceMappingURL=keymap.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keymap.js","names":[],"sources":["../../../../src/interactions/actions/booleans/keymap.ts"],"sourcesContent":["import type { KeyHeldSpec, KeySpec } from '@weasel-js/gestures';\nimport { holdPreview, holdPreviewId, keymapContribution, type Action, type Contribution } from '@weasel-js/routing';\nimport {\n pathfinderCropAction, pathfinderDivideAction, pathfinderExcludeAction, pathfinderIntersectAction,\n pathfinderMergeAction, pathfinderSubtractAction, pathfinderTrimAction, pathfinderUnionAction,\n} from './action';\n\n/** The Pathfinder keymap's id; its leader action is `keymap.pathfinder`. */\nexport const PATHFINDER_KEYMAP_ID = 'pathfinder';\n\n/** Alt+P, by the physical key too, since with Alt held on a Mac it types `π`. */\nexport const PATHFINDER_LEADER: KeySpec = { kind: 'key', key: 'p', code: 'KeyP', mods: { alt: true } };\n\n// Alt is optional so the keys work with the leader held down as well as tapped.\nconst heldKey = (letter: string): KeyHeldSpec =>\n ({ kind: 'key-held', key: letter, code: `Key${letter.toUpperCase()}`, mods: { alt: 'optional' } });\n\nconst KEYS: readonly (readonly [Action, string])[] = [\n [pathfinderUnionAction, 'u'],\n [pathfinderIntersectAction, 'i'],\n [pathfinderSubtractAction, 'm'],\n [pathfinderExcludeAction, 'x'],\n [pathfinderDivideAction, 'd'],\n [pathfinderCropAction, 'c'],\n [pathfinderTrimAction, 't'],\n [pathfinderMergeAction, 'r'],\n];\n\n/**\n * The Pathfinder operations on held keys, behind the leader Alt+P: holding\n * an operation's key previews it on the selection, releasing runs it, and\n * Escape while it is held cancels it. Each binding's id is its hold's action\n * id (`pathfinder.union.hold`), which is what a host rebinds it by. The\n * operations themselves come from the `paths` preset; this carries only their\n * holds. Install it with `<SceneCanvas ambient>`.\n */\nexport const PATHFINDER_KEYMAP: readonly Contribution<never>[] = keymapContribution({\n id: PATHFINDER_KEYMAP_ID,\n label: 'Pathfinder',\n leader: PATHFINDER_LEADER,\n bindings: KEYS.map(([action, letter]) => ({\n spec: heldKey(letter),\n actionId: holdPreviewId(action.id),\n opts: { id: holdPreviewId(action.id) },\n })),\n actions: KEYS.map(([action]) => holdPreview(action)),\n});\n"],"mappings":";;;;;AAQA,IAAa,uBAAuB;;AAGpC,IAAa,oBAA6B;CAAE,MAAM;CAAO,KAAK;CAAK,MAAM;CAAQ,MAAM,EAAE,KAAK,KAAK;AAAE;AAGrG,IAAM,WAAW,YACd;CAAE,MAAM;CAAY,KAAK;CAAQ,MAAM,MAAM,OAAO,YAAY;CAAK,MAAM,EAAE,KAAK,WAAW;AAAE;AAElG,IAAM,OAA+C;CACnD,CAAC,uBAAuB,GAAG;CAC3B,CAAC,2BAA2B,GAAG;CAC/B,CAAC,0BAA0B,GAAG;CAC9B,CAAC,yBAAyB,GAAG;CAC7B,CAAC,wBAAwB,GAAG;CAC5B,CAAC,sBAAsB,GAAG;CAC1B,CAAC,sBAAsB,GAAG;CAC1B,CAAC,uBAAuB,GAAG;AAC7B;;;;;;;;;AAUA,IAAa,oBAAoD,mBAAmB;CAClF,IAAI;CACJ,OAAO;CACP,QAAQ;CACR,UAAU,KAAK,KAAK,CAAC,QAAQ,aAAa;EACxC,MAAM,QAAQ,MAAM;EACpB,UAAU,cAAc,OAAO,EAAE;EACjC,MAAM,EAAE,IAAI,cAAc,OAAO,EAAE,EAAE;CACvC,EAAE;CACF,SAAS,KAAK,KAAK,CAAC,YAAY,YAAY,MAAM,CAAC;AACrD,CAAC"}
@@ -1,7 +1,7 @@
1
1
  import { strokeRegion } from "../outlines/strokeRegion.js";
2
2
  import { resolveFill, resolveStroke } from "@weasel-js/paint";
3
- import { textToPath, textToPathsByPaint } from "@weasel-js/text";
4
3
  import { pathUnion } from "@weasel-js/geom/booleans";
4
+ import { textToPath, textToPathsByPaint } from "@weasel-js/text";
5
5
 
6
6
  //#region src/interactions/actions/booleans/operands.ts
7
7
  function inkOf(source, strokes, frame, scale) {
@@ -1,4 +1,5 @@
1
- import { pathCropPieces, pathDividePieces, pathExclude, pathIntersect, pathMerge, pathSubtract, pathTrim, pathUnion } from "@weasel-js/geom/booleans";
1
+ import { booleanOfPaths } from "../../../core/geometry/booleanOfPaths.js";
2
+ import { pathCropPieces, pathDividePieces, pathMerge, pathTrim } from "@weasel-js/geom/booleans";
2
3
 
3
4
  //#region src/interactions/actions/booleans/pieces.ts
4
5
  /** A piece stands in for the topmost input left in it. */
@@ -19,19 +20,11 @@ function booleanPieces(op, paths, mergeKey) {
19
20
  let pieces;
20
21
  switch (op) {
21
22
  case "union":
22
- pieces = whole(pathUnion(...paths));
23
- break;
24
23
  case "intersect":
25
- pieces = whole(pathIntersect(...paths));
26
- break;
27
24
  case "exclude":
28
- pieces = whole(pathExclude(...paths));
29
- break;
30
- case "subtract": {
31
- const front = paths.length === 2 ? paths[1] : pathUnion(...paths.slice(1));
32
- pieces = whole(pathSubtract(paths[0], front));
25
+ case "subtract":
26
+ pieces = whole(booleanOfPaths(op, paths));
33
27
  break;
34
- }
35
28
  case "divide":
36
29
  pieces = bySource(pathDividePieces(...paths));
37
30
  break;
@@ -1 +1 @@
1
- {"version":3,"file":"pieces.js","names":[],"sources":["../../../../src/interactions/actions/booleans/pieces.ts"],"sourcesContent":["import {\n pathUnion,\n pathIntersect,\n pathSubtract,\n pathExclude,\n pathDividePieces,\n pathCropPieces,\n pathTrim,\n pathMerge,\n type BooleanPiece,\n} from '@weasel-js/geom/booleans';\nimport type { Path, PolygonPath } from '@weasel-js/geom';\nimport type { BooleanOp } from './booleans';\n\n/** One result path, and the operand it stands in for: an index into the\n * operands, back to front. */\nexport interface ResultPiece {\n path: PolygonPath;\n source: number;\n}\n\n/** A piece stands in for the topmost input left in it. */\nfunction bySource(pieces: BooleanPiece[]): ResultPiece[] {\n return pieces.map((p) => ({ path: p.path, source: p.sources[p.sources.length - 1]! }));\n}\n\n/** Run `op` over `paths`, back to front, dropping empty results. `mergeKey`\n * answers alike for the paths a Merge unites. */\nexport function booleanPieces(op: BooleanOp, paths: Path[], mergeKey: (index: number) => unknown): ResultPiece[] {\n const top = paths.length - 1;\n const whole = (path: PolygonPath): ResultPiece[] => [{ path, source: top }];\n let pieces: ResultPiece[];\n switch (op) {\n case 'union': pieces = whole(pathUnion(...paths)); break;\n case 'intersect': pieces = whole(pathIntersect(...paths)); break;\n case 'exclude': pieces = whole(pathExclude(...paths)); break;\n case 'subtract': {\n // Illustrator \"Minus Front\": back − union(everything in front).\n const front = paths.length === 2 ? paths[1]! : pathUnion(...paths.slice(1));\n pieces = whole(pathSubtract(paths[0]!, front));\n break;\n }\n case 'divide': pieces = bySource(pathDividePieces(...paths)); break;\n // Illustrator \"Crop\": every source below the topmost, clipped to it; the\n // topmost is consumed as the mask.\n case 'crop': pieces = bySource(pathCropPieces(...paths)); break;\n case 'trim': pieces = bySource(pathTrim(...paths)); break;\n case 'merge': pieces = bySource(pathMerge(paths, mergeKey)); break;\n }\n return pieces.filter((p) => p.path.commands.length > 0);\n}\n"],"mappings":";;;;AAsBA,SAAS,SAAS,QAAuC;CACvD,OAAO,OAAO,KAAK,OAAO;EAAE,MAAM,EAAE;EAAM,QAAQ,EAAE,QAAQ,EAAE,QAAQ,SAAS;CAAI,EAAE;AACvF;;;AAIA,SAAgB,cAAc,IAAe,OAAe,UAAqD;CAC/G,MAAM,MAAM,MAAM,SAAS;CAC3B,MAAM,SAAS,SAAqC,CAAC;EAAE;EAAM,QAAQ;CAAI,CAAC;CAC1E,IAAI;CACJ,QAAQ,IAAR;EACE,KAAK;GAAa,SAAS,MAAM,UAAU,GAAG,KAAK,CAAC;GAAG;EACvD,KAAK;GAAa,SAAS,MAAM,cAAc,GAAG,KAAK,CAAC;GAAG;EAC3D,KAAK;GAAa,SAAS,MAAM,YAAY,GAAG,KAAK,CAAC;GAAG;EACzD,KAAK,YAAY;GAEf,MAAM,QAAQ,MAAM,WAAW,IAAI,MAAM,KAAM,UAAU,GAAG,MAAM,MAAM,CAAC,CAAC;GAC1E,SAAS,MAAM,aAAa,MAAM,IAAK,KAAK,CAAC;GAC7C;EACF;EACA,KAAK;GAAa,SAAS,SAAS,iBAAiB,GAAG,KAAK,CAAC;GAAG;EAGjE,KAAK;GAAa,SAAS,SAAS,eAAe,GAAG,KAAK,CAAC;GAAG;EAC/D,KAAK;GAAa,SAAS,SAAS,SAAS,GAAG,KAAK,CAAC;GAAG;EACzD,KAAK,SAAa,SAAS,SAAS,UAAU,OAAO,QAAQ,CAAC;CAChE;CACA,OAAO,OAAO,QAAQ,MAAM,EAAE,KAAK,SAAS,SAAS,CAAC;AACxD"}
1
+ {"version":3,"file":"pieces.js","names":[],"sources":["../../../../src/interactions/actions/booleans/pieces.ts"],"sourcesContent":["import {\n pathDividePieces,\n pathCropPieces,\n pathTrim,\n pathMerge,\n type BooleanPiece,\n} from '@weasel-js/geom/booleans';\nimport type { Path, PolygonPath } from '@weasel-js/geom';\nimport type { BooleanOp } from './booleans';\nimport { booleanOfPaths } from 'core/geometry/booleanOfPaths';\n\n/** One result path, and the operand it stands in for: an index into the\n * operands, back to front. */\nexport interface ResultPiece {\n path: PolygonPath;\n source: number;\n}\n\n/** A piece stands in for the topmost input left in it. */\nfunction bySource(pieces: BooleanPiece[]): ResultPiece[] {\n return pieces.map((p) => ({ path: p.path, source: p.sources[p.sources.length - 1]! }));\n}\n\n/** Run `op` over `paths`, back to front, dropping empty results. `mergeKey`\n * answers alike for the paths a Merge unites. */\nexport function booleanPieces(op: BooleanOp, paths: Path[], mergeKey: (index: number) => unknown): ResultPiece[] {\n const top = paths.length - 1;\n const whole = (path: PolygonPath): ResultPiece[] => [{ path, source: top }];\n let pieces: ResultPiece[];\n switch (op) {\n case 'union':\n case 'intersect':\n case 'exclude':\n case 'subtract': pieces = whole(booleanOfPaths(op, paths)); break;\n case 'divide': pieces = bySource(pathDividePieces(...paths)); break;\n // Illustrator \"Crop\": every source below the topmost, clipped to it; the\n // topmost is consumed as the mask.\n case 'crop': pieces = bySource(pathCropPieces(...paths)); break;\n case 'trim': pieces = bySource(pathTrim(...paths)); break;\n case 'merge': pieces = bySource(pathMerge(paths, mergeKey)); break;\n }\n return pieces.filter((p) => p.path.commands.length > 0);\n}\n"],"mappings":";;;;;AAmBA,SAAS,SAAS,QAAuC;CACvD,OAAO,OAAO,KAAK,OAAO;EAAE,MAAM,EAAE;EAAM,QAAQ,EAAE,QAAQ,EAAE,QAAQ,SAAS;CAAI,EAAE;AACvF;;;AAIA,SAAgB,cAAc,IAAe,OAAe,UAAqD;CAC/G,MAAM,MAAM,MAAM,SAAS;CAC3B,MAAM,SAAS,SAAqC,CAAC;EAAE;EAAM,QAAQ;CAAI,CAAC;CAC1E,IAAI;CACJ,QAAQ,IAAR;EACE,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;GAAa,SAAS,MAAM,eAAe,IAAI,KAAK,CAAC;GAAG;EAC7D,KAAK;GAAa,SAAS,SAAS,iBAAiB,GAAG,KAAK,CAAC;GAAG;EAGjE,KAAK;GAAa,SAAS,SAAS,eAAe,GAAG,KAAK,CAAC;GAAG;EAC/D,KAAK;GAAa,SAAS,SAAS,SAAS,GAAG,KAAK,CAAC;GAAG;EACzD,KAAK,SAAa,SAAS,SAAS,UAAU,OAAO,QAAQ,CAAC;CAChE;CACA,OAAO,OAAO,QAAQ,MAAM,EAAE,KAAK,SAAS,SAAS,CAAC;AACxD"}
@@ -1,7 +1,7 @@
1
1
  import { defaultCommitAdapter } from "../defaultCommitAdapter.js";
2
2
  import { requiresSelection } from "../defaults/requiresSelection.js";
3
3
  import { buildDeleteOps } from "../defaults/delete.js";
4
- import { kitWeaselJsonHandler } from "../../../features/ingestion/weaselJsonHandler.js";
4
+ import { kitWeaselJsonHandler } from "../../../domains/ingestion/weaselJsonHandler.js";
5
5
  import { ANY_INGEST_MODS, INGEST_REQUIRES, claimable, ingestFromEvent } from "../defaults/ingest.js";
6
6
  import { ActionDisabledReason } from "@weasel-js/routing";
7
7
 
@@ -95,12 +95,8 @@ var clipboardPasteAction = {
95
95
  invoker: {
96
96
  timing: "immediate",
97
97
  run: (deps, params) => {
98
- const x = params?.worldX;
99
- const y = params?.worldY;
100
- deps.clipboard?.paste(typeof x === "number" && typeof y === "number" ? {
101
- worldX: x,
102
- worldY: y
103
- } : void 0);
98
+ const world = params?.world;
99
+ deps.clipboard?.paste(world);
104
100
  }
105
101
  },
106
102
  enabled: (deps) => {
@@ -1 +1 @@
1
- {"version":3,"file":"action.js","names":[],"sources":["../../../../src/interactions/actions/clipboard/action.ts"],"sourcesContent":["import { defaultCommitAdapter } from '../defaultCommitAdapter';\nimport { ActionDisabledReason, type Action } from '@weasel-js/routing';\nimport { buildDeleteOps } from '../defaults/delete';\nimport { requiresSelection } from '../defaults/requiresSelection';\nimport { kitWeaselJsonHandler } from 'features/ingestion/weaselJsonHandler';\nimport { ANY_INGEST_MODS, claimable, INGEST_REQUIRES, ingestFromEvent } from '../defaults/ingest';\nimport { icon } from '../../../icons.gen';\n\n/**\n * Static descriptor for the `clipboard.copy` Action (Cmd/Ctrl+C).\n */\nexport const clipboardCopyAction: Action & { requires: string[] } = {\n id: 'clipboard.copy',\n label: 'Copy',\n icon: icon('copy'),\n group: 'clipboard',\n defaultBinding: [{ spec: { kind: 'key', key: 'c', mods: { mod: true } }, opts: { id: 'clipboard.copy.key' } }],\n // Same gate as `duplicate`: a mode that can neither edit the page nor own a\n // selection has nothing to copy. Notably excludes `text-edit`, where Cmd+C\n // must stay the browser's own copy of the caret range.\n eligible: { capability: ['edits-page', 'creates-selection'] },\n // `selection` is read by the `enabled` gate, not the invoker — the\n // dispatcher builds deps for both, and an undeclared read is undefined.\n requires: ['clipboard', 'selection'],\n invoker: {\n timing: 'immediate',\n run: (deps) => {\n deps.clipboard?.copy();\n },\n },\n enabled: requiresSelection,\n};\n\n/**\n * Static descriptor for the `clipboard.cut` Action (Cmd/Ctrl+X) — copy, then\n * the same batched delete `deleteAction` performs, as one undo entry: the\n * sources a path effect hid go too.\n */\nexport const clipboardCutAction: Action & { requires: string[] } = {\n id: 'clipboard.cut',\n label: 'Cut',\n icon: icon('cut'),\n group: 'clipboard',\n defaultBinding: [{ spec: { kind: 'key', key: 'x', mods: { mod: true } }, opts: { id: 'clipboard.cut.key' } }],\n eligible: { capability: 'edits-page' },\n requires: ['clipboard', 'scene', 'selection', 'applyOps'],\n invoker: {\n timing: 'immediate',\n run: (deps) => {\n const clipboard = deps.clipboard;\n const selection = deps.selection;\n const scene = deps.scene;\n const applyOps = deps.applyOps;\n if (!clipboard || !selection || !scene) return;\n const ids = selection.get();\n if (ids.length === 0) return;\n\n // Snapshot before removal — `snapshotSelection` reads live nodes.\n clipboard.copy();\n\n const ops = buildDeleteOps(scene, ids, 'Cut', { takeHiddenSources: true });\n if (ops.length > 0) {\n if (applyOps) applyOps(ops, 'Cut');\n else scene.applyBatch(ops, 'Cut', defaultCommitAdapter(scene, selection.adapterMethods));\n }\n selection.set([]);\n },\n },\n enabled: requiresSelection,\n};\n\n/**\n * Static descriptor for the `clipboard.paste` Action — what a Paste button or\n * menu item triggers, pasting the last copy this canvas made. It has no key\n * binding: Cmd/Ctrl+V already arrives as a DOM `paste` event, which the\n * dispatcher routes to `clipboard.pasteEvent` or `ingest`, and a binding here\n * would fire alongside it and paste twice.\n */\nexport const clipboardPasteAction: Action & { requires: string[] } = {\n id: 'clipboard.paste',\n label: 'Paste',\n icon: icon('paste'),\n group: 'clipboard',\n eligible: { capability: 'edits-page' },\n requires: ['clipboard'],\n invoker: {\n timing: 'immediate',\n run: (deps, params) => {\n const x = params?.worldX;\n const y = params?.worldY;\n deps.clipboard?.paste(typeof x === 'number' && typeof y === 'number' ? { worldX: x, worldY: y } : undefined);\n },\n },\n enabled: (deps) => {\n const clipboard = deps?.clipboard;\n return clipboard && !clipboard.isEmpty() ? true : ActionDisabledReason.NotApplicable;\n },\n};\n\nconst PASTE_EVENT_HANDLERS = [kitWeaselJsonHandler];\n\n/**\n * Static descriptor for the `clipboard.pasteEvent` Action — Cmd/Ctrl+V on a\n * canvas that edits and does not ingest. It answers the DOM `paste` event by\n * pasting nodes a kit canvas copied to the OS clipboard, in this tab or\n * another, and nothing else: an image, SVG, or file on the clipboard, and\n * every consumer content handler, need `ingest`. `ingest` binds the same\n * event and takes this payload among the rest, so `useStandardActions`\n * leaves this one unregistered wherever `ingest` is registered.\n *\n * Bound to `text/plain` because that is the only flavor of a copy a paste\n * event carries; a paste without text stays the page's.\n */\nexport const clipboardPasteEventAction: Action & { requires: string[] } = {\n id: 'clipboard.pasteEvent',\n label: 'Paste copied nodes',\n defaultBinding: [{ spec: { kind: 'paste', types: ['text/plain'], mods: ANY_INGEST_MODS }, opts: { id: 'clipboard.pasteEvent.paste' } }],\n requires: [...INGEST_REQUIRES],\n invoker: {\n timing: 'immediate',\n run: (deps, params) => ingestFromEvent(deps, params, { handlers: PASTE_EVENT_HANDLERS }),\n },\n enabled: (_deps, _at, carried) => claimable(carried, PASTE_EVENT_HANDLERS),\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"action.js","names":[],"sources":["../../../../src/interactions/actions/clipboard/action.ts"],"sourcesContent":["import { defaultCommitAdapter } from '../defaultCommitAdapter';\nimport { ActionDisabledReason, type Action } from '@weasel-js/routing';\nimport { buildDeleteOps } from '../defaults/delete';\nimport { requiresSelection } from '../defaults/requiresSelection';\nimport { kitWeaselJsonHandler } from 'domains/ingestion/weaselJsonHandler';\nimport { ANY_INGEST_MODS, claimable, INGEST_REQUIRES, ingestFromEvent } from '../defaults/ingest';\nimport { icon } from '../../../icons.gen';\nimport type { ImmediateParams } from '@weasel-js/routing';\n\n/**\n * Static descriptor for the `clipboard.copy` Action (Cmd/Ctrl+C).\n */\nexport const clipboardCopyAction: Action & { requires: string[] } = {\n id: 'clipboard.copy',\n label: 'Copy',\n icon: icon('copy'),\n group: 'clipboard',\n defaultBinding: [{ spec: { kind: 'key', key: 'c', mods: { mod: true } }, opts: { id: 'clipboard.copy.key' } }],\n // Same gate as `duplicate`: a mode that can neither edit the page nor own a\n // selection has nothing to copy. Notably excludes `text-edit`, where Cmd+C\n // must stay the browser's own copy of the caret range.\n eligible: { capability: ['edits-page', 'creates-selection'] },\n // `selection` is read by the `enabled` gate, not the invoker — the\n // dispatcher builds deps for both, and an undeclared read is undefined.\n requires: ['clipboard', 'selection'],\n invoker: {\n timing: 'immediate',\n run: (deps) => {\n deps.clipboard?.copy();\n },\n },\n enabled: requiresSelection,\n};\n\n/**\n * Static descriptor for the `clipboard.cut` Action (Cmd/Ctrl+X) — copy, then\n * the same batched delete `deleteAction` performs, as one undo entry: the\n * sources a path effect hid go too.\n */\nexport const clipboardCutAction: Action & { requires: string[] } = {\n id: 'clipboard.cut',\n label: 'Cut',\n icon: icon('cut'),\n group: 'clipboard',\n defaultBinding: [{ spec: { kind: 'key', key: 'x', mods: { mod: true } }, opts: { id: 'clipboard.cut.key' } }],\n eligible: { capability: 'edits-page' },\n requires: ['clipboard', 'scene', 'selection', 'applyOps'],\n invoker: {\n timing: 'immediate',\n run: (deps) => {\n const clipboard = deps.clipboard;\n const selection = deps.selection;\n const scene = deps.scene;\n const applyOps = deps.applyOps;\n if (!clipboard || !selection || !scene) return;\n const ids = selection.get();\n if (ids.length === 0) return;\n\n // Snapshot before removal — `snapshotSelection` reads live nodes.\n clipboard.copy();\n\n const ops = buildDeleteOps(scene, ids, 'Cut', { takeHiddenSources: true });\n if (ops.length > 0) {\n if (applyOps) applyOps(ops, 'Cut');\n else scene.applyBatch(ops, 'Cut', defaultCommitAdapter(scene, selection.adapterMethods));\n }\n selection.set([]);\n },\n },\n enabled: requiresSelection,\n};\n\n/**\n * Static descriptor for the `clipboard.paste` Action — what a Paste button or\n * menu item triggers, pasting the last copy this canvas made. It has no key\n * binding: Cmd/Ctrl+V already arrives as a DOM `paste` event, which the\n * dispatcher routes to `clipboard.pasteEvent` or `ingest`, and a binding here\n * would fire alongside it and paste twice.\n */\nexport const clipboardPasteAction: Action & { requires: string[] } = {\n id: 'clipboard.paste',\n label: 'Paste',\n icon: icon('paste'),\n group: 'clipboard',\n eligible: { capability: 'edits-page' },\n requires: ['clipboard'],\n invoker: {\n timing: 'immediate',\n run: (deps, params) => {\n const world = (params as ImmediateParams | undefined)?.world;\n deps.clipboard?.paste(world);\n },\n },\n enabled: (deps) => {\n const clipboard = deps?.clipboard;\n return clipboard && !clipboard.isEmpty() ? true : ActionDisabledReason.NotApplicable;\n },\n};\n\nconst PASTE_EVENT_HANDLERS = [kitWeaselJsonHandler];\n\n/**\n * Static descriptor for the `clipboard.pasteEvent` Action — Cmd/Ctrl+V on a\n * canvas that edits and does not ingest. It answers the DOM `paste` event by\n * pasting nodes a kit canvas copied to the OS clipboard, in this tab or\n * another, and nothing else: an image, SVG, or file on the clipboard, and\n * every consumer content handler, need `ingest`. `ingest` binds the same\n * event and takes this payload among the rest, so `useStandardActions`\n * leaves this one unregistered wherever `ingest` is registered.\n *\n * Bound to `text/plain` because that is the only flavor of a copy a paste\n * event carries; a paste without text stays the page's.\n */\nexport const clipboardPasteEventAction: Action & { requires: string[] } = {\n id: 'clipboard.pasteEvent',\n label: 'Paste copied nodes',\n defaultBinding: [{ spec: { kind: 'paste', types: ['text/plain'], mods: ANY_INGEST_MODS }, opts: { id: 'clipboard.pasteEvent.paste' } }],\n requires: [...INGEST_REQUIRES],\n invoker: {\n timing: 'immediate',\n run: (deps, params) => ingestFromEvent(deps, params, { handlers: PASTE_EVENT_HANDLERS }),\n },\n enabled: (_deps, _at, carried) => claimable(carried, PASTE_EVENT_HANDLERS),\n};\n"],"mappings":"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"}
@@ -12,7 +12,7 @@ var EMPTY = { items: [] };
12
12
  function useClipboardOps(adapter, options) {
13
13
  const { getSelection, onPaste, onPasteOmitted, pasteLabel = "Paste", getDropPoint, produceFlavors, jsonReplacer } = options;
14
14
  const pointerCtx = usePointerContext();
15
- const effectiveGetDropPoint = getDropPoint ?? pointerCtx?.getDropPoint;
15
+ const effectiveGetDropPoint = getDropPoint ?? (pointerCtx ? () => pointerCtx.get()?.world ?? null : void 0);
16
16
  const clipboardRef = useRef(EMPTY);
17
17
  const adapterRef = useLatest(adapter);
18
18
  const optsRef = useLatest({
@@ -1 +1 @@
1
- {"version":3,"file":"clipboardOps.js","names":[],"sources":["../../../../src/interactions/actions/clipboard/clipboardOps.ts"],"sourcesContent":["import { useCallback, useRef } from 'react';\nimport { useLatest } from '@weasel-js/react';\nimport type { NodeId } from 'core/scene/types';\nimport { dispatchApplyBatch } from 'core/applyOps';\nimport type { InsertAdapter, PasteOmission } from 'core/adapters/types';\nimport type { ClipboardSnapshot } from './types';\nimport { usePointerContext } from '@weasel-js/routing/react';\nimport { dwarn } from 'debug/flag';\nimport { materializePaste } from './materializePaste';\nimport { WEASEL_CLIPBOARD_MIME, buildWeaselClipboardText } from './wireFormat';\n\ntype Replacer = (key: string, value: unknown) => unknown;\n\n/** Options for `useClipboardOps`. */\nexport interface UseClipboardOpsOptions {\n /** How the hook reads \"current selection\" for copy. The kit doesn't assume\n * a global selection store; each consumer wires this. */\n getSelection: () => NodeId[];\n /** Called after a successful paste with the ids of the newly inserted objects. */\n onPaste?: (newIds: NodeId[]) => void;\n /** Called when a paste left copied nodes out, with each one and the reason\n * — an edge whose endpoints were not copied with it, say. Also called for\n * a paste that made nothing. */\n onPasteOmitted?: (omitted: PasteOmission[]) => void;\n /** Label for the history entry produced by paste. Default 'Paste'. */\n pasteLabel?: string;\n /** Pulled once per paste() call. When non-null, threaded to commitPaste\n * as `ctx.dropPoint`; adapters typically use it as the cluster origin\n * (ignoring `offset`). When null/undefined, the hook falls back to the\n * existing cascade-offset behavior. */\n getDropPoint?: () => { worldX: number; worldY: number } | null;\n /** Produce the OS-clipboard flavor map for a copied snapshot. Keys are MIME\n * types, values the serialized payload. The kit default emits\n * `application/x-weasel-clipboard+json` plus `text/plain` carrying the\n * same JSON. Apps override to add richer flavors (e.g. real SVG) or to\n * replace the text flavor. Return an empty object to skip the OS write\n * entirely. A value may be a promise — an SVG flavor waiting on\n * `warmSvg`, say: the write is still issued inside the copy gesture and\n * the clipboard takes the text when it resolves. The producer itself runs\n * synchronously, so it reads the selection as it stood at the copy. */\n produceFlavors?: (snapshot: ClipboardSnapshot) => ClipboardFlavors;\n /** Replacer for the kit-default JSON flavor (typed arrays etc.). Ignored\n * when `produceFlavors` is supplied. */\n jsonReplacer?: Replacer;\n}\n\n/** MIME type to payload, as `produceFlavors` returns it. */\nexport type ClipboardFlavors = Record<string, string | Promise<string>>;\n\n/** Return shape of `useClipboardOps`: imperative `copy`, `paste`, and `isEmpty` functions. */\nexport interface UseClipboardOpsReturn {\n copy(): void;\n /** Paste at `at` when given; otherwise at the drop point, else the cascade offset. */\n paste(at?: { worldX: number; worldY: number }): void;\n isEmpty(): boolean;\n}\n\nconst EMPTY: ClipboardSnapshot = { items: [] };\n\n/** In-memory copy/paste of selections via `InsertAdapter.snapshotSelection` / `commitPaste`. */\nexport function useClipboardOps<TNode extends { id: string }>(\n adapter: InsertAdapter<TNode>,\n options: UseClipboardOpsOptions,\n): UseClipboardOpsReturn {\n const {\n getSelection, onPaste, onPasteOmitted, pasteLabel = 'Paste', getDropPoint, produceFlavors, jsonReplacer,\n } = options;\n // Fall back to the ambient pointer context (auto-published by SceneCanvas)\n // when the caller didn't supply an explicit `getDropPoint`. Null context\n // (no provider in scope) and no caller-supplied thunk together mean\n // \"no drop point\" — paste uses the cascade offset instead.\n const pointerCtx = usePointerContext();\n const effectiveGetDropPoint = getDropPoint ?? pointerCtx?.getDropPoint;\n const clipboardRef = useRef<ClipboardSnapshot>(EMPTY);\n // Keep callbacks stable across renders.\n const adapterRef = useLatest(adapter);\n const optsRef = useLatest({\n getSelection, onPaste, onPasteOmitted, pasteLabel, getDropPoint: effectiveGetDropPoint, produceFlavors,\n jsonReplacer,\n });\n\n const copy = useCallback(() => {\n const ids = optsRef.current.getSelection();\n if (ids.length === 0) return;\n const snap = adapterRef.current.snapshotSelection;\n if (!snap) return;\n clipboardRef.current = snap(ids);\n // Best-effort OS write. Never blocks or throws — the in-memory ref is\n // already set, and OS clipboard support varies (custom formats are\n // Chromium-only via the \"web \" prefix; jsdom/non-secure contexts have\n // no API at all). The flavor producer itself is untrusted consumer code\n // (`produceFlavors`), so guard its call too — a throwing producer must\n // not break `copy()`, it just skips the OS write.\n let flavors: ClipboardFlavors | null = null;\n try {\n flavors = optsRef.current.produceFlavors?.(clipboardRef.current)\n ?? defaultFlavors(clipboardRef.current, optsRef.current.jsonReplacer);\n } catch (err) {\n dwarn('clipboard', `flavor producer threw — skipping OS write: ${String(err)}`);\n }\n if (flavors) void writeOsClipboard(flavors);\n }, [adapterRef, optsRef]);\n\n const paste = useCallback((at?: { worldX: number; worldY: number }) => {\n const cb = clipboardRef.current;\n if (cb.items.length === 0) return;\n const a = adapterRef.current;\n const result = materializePaste(a, cb, {\n currentSelection: optsRef.current.getSelection(),\n dropPoint: at ?? optsRef.current.getDropPoint?.(),\n onOmitted: optsRef.current.onPasteOmitted,\n });\n if (!result) return;\n dispatchApplyBatch(a, result.ops, optsRef.current.pasteLabel);\n // Use the just-created objects as the next cascade source. Re-snapshotting\n // via `adapter.snapshotSelection(newIds)` would read adapter state, but\n // React-state adapters haven't flushed yet — `itemsRef.current` still\n // points at the pre-insert array, so the snapshot would come back empty\n // and the next paste would no-op.\n clipboardRef.current = { items: result.created };\n optsRef.current.onPaste?.(result.newIds as NodeId[]);\n }, [adapterRef, optsRef]);\n\n const isEmpty = useCallback(() => clipboardRef.current.items.length === 0, []);\n\n return { copy, paste, isEmpty };\n}\n\nfunction defaultFlavors(snapshot: ClipboardSnapshot, replacer?: Replacer): ClipboardFlavors {\n const text = buildWeaselClipboardText(snapshot.items, replacer);\n return { [WEASEL_CLIPBOARD_MIME]: text, 'text/plain': text };\n}\n\n/** MIME types the async Clipboard API accepts unprefixed. Every other type\n * (including our own custom MIME, and app-supplied flavors like\n * `image/svg+xml`) must carry Chromium's `web ` prefix or `ClipboardItem`'s\n * constructor throws. */\nconst WELL_KNOWN_CLIPBOARD_MIMES = new Set(['text/plain', 'text/html', 'image/png']);\n\n/** Degradation ladder: full map (every non-well-known MIME web-prefixed) →\n * the same minus any promised flavor that rejected → well-known-only → give\n * up with a dwarn. Chromium writes nothing when one flavor rejects, so a\n * rejection costs only that flavor, never the clipboard's previous content\n * half-overwritten.\n * @internal test seam — exported so unit tests can await the fire-and-forget\n * write directly; tests should still exercise this at least once through\n * the public `copy()` (see clipboardOps.test.tsx). */\nexport async function writeOsClipboard(flavors: ClipboardFlavors): Promise<void> {\n const entries = Object.entries(flavors);\n if (entries.length === 0) return;\n const cb = typeof navigator !== 'undefined' ? navigator.clipboard : undefined;\n if (!cb?.write || typeof ClipboardItem === 'undefined') return;\n const rejected = new Set<string>();\n for (const [mime, text] of entries) {\n if (typeof text !== 'string') text.catch(() => { rejected.add(mime); });\n }\n const wireMime = (mime: string) => (WELL_KNOWN_CLIPBOARD_MIMES.has(mime) ? mime : `web ${mime}`);\n const toItem = (fs: Flavor[]) => new ClipboardItem(Object.fromEntries(\n fs.map(([mime, text]) => {\n const wire = wireMime(mime);\n const blob = (t: string) => new Blob([t], { type: wire });\n if (typeof text === 'string') return [wire, blob(text)];\n const promised = text.then(blob);\n // Chromium leaves a ClipboardItem's rejected promise unhandled.\n promised.catch(() => {});\n return [wire, promised];\n }),\n ));\n // Writes `fs`, dropping flavors whose promise rejected and retrying the\n // rest. Returns the last error, or null once a write lands.\n const writeLive = async (fs: Flavor[]): Promise<unknown> => {\n let live = fs;\n for (;;) {\n try {\n await cb.write([toItem(live)]);\n return null;\n } catch (err) {\n const next = live.filter(([mime]) => !rejected.has(mime));\n if (next.length === live.length || next.length === 0) return err;\n live = next;\n }\n }\n };\n if (await writeLive(entries) === null) return;\n const standard = entries.filter(([mime]) => WELL_KNOWN_CLIPBOARD_MIMES.has(mime) && !rejected.has(mime));\n if (standard.length === 0) { dwarn('clipboard', 'OS write failed; no standard flavors to fall back to'); return; }\n const err = await writeLive(standard);\n if (err !== null) dwarn('clipboard', `OS clipboard write failed twice — copy stays in-memory only: ${String(err)}`);\n}\n\ntype Flavor = [mime: string, text: string | Promise<string>];\n"],"mappings":"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"}
1
+ {"version":3,"file":"clipboardOps.js","names":[],"sources":["../../../../src/interactions/actions/clipboard/clipboardOps.ts"],"sourcesContent":["import { useCallback, useRef } from 'react';\nimport { useLatest } from '@weasel-js/react';\nimport type { NodeId } from 'core/scene/types';\nimport { dispatchApplyBatch } from 'core/applyOps';\nimport type { InsertAdapter, PasteOmission } from 'core/adapters/types';\nimport type { ClipboardSnapshot } from './types';\nimport type { WorldPoint } from '@weasel-js/routing';\nimport { usePointerContext } from '@weasel-js/routing/react';\nimport { dwarn } from 'debug/flag';\nimport { materializePaste } from './materializePaste';\nimport { WEASEL_CLIPBOARD_MIME, buildWeaselClipboardText } from './wireFormat';\n\ntype Replacer = (key: string, value: unknown) => unknown;\n\n/** Options for `useClipboardOps`. */\nexport interface UseClipboardOpsOptions {\n /** How the hook reads \"current selection\" for copy. The kit doesn't assume\n * a global selection store; each consumer wires this. */\n getSelection: () => NodeId[];\n /** Called after a successful paste with the ids of the newly inserted objects. */\n onPaste?: (newIds: NodeId[]) => void;\n /** Called when a paste left copied nodes out, with each one and the reason\n * — an edge whose endpoints were not copied with it, say. Also called for\n * a paste that made nothing. */\n onPasteOmitted?: (omitted: PasteOmission[]) => void;\n /** Label for the history entry produced by paste. Default 'Paste'. */\n pasteLabel?: string;\n /** Pulled once per paste() call. When non-null, threaded to commitPaste\n * as `ctx.dropPoint`; adapters typically use it as the cluster origin\n * (ignoring `offset`). When null/undefined, the hook falls back to the\n * existing cascade-offset behavior. */\n getDropPoint?: () => WorldPoint | null;\n /** Produce the OS-clipboard flavor map for a copied snapshot. Keys are MIME\n * types, values the serialized payload. The kit default emits\n * `application/x-weasel-clipboard+json` plus `text/plain` carrying the\n * same JSON. Apps override to add richer flavors (e.g. real SVG) or to\n * replace the text flavor. Return an empty object to skip the OS write\n * entirely. A value may be a promise — an SVG flavor waiting on\n * `warmSvg`, say: the write is still issued inside the copy gesture and\n * the clipboard takes the text when it resolves. The producer itself runs\n * synchronously, so it reads the selection as it stood at the copy. */\n produceFlavors?: (snapshot: ClipboardSnapshot) => ClipboardFlavors;\n /** Replacer for the kit-default JSON flavor (typed arrays etc.). Ignored\n * when `produceFlavors` is supplied. */\n jsonReplacer?: Replacer;\n}\n\n/** MIME type to payload, as `produceFlavors` returns it. */\nexport type ClipboardFlavors = Record<string, string | Promise<string>>;\n\n/** Return shape of `useClipboardOps`: imperative `copy`, `paste`, and `isEmpty` functions. */\nexport interface UseClipboardOpsReturn {\n copy(): void;\n /** Paste at `at` when given; otherwise at the drop point, else the cascade offset. */\n paste(at?: WorldPoint): void;\n isEmpty(): boolean;\n}\n\nconst EMPTY: ClipboardSnapshot = { items: [] };\n\n/** In-memory copy/paste of selections via `InsertAdapter.snapshotSelection` / `commitPaste`. */\nexport function useClipboardOps<TNode extends { id: string }>(\n adapter: InsertAdapter<TNode>,\n options: UseClipboardOpsOptions,\n): UseClipboardOpsReturn {\n const {\n getSelection, onPaste, onPasteOmitted, pasteLabel = 'Paste', getDropPoint, produceFlavors, jsonReplacer,\n } = options;\n // Fall back to the ambient pointer context (auto-published by SceneCanvas)\n // when the caller didn't supply an explicit `getDropPoint`. Null context\n // (no provider in scope) and no caller-supplied thunk together mean\n // \"no drop point\" — paste uses the cascade offset instead.\n const pointerCtx = usePointerContext();\n const effectiveGetDropPoint = getDropPoint ?? (pointerCtx ? () => pointerCtx.get()?.world ?? null : undefined);\n const clipboardRef = useRef<ClipboardSnapshot>(EMPTY);\n // Keep callbacks stable across renders.\n const adapterRef = useLatest(adapter);\n const optsRef = useLatest({\n getSelection, onPaste, onPasteOmitted, pasteLabel, getDropPoint: effectiveGetDropPoint, produceFlavors,\n jsonReplacer,\n });\n\n const copy = useCallback(() => {\n const ids = optsRef.current.getSelection();\n if (ids.length === 0) return;\n const snap = adapterRef.current.snapshotSelection;\n if (!snap) return;\n clipboardRef.current = snap(ids);\n // Best-effort OS write. Never blocks or throws — the in-memory ref is\n // already set, and OS clipboard support varies (custom formats are\n // Chromium-only via the \"web \" prefix; jsdom/non-secure contexts have\n // no API at all). The flavor producer itself is untrusted consumer code\n // (`produceFlavors`), so guard its call too — a throwing producer must\n // not break `copy()`, it just skips the OS write.\n let flavors: ClipboardFlavors | null = null;\n try {\n flavors = optsRef.current.produceFlavors?.(clipboardRef.current)\n ?? defaultFlavors(clipboardRef.current, optsRef.current.jsonReplacer);\n } catch (err) {\n dwarn('clipboard', `flavor producer threw — skipping OS write: ${String(err)}`);\n }\n if (flavors) void writeOsClipboard(flavors);\n }, [adapterRef, optsRef]);\n\n const paste = useCallback((at?: WorldPoint) => {\n const cb = clipboardRef.current;\n if (cb.items.length === 0) return;\n const a = adapterRef.current;\n const result = materializePaste(a, cb, {\n currentSelection: optsRef.current.getSelection(),\n dropPoint: at ?? optsRef.current.getDropPoint?.(),\n onOmitted: optsRef.current.onPasteOmitted,\n });\n if (!result) return;\n dispatchApplyBatch(a, result.ops, optsRef.current.pasteLabel);\n // Use the just-created objects as the next cascade source. Re-snapshotting\n // via `adapter.snapshotSelection(newIds)` would read adapter state, but\n // React-state adapters haven't flushed yet — `itemsRef.current` still\n // points at the pre-insert array, so the snapshot would come back empty\n // and the next paste would no-op.\n clipboardRef.current = { items: result.created };\n optsRef.current.onPaste?.(result.newIds as NodeId[]);\n }, [adapterRef, optsRef]);\n\n const isEmpty = useCallback(() => clipboardRef.current.items.length === 0, []);\n\n return { copy, paste, isEmpty };\n}\n\nfunction defaultFlavors(snapshot: ClipboardSnapshot, replacer?: Replacer): ClipboardFlavors {\n const text = buildWeaselClipboardText(snapshot.items, replacer);\n return { [WEASEL_CLIPBOARD_MIME]: text, 'text/plain': text };\n}\n\n/** MIME types the async Clipboard API accepts unprefixed. Every other type\n * (including our own custom MIME, and app-supplied flavors like\n * `image/svg+xml`) must carry Chromium's `web ` prefix or `ClipboardItem`'s\n * constructor throws. */\nconst WELL_KNOWN_CLIPBOARD_MIMES = new Set(['text/plain', 'text/html', 'image/png']);\n\n/** Degradation ladder: full map (every non-well-known MIME web-prefixed) →\n * the same minus any promised flavor that rejected → well-known-only → give\n * up with a dwarn. Chromium writes nothing when one flavor rejects, so a\n * rejection costs only that flavor, never the clipboard's previous content\n * half-overwritten.\n * @internal test seam — exported so unit tests can await the fire-and-forget\n * write directly; tests should still exercise this at least once through\n * the public `copy()` (see clipboardOps.test.tsx). */\nexport async function writeOsClipboard(flavors: ClipboardFlavors): Promise<void> {\n const entries = Object.entries(flavors);\n if (entries.length === 0) return;\n const cb = typeof navigator !== 'undefined' ? navigator.clipboard : undefined;\n if (!cb?.write || typeof ClipboardItem === 'undefined') return;\n const rejected = new Set<string>();\n for (const [mime, text] of entries) {\n if (typeof text !== 'string') text.catch(() => { rejected.add(mime); });\n }\n const wireMime = (mime: string) => (WELL_KNOWN_CLIPBOARD_MIMES.has(mime) ? mime : `web ${mime}`);\n const toItem = (fs: Flavor[]) => new ClipboardItem(Object.fromEntries(\n fs.map(([mime, text]) => {\n const wire = wireMime(mime);\n const blob = (t: string) => new Blob([t], { type: wire });\n if (typeof text === 'string') return [wire, blob(text)];\n const promised = text.then(blob);\n // Chromium leaves a ClipboardItem's rejected promise unhandled.\n promised.catch(() => {});\n return [wire, promised];\n }),\n ));\n // Writes `fs`, dropping flavors whose promise rejected and retrying the\n // rest. Returns the last error, or null once a write lands.\n const writeLive = async (fs: Flavor[]): Promise<unknown> => {\n let live = fs;\n for (;;) {\n try {\n await cb.write([toItem(live)]);\n return null;\n } catch (err) {\n const next = live.filter(([mime]) => !rejected.has(mime));\n if (next.length === live.length || next.length === 0) return err;\n live = next;\n }\n }\n };\n if (await writeLive(entries) === null) return;\n const standard = entries.filter(([mime]) => WELL_KNOWN_CLIPBOARD_MIMES.has(mime) && !rejected.has(mime));\n if (standard.length === 0) { dwarn('clipboard', 'OS write failed; no standard flavors to fall back to'); return; }\n const err = await writeLive(standard);\n if (err !== null) dwarn('clipboard', `OS clipboard write failed twice — copy stays in-memory only: ${String(err)}`);\n}\n\ntype Flavor = [mime: string, text: string | Promise<string>];\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"materializePaste.js","names":[],"sources":["../../../../src/interactions/actions/clipboard/materializePaste.ts"],"sourcesContent":["/**\n * Shared paste materialization — the one place the paste recipe lives:\n * offset policy → `commitPaste` → the op batch (InsertOps parents-first +\n * a SetSelectionOp). Both `useClipboardOps.paste` (in-memory paste) and the\n * kit weasel-JSON content handler (OS-clipboard paste) dispatch exactly this\n * batch, so the two arrival paths stay indistinguishable in history.\n *\n * Pure: no dispatching here — callers own how the ops are applied\n * (`dispatchApplyBatch` vs `IngestCtx.applyOps`) and any post-paste\n * bookkeeping (the hook's cascade re-snapshot, the handler's selection set).\n */\nimport { createInsertOp } from 'core/ops/create';\nimport { createSetSelectionOp } from 'core/ops/select';\nimport type { Op } from 'core/ops/types';\nimport type { NodeId } from 'core/scene/types';\nimport type { ClipboardSnapshot, InsertAdapter, PasteCtx, PasteOmission } from 'core/adapters/types';\n\n/** Shared paste materialization: offset policy → commitPaste → the op batch\n * both the in-memory paste and the OS-paste handler dispatch. Returns null\n * when the adapter can't paste or nothing was created. */\nexport function materializePaste<TNode extends { id: string }>(\n adapter: InsertAdapter<TNode>,\n snapshot: ClipboardSnapshot,\n opts: {\n currentSelection: string[];\n dropPoint?: { worldX: number; worldY: number } | null;\n /** Told what the paste left out and why, when it left anything out —\n * including a paste that made nothing. */\n onOmitted?: (omitted: PasteOmission[]) => void;\n },\n): { ops: Op[]; newIds: string[]; created: TNode[] } | null {\n const commitPaste = adapter.commitPaste;\n if (!commitPaste) return null;\n const offset = adapter.getPasteOffset?.(snapshot) ?? { dx: 0, dy: 0 };\n const omitted: PasteOmission[] = [];\n const ctx: PasteCtx = {\n ...(opts.dropPoint != null ? { dropPoint: opts.dropPoint } : {}),\n ...(opts.onOmitted ? { onOmit: (omission: PasteOmission) => omitted.push(omission) } : {}),\n };\n const created = commitPaste.call(\n adapter, snapshot, offset, Object.keys(ctx).length > 0 ? ctx : undefined,\n );\n if (omitted.length > 0) opts.onOmitted?.(omitted);\n if (created.length === 0) return null;\n const newIds = created.map((o) => o.id);\n const ops: Op[] = [\n ...created.map((o) => createInsertOp({ node: o })),\n createSetSelectionOp({ from: opts.currentSelection as NodeId[], to: newIds as NodeId[] }),\n ];\n return { ops, newIds, created };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAoBA,SAAgB,iBACd,SACA,UACA,MAO0D;CAC1D,MAAM,cAAc,QAAQ;CAC5B,IAAI,CAAC,aAAa,OAAO;CACzB,MAAM,SAAS,QAAQ,iBAAiB,QAAQ,KAAK;EAAE,IAAI;EAAG,IAAI;CAAE;CACpE,MAAM,UAA2B,CAAC;CAClC,MAAM,MAAgB;EACpB,GAAI,KAAK,aAAa,OAAO,EAAE,WAAW,KAAK,UAAU,IAAI,CAAC;EAC9D,GAAI,KAAK,YAAY,EAAE,SAAS,aAA4B,QAAQ,KAAK,QAAQ,EAAE,IAAI,CAAC;CAC1F;CACA,MAAM,UAAU,YAAY,KAC1B,SAAS,UAAU,QAAQ,OAAO,KAAK,GAAG,CAAC,CAAC,SAAS,IAAI,MAAM,MACjE;CACA,IAAI,QAAQ,SAAS,GAAG,KAAK,YAAY,OAAO;CAChD,IAAI,QAAQ,WAAW,GAAG,OAAO;CACjC,MAAM,SAAS,QAAQ,KAAK,MAAM,EAAE,EAAE;CAKtC,OAAO;EAAE,MAHP,GAAG,QAAQ,KAAK,MAAM,eAAe,EAAE,MAAM,EAAE,CAAC,CAAC,GACjD,qBAAqB;GAAE,MAAM,KAAK;GAA8B,IAAI;EAAmB,CAAC,CAEjF;EAAK;EAAQ;CAAQ;AAChC"}
1
+ {"version":3,"file":"materializePaste.js","names":[],"sources":["../../../../src/interactions/actions/clipboard/materializePaste.ts"],"sourcesContent":["/**\n * Shared paste materialization — the one place the paste recipe lives:\n * offset policy → `commitPaste` → the op batch (InsertOps parents-first +\n * a SetSelectionOp). Both `useClipboardOps.paste` (in-memory paste) and the\n * kit weasel-JSON content handler (OS-clipboard paste) dispatch exactly this\n * batch, so the two arrival paths stay indistinguishable in history.\n *\n * Pure: no dispatching here — callers own how the ops are applied\n * (`dispatchApplyBatch` vs `IngestCtx.applyOps`) and any post-paste\n * bookkeeping (the hook's cascade re-snapshot, the handler's selection set).\n */\nimport { createInsertOp } from 'core/ops/create';\nimport { createSetSelectionOp } from 'core/ops/select';\nimport type { Op } from 'core/ops/types';\nimport type { NodeId } from 'core/scene/types';\nimport type { WorldPoint } from '@weasel-js/routing';\nimport type { ClipboardSnapshot, InsertAdapter, PasteCtx, PasteOmission } from 'core/adapters/types';\n\n/** Shared paste materialization: offset policy → commitPaste → the op batch\n * both the in-memory paste and the OS-paste handler dispatch. Returns null\n * when the adapter can't paste or nothing was created. */\nexport function materializePaste<TNode extends { id: string }>(\n adapter: InsertAdapter<TNode>,\n snapshot: ClipboardSnapshot,\n opts: {\n currentSelection: string[];\n dropPoint?: WorldPoint | null;\n /** Told what the paste left out and why, when it left anything out —\n * including a paste that made nothing. */\n onOmitted?: (omitted: PasteOmission[]) => void;\n },\n): { ops: Op[]; newIds: string[]; created: TNode[] } | null {\n const commitPaste = adapter.commitPaste;\n if (!commitPaste) return null;\n const offset = adapter.getPasteOffset?.(snapshot) ?? { dx: 0, dy: 0 };\n const omitted: PasteOmission[] = [];\n const ctx: PasteCtx = {\n ...(opts.dropPoint != null ? { dropPoint: opts.dropPoint } : {}),\n ...(opts.onOmitted ? { onOmit: (omission: PasteOmission) => omitted.push(omission) } : {}),\n };\n const created = commitPaste.call(\n adapter, snapshot, offset, Object.keys(ctx).length > 0 ? ctx : undefined,\n );\n if (omitted.length > 0) opts.onOmitted?.(omitted);\n if (created.length === 0) return null;\n const newIds = created.map((o) => o.id);\n const ops: Op[] = [\n ...created.map((o) => createInsertOp({ node: o })),\n createSetSelectionOp({ from: opts.currentSelection as NodeId[], to: newIds as NodeId[] }),\n ];\n return { ops, newIds, created };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAqBA,SAAgB,iBACd,SACA,UACA,MAO0D;CAC1D,MAAM,cAAc,QAAQ;CAC5B,IAAI,CAAC,aAAa,OAAO;CACzB,MAAM,SAAS,QAAQ,iBAAiB,QAAQ,KAAK;EAAE,IAAI;EAAG,IAAI;CAAE;CACpE,MAAM,UAA2B,CAAC;CAClC,MAAM,MAAgB;EACpB,GAAI,KAAK,aAAa,OAAO,EAAE,WAAW,KAAK,UAAU,IAAI,CAAC;EAC9D,GAAI,KAAK,YAAY,EAAE,SAAS,aAA4B,QAAQ,KAAK,QAAQ,EAAE,IAAI,CAAC;CAC1F;CACA,MAAM,UAAU,YAAY,KAC1B,SAAS,UAAU,QAAQ,OAAO,KAAK,GAAG,CAAC,CAAC,SAAS,IAAI,MAAM,MACjE;CACA,IAAI,QAAQ,SAAS,GAAG,KAAK,YAAY,OAAO;CAChD,IAAI,QAAQ,WAAW,GAAG,OAAO;CACjC,MAAM,SAAS,QAAQ,KAAK,MAAM,EAAE,EAAE;CAKtC,OAAO;EAAE,MAHP,GAAG,QAAQ,KAAK,MAAM,eAAe,EAAE,MAAM,EAAE,CAAC,CAAC,GACjD,qBAAqB;GAAE,MAAM,KAAK;GAA8B,IAAI;EAAmB,CAAC,CAEjF;EAAK;EAAQ;CAAQ;AAChC"}
@@ -115,9 +115,9 @@ var selectAnchorAction = inPlane({
115
115
  run: (deps, params) => {
116
116
  const dep = depOf(deps);
117
117
  if (!dep) return;
118
- const wx = params?.worldX;
119
- const wy = params?.worldY;
120
- if (typeof wx !== "number" || typeof wy !== "number") return;
118
+ const world = params?.world;
119
+ if (!world) return;
120
+ const { x: wx, y: wy } = world;
121
121
  const worldPath = worldPathOf(dep);
122
122
  if (!worldPath) return;
123
123
  const hit = nearestAnchorIndex(worldPath, wx, wy, anchorClickSlop(deps));
@@ -267,9 +267,9 @@ var cutPathAtAnchorAction = inPlane({
267
267
  run: (deps, params) => {
268
268
  const dep = depOf(deps);
269
269
  if (!dep) return;
270
- const wx = params?.worldX;
271
- const wy = params?.worldY;
272
- if (typeof wx !== "number" || typeof wy !== "number") return;
270
+ const world = params?.world;
271
+ if (!world) return;
272
+ const { x: wx, y: wy } = world;
273
273
  const worldPath = worldPathOf(dep);
274
274
  if (!worldPath) return;
275
275
  const nearest = nearestAnchorIndex(worldPath, wx, wy, anchorClickSlop(deps));