@weasel-js/core 1.6.1 → 1.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +1006 -0
- package/README.md +28 -9
- package/dist/WeaselProvider.js +15 -0
- package/dist/WeaselProvider.js.map +1 -0
- package/dist/affordances/composeAffordanceLayer.js +224 -0
- package/dist/affordances/composeAffordanceLayer.js.map +1 -0
- package/dist/affordances/cornerResize.js +69 -0
- package/dist/affordances/cornerResize.js.map +1 -0
- package/dist/affordances/hitAffordanceRegions.js +138 -0
- package/dist/affordances/hitAffordanceRegions.js.map +1 -0
- package/dist/affordances/pathAnchors.js +66 -0
- package/dist/affordances/pathAnchors.js.map +1 -0
- package/dist/affordances/rotationHandle.js +103 -0
- package/dist/affordances/rotationHandle.js.map +1 -0
- package/dist/animation/behaviors/momentum.js +118 -0
- package/dist/animation/behaviors/momentum.js.map +1 -0
- package/dist/animation/colorHelpers.js +135 -0
- package/dist/animation/colorHelpers.js.map +1 -0
- package/dist/animation/colorRegistry.js +37 -0
- package/dist/animation/colorRegistry.js.map +1 -0
- package/dist/animation/index.js +20 -0
- package/dist/animation/loop.js +62 -0
- package/dist/animation/loop.js.map +1 -0
- package/dist/animation/observe.js +23 -0
- package/dist/animation/observe.js.map +1 -0
- package/dist/animation/poseHelpers.js +50 -0
- package/dist/animation/poseHelpers.js.map +1 -0
- package/dist/animation/reflow.js +121 -0
- package/dist/animation/reflow.js.map +1 -0
- package/dist/animation/rig/bindRig.js +74 -0
- package/dist/animation/rig/bindRig.js.map +1 -0
- package/dist/animation/rig/blendPoses.js +43 -0
- package/dist/animation/rig/blendPoses.js.map +1 -0
- package/dist/animation/rig/mirrorPose.js +19 -0
- package/dist/animation/rig/mirrorPose.js.map +1 -0
- package/dist/animation/rig/resolveSkeleton.js +33 -0
- package/dist/animation/rig/resolveSkeleton.js.map +1 -0
- package/dist/animation/rig/solveIk.js +103 -0
- package/dist/animation/rig/solveIk.js.map +1 -0
- package/dist/animation/rig/types.js +12 -0
- package/dist/animation/rig/types.js.map +1 -0
- package/dist/animation/rig/useRig.js +23 -0
- package/dist/animation/rig/useRig.js.map +1 -0
- package/dist/animation/slew.js +27 -0
- package/dist/animation/slew.js.map +1 -0
- package/dist/animation/stagger.js +138 -0
- package/dist/animation/stagger.js.map +1 -0
- package/dist/animation/timeline/booking.js +106 -0
- package/dist/animation/timeline/booking.js.map +1 -0
- package/dist/animation/timeline/createTimeline.js +116 -0
- package/dist/animation/timeline/createTimeline.js.map +1 -0
- package/dist/animation/timeline/sampleTrack.js +29 -0
- package/dist/animation/timeline/sampleTrack.js.map +1 -0
- package/dist/animation/useAnimator.js +329 -0
- package/dist/animation/useAnimator.js.map +1 -0
- package/dist/animation/wrappers/animateLifecycle.js +40 -0
- package/dist/animation/wrappers/animateLifecycle.js.map +1 -0
- package/dist/animation/wrappers/animateOnSetPose.js +44 -0
- package/dist/animation/wrappers/animateOnSetPose.js.map +1 -0
- package/dist/{autoPoseDescriptor-_XOyF7t4.d.ts → autoPoseDescriptor-BT_vp9FO.d.ts} +2 -2
- package/dist/{builtins-HWyuLzE-.d.ts → builtins-BSUfH8nU.d.ts} +1301 -508
- package/dist/canvas/Canvas.js +608 -0
- package/dist/canvas/Canvas.js.map +1 -0
- package/dist/canvas/CanvasView.js +255 -0
- package/dist/canvas/CanvasView.js.map +1 -0
- package/dist/canvas/CursorCoordsHud.js +75 -0
- package/dist/canvas/CursorCoordsHud.js.map +1 -0
- package/dist/canvas/DrawCanvas.js +67 -0
- package/dist/canvas/DrawCanvas.js.map +1 -0
- package/dist/canvas/MinimapCanvas.js +139 -0
- package/dist/canvas/MinimapCanvas.js.map +1 -0
- package/dist/canvas/ModalityHud.js +66 -0
- package/dist/canvas/ModalityHud.js.map +1 -0
- package/dist/canvas/NodeShape.js +391 -0
- package/dist/canvas/NodeShape.js.map +1 -0
- package/dist/canvas/PickHud.js +93 -0
- package/dist/canvas/PickHud.js.map +1 -0
- package/dist/canvas/SceneCanvas/ActionsProviderIfRoot.js +10 -0
- package/dist/canvas/SceneCanvas/ActionsProviderIfRoot.js.map +1 -0
- package/dist/canvas/SceneCanvas/DepRegistryProviderIfRoot.js +10 -0
- package/dist/canvas/SceneCanvas/DepRegistryProviderIfRoot.js.map +1 -0
- package/dist/canvas/SceneCanvas/PointerProviderIfRoot.js +51 -0
- package/dist/canvas/SceneCanvas/PointerProviderIfRoot.js.map +1 -0
- package/dist/canvas/SceneCanvas/contributionFrameHooks.js +42 -0
- package/dist/canvas/SceneCanvas/contributionFrameHooks.js.map +1 -0
- package/dist/canvas/SceneCanvas/defaultNodeProperties.js +549 -0
- package/dist/canvas/SceneCanvas/defaultNodeProperties.js.map +1 -0
- package/dist/canvas/SceneCanvas/defaultNodeRouting.js +26 -0
- package/dist/canvas/SceneCanvas/defaultNodeRouting.js.map +1 -0
- package/dist/canvas/SceneCanvas/dispatcherGestureBounds.js +69 -0
- package/dist/canvas/SceneCanvas/dispatcherGestureBounds.js.map +1 -0
- package/dist/canvas/SceneCanvas/features.js +97 -0
- package/dist/canvas/SceneCanvas/features.js.map +1 -0
- package/dist/canvas/SceneCanvas/poseGeometry.js +46 -0
- package/dist/canvas/SceneCanvas/poseGeometry.js.map +1 -0
- package/dist/canvas/SceneCanvas/useActionsPropResolver.js +48 -0
- package/dist/canvas/SceneCanvas/useActionsPropResolver.js.map +1 -0
- package/dist/canvas/SceneCanvas/useBuiltinShapeTools.js +70 -0
- package/dist/canvas/SceneCanvas/useBuiltinShapeTools.js.map +1 -0
- package/dist/canvas/SceneCanvas/useContributionRoles.js +75 -0
- package/dist/canvas/SceneCanvas/useContributionRoles.js.map +1 -0
- package/dist/canvas/SceneCanvas/useDispatcherOverlayLayer.js +172 -0
- package/dist/canvas/SceneCanvas/useDispatcherOverlayLayer.js.map +1 -0
- package/dist/canvas/SceneCanvas/usePreviewGhostLayer.js +69 -0
- package/dist/canvas/SceneCanvas/usePreviewGhostLayer.js.map +1 -0
- package/dist/canvas/SceneCanvas/useSceneSelectTool.js +127 -0
- package/dist/canvas/SceneCanvas/useSceneSelectTool.js.map +1 -0
- package/dist/canvas/SceneCanvas/useViewportActions.js +30 -0
- package/dist/canvas/SceneCanvas/useViewportActions.js.map +1 -0
- package/dist/canvas/SceneCanvas.js +992 -0
- package/dist/canvas/SceneCanvas.js.map +1 -0
- package/dist/canvas/SceneViewCanvas.js +54 -0
- package/dist/canvas/SceneViewCanvas.js.map +1 -0
- package/dist/canvas/accentColor.js +9 -0
- package/dist/canvas/accentColor.js.map +1 -0
- package/dist/canvas/affordanceAt.js +63 -0
- package/dist/canvas/affordanceAt.js.map +1 -0
- package/dist/canvas/buildSceneTree.js +65 -0
- package/dist/canvas/buildSceneTree.js.map +1 -0
- package/dist/canvas/canvasRenderer.js +89 -0
- package/dist/canvas/canvasRenderer.js.map +1 -0
- package/dist/canvas/colorOverrides.js +16 -0
- package/dist/canvas/colorOverrides.js.map +1 -0
- package/dist/canvas/defaultDrawOne.js +43 -0
- package/dist/canvas/defaultDrawOne.js.map +1 -0
- package/dist/canvas/deps/areaSelect.js +19 -0
- package/dist/canvas/deps/areaSelect.js.map +1 -0
- package/dist/canvas/deps/debug.js +9 -0
- package/dist/canvas/deps/debug.js.map +1 -0
- package/dist/canvas/deps/dispatcher.js +11 -0
- package/dist/canvas/deps/dispatcher.js.map +1 -0
- package/dist/canvas/deps/editAnchors.js +101 -0
- package/dist/canvas/deps/editAnchors.js.map +1 -0
- package/dist/canvas/deps/geometryProjection.js +11 -0
- package/dist/canvas/deps/geometryProjection.js.map +1 -0
- package/dist/canvas/deps/hitTestArea.js +51 -0
- package/dist/canvas/deps/hitTestArea.js.map +1 -0
- package/dist/canvas/deps/ingestion.js +31 -0
- package/dist/canvas/deps/ingestion.js.map +1 -0
- package/dist/canvas/deps/insert.js +116 -0
- package/dist/canvas/deps/insert.js.map +1 -0
- package/dist/canvas/deps/lassoSelect.js +20 -0
- package/dist/canvas/deps/lassoSelect.js.map +1 -0
- package/dist/canvas/deps/layout.js +34 -0
- package/dist/canvas/deps/layout.js.map +1 -0
- package/dist/canvas/deps/nodeAtPoint.js +19 -0
- package/dist/canvas/deps/nodeAtPoint.js.map +1 -0
- package/dist/canvas/deps/poseComposition.js +11 -0
- package/dist/canvas/deps/poseComposition.js.map +1 -0
- package/dist/canvas/deps/poseDescriptor.js +12 -0
- package/dist/canvas/deps/poseDescriptor.js.map +1 -0
- package/dist/canvas/deps/resizePolicy.js +35 -0
- package/dist/canvas/deps/resizePolicy.js.map +1 -0
- package/dist/canvas/deps/slice.js +99 -0
- package/dist/canvas/deps/slice.js.map +1 -0
- package/dist/canvas/deps/snap.js +11 -0
- package/dist/canvas/deps/snap.js.map +1 -0
- package/dist/canvas/deps/textEdit.js +21 -0
- package/dist/canvas/deps/textEdit.js.map +1 -0
- package/dist/canvas/deps/view.js +43 -0
- package/dist/canvas/deps/view.js.map +1 -0
- package/dist/canvas/derivedPath.js +47 -0
- package/dist/canvas/derivedPath.js.map +1 -0
- package/dist/canvas/drawEnvelope.js +22 -0
- package/dist/canvas/drawEnvelope.js.map +1 -0
- package/dist/canvas/getNodeAtPoint.js +18 -0
- package/dist/canvas/getNodeAtPoint.js.map +1 -0
- package/dist/canvas/hostAnchor.js +29 -0
- package/dist/canvas/hostAnchor.js.map +1 -0
- package/dist/canvas/hud.module.js +18 -0
- package/dist/canvas/hud.module.js.map +1 -0
- package/dist/canvas/insertPreviewExtent.js +103 -0
- package/dist/canvas/insertPreviewExtent.js.map +1 -0
- package/dist/canvas/kitRequirements.js +177 -0
- package/dist/canvas/kitRequirements.js.map +1 -0
- package/dist/canvas/layerOrder.js +66 -0
- package/dist/canvas/layerOrder.js.map +1 -0
- package/dist/canvas/layerSlots.js +14 -0
- package/dist/canvas/layerSlots.js.map +1 -0
- package/dist/canvas/minimapMath.js +80 -0
- package/dist/canvas/minimapMath.js.map +1 -0
- package/dist/canvas/mountedCanvases.js +20 -0
- package/dist/canvas/mountedCanvases.js.map +1 -0
- package/dist/canvas/overlayRoleStrokes.js +17 -0
- package/dist/canvas/overlayRoleStrokes.js.map +1 -0
- package/dist/canvas/paintCull.js +20 -0
- package/dist/canvas/paintCull.js.map +1 -0
- package/dist/canvas/pickWalk.js +158 -0
- package/dist/canvas/pickWalk.js.map +1 -0
- package/dist/canvas/planeClips.js +30 -0
- package/dist/canvas/planeClips.js.map +1 -0
- package/dist/canvas/poseRotation.js +35 -0
- package/dist/canvas/poseRotation.js.map +1 -0
- package/dist/canvas/rasterToPng.js +21 -0
- package/dist/canvas/rasterToPng.js.map +1 -0
- package/dist/canvas/renderDebugSnapshot.js +32 -0
- package/dist/canvas/renderDebugSnapshot.js.map +1 -0
- package/dist/canvas/renderNeeds.js +25 -0
- package/dist/canvas/renderNeeds.js.map +1 -0
- package/dist/canvas/renderSceneToPixels.js +143 -0
- package/dist/canvas/renderSceneToPixels.js.map +1 -0
- package/dist/canvas/sceneAdapter.js +270 -0
- package/dist/canvas/sceneAdapter.js.map +1 -0
- package/dist/canvas/sceneLayerPaint.js +37 -0
- package/dist/canvas/sceneLayerPaint.js.map +1 -0
- package/dist/canvas/sceneSlotWiring.js +20 -0
- package/dist/canvas/sceneSlotWiring.js.map +1 -0
- package/dist/canvas/sceneViewRender.js +72 -0
- package/dist/canvas/sceneViewRender.js.map +1 -0
- package/dist/canvas/slopsDebugLayer.js +61 -0
- package/dist/canvas/slopsDebugLayer.js.map +1 -0
- package/dist/canvas/surfaceContribution.js +15 -0
- package/dist/canvas/surfaceContribution.js.map +1 -0
- package/dist/canvas/toolPreview.js +39 -0
- package/dist/canvas/toolPreview.js.map +1 -0
- package/dist/canvas/useCanvasRenderer.js +11 -0
- package/dist/canvas/useCanvasRenderer.js.map +1 -0
- package/dist/canvas/useFrameLoop.js +60 -0
- package/dist/canvas/useFrameLoop.js.map +1 -0
- package/dist/canvas/useHostAnchor.js +71 -0
- package/dist/canvas/useHostAnchor.js.map +1 -0
- package/dist/canvas/useLateContentRedraw.js +21 -0
- package/dist/canvas/useLateContentRedraw.js.map +1 -0
- package/dist/canvas/useRedrawOn.js +21 -0
- package/dist/canvas/useRedrawOn.js.map +1 -0
- package/dist/canvas/useViewHelpers.js +120 -0
- package/dist/canvas/useViewHelpers.js.map +1 -0
- package/dist/canvas/viewInputs.js +17 -0
- package/dist/canvas/viewInputs.js.map +1 -0
- package/dist/canvas/viewRegistry.js +61 -0
- package/dist/canvas/viewRegistry.js.map +1 -0
- package/dist/canvas/wrapNodeOutput.js +14 -0
- package/dist/canvas/wrapNodeOutput.js.map +1 -0
- package/dist/clipboard.d.ts +10 -5
- package/dist/clipboard.js +3 -5
- package/dist/clone.d.ts +3 -3
- package/dist/clone.js +2 -5
- package/dist/core/adapters/arrayAdapter.js +85 -0
- package/dist/core/adapters/arrayAdapter.js.map +1 -0
- package/dist/core/adapters/useArrayAdapter.js +13 -0
- package/dist/core/adapters/useArrayAdapter.js.map +1 -0
- package/dist/core/applyOps.js +12 -0
- package/dist/core/applyOps.js.map +1 -0
- package/dist/core/device/index.js +4 -0
- package/dist/core/device/targets.js +17 -0
- package/dist/core/device/targets.js.map +1 -0
- package/dist/core/device/useDeviceProfile.js +75 -0
- package/dist/core/device/useDeviceProfile.js.map +1 -0
- package/dist/core/fillInPoseFrame.js +102 -0
- package/dist/core/fillInPoseFrame.js.map +1 -0
- package/dist/core/geometry/poseDescriptor.js +98 -0
- package/dist/core/geometry/poseDescriptor.js.map +1 -0
- package/dist/core/geometry/poseRotation.js +58 -0
- package/dist/core/geometry/poseRotation.js.map +1 -0
- package/dist/core/geometry/regionHit.js +102 -0
- package/dist/core/geometry/regionHit.js.map +1 -0
- package/dist/core/geometry/unionBounds.js +60 -0
- package/dist/core/geometry/unionBounds.js.map +1 -0
- package/dist/core/gradient.js +136 -0
- package/dist/core/gradient.js.map +1 -0
- package/dist/core/isPlainObject.js +11 -0
- package/dist/core/isPlainObject.js.map +1 -0
- package/dist/core/layers/render.js +150 -0
- package/dist/core/layers/render.js.map +1 -0
- package/dist/core/markerInset.js +24 -0
- package/dist/core/markerInset.js.map +1 -0
- package/dist/core/mixed.js +6 -0
- package/dist/core/mixed.js.map +1 -0
- package/dist/core/ops/arrange.js +31 -0
- package/dist/core/ops/arrange.js.map +1 -0
- package/dist/core/ops/create.js +32 -0
- package/dist/core/ops/create.js.map +1 -0
- package/dist/core/ops/createHistory.js +20 -0
- package/dist/core/ops/createHistory.js.map +1 -0
- package/dist/core/ops/delete.js +89 -0
- package/dist/core/ops/delete.js.map +1 -0
- package/dist/core/ops/registry.js +17 -0
- package/dist/core/ops/registry.js.map +1 -0
- package/dist/core/ops/reorder/algorithms.js +55 -0
- package/dist/core/ops/reorder/algorithms.js.map +1 -0
- package/dist/core/ops/reorder/index.js +140 -0
- package/dist/core/ops/reorder/index.js.map +1 -0
- package/dist/core/ops/reparent.js +52 -0
- package/dist/core/ops/reparent.js.map +1 -0
- package/dist/core/ops/select.js +34 -0
- package/dist/core/ops/select.js.map +1 -0
- package/dist/core/ops/setData.js +34 -0
- package/dist/core/ops/setData.js.map +1 -0
- package/dist/core/ops/setLayer.js +34 -0
- package/dist/core/ops/setLayer.js.map +1 -0
- package/dist/core/ops/setLayout.js +31 -0
- package/dist/core/ops/setLayout.js.map +1 -0
- package/dist/core/ops/setPath.js +57 -0
- package/dist/core/ops/setPath.js.map +1 -0
- package/dist/core/ops/setText.js +34 -0
- package/dist/core/ops/setText.js.map +1 -0
- package/dist/core/ops/slot.js +37 -0
- package/dist/core/ops/slot.js.map +1 -0
- package/dist/core/ops/transform.js +42 -0
- package/dist/core/ops/transform.js.map +1 -0
- package/dist/core/paintKinds.js +156 -0
- package/dist/core/paintKinds.js.map +1 -0
- package/dist/core/scene/NodeProperties.js +20 -0
- package/dist/core/scene/NodeProperties.js.map +1 -0
- package/dist/core/scene/NodeRouting.js +24 -0
- package/dist/core/scene/NodeRouting.js.map +1 -0
- package/dist/core/scene/arrivals.js +12 -0
- package/dist/core/scene/arrivals.js.map +1 -0
- package/dist/core/scene/composeFrame.js +29 -0
- package/dist/core/scene/composeFrame.js.map +1 -0
- package/dist/core/scene/depMemo.js +18 -0
- package/dist/core/scene/depMemo.js.map +1 -0
- package/dist/core/scene/dependents.js +66 -0
- package/dist/core/scene/dependents.js.map +1 -0
- package/dist/core/scene/derivedPath.js +31 -0
- package/dist/core/scene/derivedPath.js.map +1 -0
- package/dist/core/scene/effectivePose.js +78 -0
- package/dist/core/scene/effectivePose.js.map +1 -0
- package/dist/core/scene/kitRegistry.js +33 -0
- package/dist/core/scene/kitRegistry.js.map +1 -0
- package/dist/core/scene/layoutPass.js +96 -0
- package/dist/core/scene/layoutPass.js.map +1 -0
- package/dist/core/scene/nodeFnFields.js +83 -0
- package/dist/core/scene/nodeFnFields.js.map +1 -0
- package/dist/core/scene/nodeMemo.js +28 -0
- package/dist/core/scene/nodeMemo.js.map +1 -0
- package/dist/core/scene/poseFeed.js +87 -0
- package/dist/core/scene/poseFeed.js.map +1 -0
- package/dist/core/scene/poseOverrides.js +52 -0
- package/dist/core/scene/poseOverrides.js.map +1 -0
- package/dist/core/scene/poseSnapshot.js +54 -0
- package/dist/core/scene/poseSnapshot.js.map +1 -0
- package/dist/core/scene/scene.js +1271 -0
- package/dist/core/scene/scene.js.map +1 -0
- package/dist/core/scene/types.js +6 -0
- package/dist/core/scene/types.js.map +1 -0
- package/dist/core/scene/useScene.js +32 -0
- package/dist/core/scene/useScene.js.map +1 -0
- package/dist/core/selection/chromeState.js +31 -0
- package/dist/core/selection/chromeState.js.map +1 -0
- package/dist/core/selection/selectionTarget.js +6 -0
- package/dist/core/selection/selectionTarget.js.map +1 -0
- package/dist/core/selection/useSelection.js +71 -0
- package/dist/core/selection/useSelection.js.map +1 -0
- package/dist/core/shapeKinds.js +54 -0
- package/dist/core/shapeKinds.js.map +1 -0
- package/dist/core/strokeMarkerShapes.js +139 -0
- package/dist/core/strokeMarkerShapes.js.map +1 -0
- package/dist/core/strokeMarkers.js +28 -0
- package/dist/core/strokeMarkers.js.map +1 -0
- package/dist/core/stylus/stylus.js +39 -0
- package/dist/core/stylus/stylus.js.map +1 -0
- package/dist/core/stylus/usePointerStylus.js +51 -0
- package/dist/core/stylus/usePointerStylus.js.map +1 -0
- package/dist/core/usePaintKinds.js +17 -0
- package/dist/core/usePaintKinds.js.map +1 -0
- package/dist/core/viewport/clampView.js +24 -0
- package/dist/core/viewport/clampView.js.map +1 -0
- package/dist/core/viewport/clientToWorld.js +8 -0
- package/dist/core/viewport/clientToWorld.js.map +1 -0
- package/dist/core/viewport/createVelocityTracker.js +39 -0
- package/dist/core/viewport/createVelocityTracker.js.map +1 -0
- package/dist/core/viewport/fitToBounds.js +18 -0
- package/dist/core/viewport/fitToBounds.js.map +1 -0
- package/dist/core/viewport/fitViewToBounds.js +36 -0
- package/dist/core/viewport/fitViewToBounds.js.map +1 -0
- package/dist/core/viewport/interpolateView.js +34 -0
- package/dist/core/viewport/interpolateView.js.map +1 -0
- package/dist/core/viewport/meanScale.js +8 -0
- package/dist/core/viewport/meanScale.js.map +1 -0
- package/dist/core/viewport/parallax.js +111 -0
- package/dist/core/viewport/parallax.js.map +1 -0
- package/dist/core/viewport/pxExtent.js +42 -0
- package/dist/core/viewport/pxExtent.js.map +1 -0
- package/dist/core/viewport/sceneNodeClientRect.js +18 -0
- package/dist/core/viewport/sceneNodeClientRect.js.map +1 -0
- package/dist/core/viewport/screenSlop.js +27 -0
- package/dist/core/viewport/screenSlop.js.map +1 -0
- package/dist/core/viewport/useAutoCenter.js +32 -0
- package/dist/core/viewport/useAutoCenter.js.map +1 -0
- package/dist/core/viewport/useCanvasSize.js +29 -0
- package/dist/core/viewport/useCanvasSize.js.map +1 -0
- package/dist/core/viewport/useDecayLoop.js +63 -0
- package/dist/core/viewport/useDecayLoop.js.map +1 -0
- package/dist/core/viewport/useVelocityTracker.js +10 -0
- package/dist/core/viewport/useVelocityTracker.js.map +1 -0
- package/dist/core/viewport/useViewAnimation.js +63 -0
- package/dist/core/viewport/useViewAnimation.js.map +1 -0
- package/dist/core/viewport/view.js +37 -0
- package/dist/core/viewport/view.js.map +1 -0
- package/dist/core/viewport/viewTransform.js +11 -0
- package/dist/core/viewport/viewTransform.js.map +1 -0
- package/dist/core/viewport/viewportWorldRect.js +13 -0
- package/dist/core/viewport/viewportWorldRect.js.map +1 -0
- package/dist/core/viewport/wheelHandler.js +30 -0
- package/dist/core/viewport/wheelHandler.js.map +1 -0
- package/dist/core/viewport/zoomAt.js +22 -0
- package/dist/core/viewport/zoomAt.js.map +1 -0
- package/dist/core/viewport/zoomBounds.js +20 -0
- package/dist/core/viewport/zoomBounds.js.map +1 -0
- package/dist/{pointSnapToGrid-7mCcm6qG.d.ts → cornerHandles-CDcZOV8h.d.ts} +54 -71
- package/dist/debug/createDebugOverlayLayer.js +358 -0
- package/dist/debug/createDebugOverlayLayer.js.map +1 -0
- package/dist/debug/createDebugSink.js +83 -0
- package/dist/debug/createDebugSink.js.map +1 -0
- package/dist/debug/defaultTheme.js +31 -0
- package/dist/debug/defaultTheme.js.map +1 -0
- package/dist/debug/flag.js +41 -0
- package/dist/debug/flag.js.map +1 -0
- package/dist/debug/frameStats.js +16 -0
- package/dist/debug/frameStats.js.map +1 -0
- package/dist/debug/parseDebugFlags.js +32 -0
- package/dist/debug/parseDebugFlags.js.map +1 -0
- package/dist/features/chrome-caps/buildChromeCtx.js +16 -0
- package/dist/features/chrome-caps/buildChromeCtx.js.map +1 -0
- package/dist/features/chrome-caps/conditions.js +36 -0
- package/dist/features/chrome-caps/conditions.js.map +1 -0
- package/dist/features/chrome-caps/defaults.js +26 -0
- package/dist/features/chrome-caps/defaults.js.map +1 -0
- package/dist/features/chrome-caps/index.js +7 -0
- package/dist/features/chrome-caps/resolve.js +23 -0
- package/dist/features/chrome-caps/resolve.js.map +1 -0
- package/dist/features/chrome-caps/useHoverTracking.js +27 -0
- package/dist/features/chrome-caps/useHoverTracking.js.map +1 -0
- package/dist/features/cursor/paintedCursorLayer.js +60 -0
- package/dist/features/cursor/paintedCursorLayer.js.map +1 -0
- package/dist/features/focus/gateLayer.js +14 -0
- package/dist/features/focus/gateLayer.js.map +1 -0
- package/dist/features/focus/useCanvasFocus.js +29 -0
- package/dist/features/focus/useCanvasFocus.js.map +1 -0
- package/dist/features/groups/children.js +23 -0
- package/dist/features/groups/children.js.map +1 -0
- package/dist/features/groups/composePose.js +67 -0
- package/dist/features/groups/composePose.js.map +1 -0
- package/dist/features/groups/nestedHit.js +40 -0
- package/dist/features/groups/nestedHit.js.map +1 -0
- package/dist/features/groups/unionOfChildren.js +15 -0
- package/dist/features/groups/unionOfChildren.js.map +1 -0
- package/dist/features/images/imageCache.js +94 -0
- package/dist/features/images/imageCache.js.map +1 -0
- package/dist/features/ingestion/contentHandlers.js +37 -0
- package/dist/features/ingestion/contentHandlers.js.map +1 -0
- package/dist/features/ingestion/imageHandler.js +45 -0
- package/dist/features/ingestion/imageHandler.js.map +1 -0
- package/dist/features/ingestion/index.js +8 -0
- package/dist/features/ingestion/openFilePicker.js +15 -0
- package/dist/features/ingestion/openFilePicker.js.map +1 -0
- package/dist/features/ingestion/registerKitHandlers.js +26 -0
- package/dist/features/ingestion/registerKitHandlers.js.map +1 -0
- package/dist/features/ingestion/svgHandler.js +58 -0
- package/dist/features/ingestion/svgHandler.js.map +1 -0
- package/dist/features/ingestion/weaselJsonHandler.js +39 -0
- package/dist/features/ingestion/weaselJsonHandler.js.map +1 -0
- package/dist/features/longPress/longPressFeedback.js +96 -0
- package/dist/features/longPress/longPressFeedback.js.map +1 -0
- package/dist/features/meshPaint/bake.js +79 -0
- package/dist/features/meshPaint/bake.js.map +1 -0
- package/dist/features/meshPaint/bakeCache.js +59 -0
- package/dist/features/meshPaint/bakeCache.js.map +1 -0
- package/dist/features/meshPaint/handles.js +86 -0
- package/dist/features/meshPaint/handles.js.map +1 -0
- package/dist/features/meshPaint/lazyKind.js +1298 -0
- package/dist/features/meshPaint/lazyKind.js.map +1 -0
- package/dist/features/meshPaint/meshPaint.js +236 -0
- package/dist/features/meshPaint/meshPaint.js.map +1 -0
- package/dist/features/meshPaint/meshShader.js +6 -0
- package/dist/features/meshPaint/meshShader.js.map +1 -0
- package/dist/features/meshPaint/register.js +7 -0
- package/dist/features/meshPaint/register.js.map +1 -0
- package/dist/features/meshPaint/surface.js +110 -0
- package/dist/features/meshPaint/surface.js.map +1 -0
- package/dist/features/minimap/actions.js +53 -0
- package/dist/features/minimap/actions.js.map +1 -0
- package/dist/features/minimap/createMinimapContribution.js +96 -0
- package/dist/features/minimap/createMinimapContribution.js.map +1 -0
- package/dist/features/minimap/layers.js +103 -0
- package/dist/features/minimap/layers.js.map +1 -0
- package/dist/features/modes/modeLayers.js +113 -0
- package/dist/features/modes/modeLayers.js.map +1 -0
- package/dist/features/overlays/useNodeOverlayFrame.js +103 -0
- package/dist/features/overlays/useNodeOverlayFrame.js.map +1 -0
- package/dist/features/parallax/createParallaxLayer.js +26 -0
- package/dist/features/parallax/createParallaxLayer.js.map +1 -0
- package/dist/features/parallax/createParallaxPlane.js +26 -0
- package/dist/features/parallax/createParallaxPlane.js.map +1 -0
- package/dist/features/paths/anchorEdits.js +156 -0
- package/dist/features/paths/anchorEdits.js.map +1 -0
- package/dist/features/paths/anchors.js +154 -0
- package/dist/features/paths/anchors.js.map +1 -0
- package/dist/features/paths/booleans.js +2 -0
- package/dist/features/paths/index.js +15 -0
- package/dist/features/paths/markerCommands.js +116 -0
- package/dist/features/paths/markerCommands.js.map +1 -0
- package/dist/features/paths/markerSites.js +59 -0
- package/dist/features/paths/markerSites.js.map +1 -0
- package/dist/features/paths/markers.js +95 -0
- package/dist/features/paths/markers.js.map +1 -0
- package/dist/features/paths/nearestAnchor.js +36 -0
- package/dist/features/paths/nearestAnchor.js.map +1 -0
- package/dist/features/paths/originProjection.js +16 -0
- package/dist/features/paths/originProjection.js.map +1 -0
- package/dist/features/paths/pathEditingOverlayLayer.js +137 -0
- package/dist/features/paths/pathEditingOverlayLayer.js.map +1 -0
- package/dist/features/paths/pathInWorld.js +41 -0
- package/dist/features/paths/pathInWorld.js.map +1 -0
- package/dist/features/paths/pathLayer.js +44 -0
- package/dist/features/paths/pathLayer.js.map +1 -0
- package/dist/features/paths/penPreviewLayer.js +220 -0
- package/dist/features/paths/penPreviewLayer.js.map +1 -0
- package/dist/features/paths/poseDescriptor.js +44 -0
- package/dist/features/paths/poseDescriptor.js.map +1 -0
- package/dist/features/paths/tessellate/stroke.js +230 -0
- package/dist/features/paths/tessellate/stroke.js.map +1 -0
- package/dist/features/patterns/index.js +23 -0
- package/dist/features/patterns/index.js.map +1 -0
- package/dist/features/patterns/patterns-builtin.js +38 -0
- package/dist/features/patterns/patterns-builtin.js.map +1 -0
- package/dist/features/patterns/resolveSpec.js +57 -0
- package/dist/features/patterns/resolveSpec.js.map +1 -0
- package/dist/features/patterns/tileGeometry.js +158 -0
- package/dist/features/patterns/tileGeometry.js.map +1 -0
- package/dist/features/pointer/PointerContext.js +45 -0
- package/dist/features/pointer/PointerContext.js.map +1 -0
- package/dist/features/poseRun/usePoseRun.js +70 -0
- package/dist/features/poseRun/usePoseRun.js.map +1 -0
- package/dist/features/selection/SelectionContext.js +46 -0
- package/dist/features/selection/SelectionContext.js.map +1 -0
- package/dist/features/selection/overlay.js +442 -0
- package/dist/features/selection/overlay.js.map +1 -0
- package/dist/features/simulation/createSimulation.js +61 -0
- package/dist/features/simulation/createSimulation.js.map +1 -0
- package/dist/features/simulation/types.js +6 -0
- package/dist/features/simulation/types.js.map +1 -0
- package/dist/features/simulation/useSimulation.js +74 -0
- package/dist/features/simulation/useSimulation.js.map +1 -0
- package/dist/features/text/domRuns.js +258 -0
- package/dist/features/text/domRuns.js.map +1 -0
- package/dist/features/text/fitTextPose.js +38 -0
- package/dist/features/text/fitTextPose.js.map +1 -0
- package/dist/features/text/hitTest.js +45 -0
- package/dist/features/text/hitTest.js.map +1 -0
- package/dist/features/text/renderLabel.js +14 -0
- package/dist/features/text/renderLabel.js.map +1 -0
- package/dist/features/text/runs/effectiveRangeStyle.js +66 -0
- package/dist/features/text/runs/effectiveRangeStyle.js.map +1 -0
- package/dist/features/text/runs/flagRange.js +53 -0
- package/dist/features/text/runs/flagRange.js.map +1 -0
- package/dist/features/text/runs/rangeStyle.js +135 -0
- package/dist/features/text/runs/rangeStyle.js.map +1 -0
- package/dist/features/text/textCommand.js +59 -0
- package/dist/features/text/textCommand.js.map +1 -0
- package/dist/features/text/textLayer.js +35 -0
- package/dist/features/text/textLayer.js.map +1 -0
- package/dist/features/text/textToPath.js +181 -0
- package/dist/features/text/textToPath.js.map +1 -0
- package/dist/features/text/useSceneTextEdit.js +138 -0
- package/dist/features/text/useSceneTextEdit.js.map +1 -0
- package/dist/features/text/useTextEdit.js +465 -0
- package/dist/features/text/useTextEdit.js.map +1 -0
- package/dist/features/tiling/createTiledLayer.js +63 -0
- package/dist/features/tiling/createTiledLayer.js.map +1 -0
- package/dist/features/tiling/tiledProject.js +14 -0
- package/dist/features/tiling/tiledProject.js.map +1 -0
- package/dist/features/viewports/viewResolver.js +59 -0
- package/dist/features/viewports/viewResolver.js.map +1 -0
- package/dist/features/viewports/viewportLayer.js +58 -0
- package/dist/features/viewports/viewportLayer.js.map +1 -0
- package/dist/icons/ArrowIcon.js +23 -0
- package/dist/icons/ArrowIcon.js.map +1 -0
- package/dist/icons/EllipseIcon.js +21 -0
- package/dist/icons/EllipseIcon.js.map +1 -0
- package/dist/icons/EyedropperIcon.js +49 -0
- package/dist/icons/EyedropperIcon.js.map +1 -0
- package/dist/icons/HandIcon.js +59 -0
- package/dist/icons/HandIcon.js.map +1 -0
- package/dist/icons/ImageIcon.js +34 -0
- package/dist/icons/ImageIcon.js.map +1 -0
- package/dist/icons/LassoIcon.js +22 -0
- package/dist/icons/LassoIcon.js.map +1 -0
- package/dist/icons/LineIcon.js +22 -0
- package/dist/icons/LineIcon.js.map +1 -0
- package/dist/icons/PenIcon.js +36 -0
- package/dist/icons/PenIcon.js.map +1 -0
- package/dist/icons/PencilIcon.js +25 -0
- package/dist/icons/PencilIcon.js.map +1 -0
- package/dist/icons/PolygonIcon.js +19 -0
- package/dist/icons/PolygonIcon.js.map +1 -0
- package/dist/icons/RectIcon.js +37 -0
- package/dist/icons/RectIcon.js.map +1 -0
- package/dist/icons/SelectIcon.js +20 -0
- package/dist/icons/SelectIcon.js.map +1 -0
- package/dist/icons/StarIcon.js +19 -0
- package/dist/icons/StarIcon.js.map +1 -0
- package/dist/icons/TextIcon.js +19 -0
- package/dist/icons/TextIcon.js.map +1 -0
- package/dist/icons/UnknownIcon.js +33 -0
- package/dist/icons/UnknownIcon.js.map +1 -0
- package/dist/icons/_base.js +12 -0
- package/dist/icons/_base.js.map +1 -0
- package/dist/index.css +2 -86
- package/dist/index.d.ts +2349 -2609
- package/dist/index.js +312 -13
- package/dist/input/keyState.js +76 -0
- package/dist/input/keyState.js.map +1 -0
- package/dist/input/useKeyState.js +22 -0
- package/dist/input/useKeyState.js.map +1 -0
- package/dist/interactions/actions/actionShortcuts.js +32 -0
- package/dist/interactions/actions/actionShortcuts.js.map +1 -0
- package/dist/interactions/actions/align/align.js +81 -0
- package/dist/interactions/actions/align/align.js.map +1 -0
- package/dist/interactions/actions/booleans/booleans.js +120 -0
- package/dist/interactions/actions/booleans/booleans.js.map +1 -0
- package/dist/interactions/actions/booleans/useBooleans.js +20 -0
- package/dist/interactions/actions/booleans/useBooleans.js.map +1 -0
- package/dist/interactions/actions/booleans/useBooleansAdapter.js +9 -0
- package/dist/interactions/actions/booleans/useBooleansAdapter.js.map +1 -0
- package/dist/interactions/actions/clipboard/clipboardOps.js +94 -0
- package/dist/interactions/actions/clipboard/clipboardOps.js.map +1 -0
- package/dist/interactions/actions/clipboard/materializePaste.js +25 -0
- package/dist/interactions/actions/clipboard/materializePaste.js.map +1 -0
- package/dist/interactions/actions/clipboard/wireFormat.js +43 -0
- package/dist/interactions/actions/clipboard/wireFormat.js.map +1 -0
- package/dist/interactions/actions/clone/behaviors/cloneByAltDrag.js +26 -0
- package/dist/interactions/actions/clone/behaviors/cloneByAltDrag.js.map +1 -0
- package/dist/interactions/actions/defaultCommitAdapter.js +42 -0
- package/dist/interactions/actions/defaultCommitAdapter.js.map +1 -0
- package/dist/interactions/actions/defaults/align.js +71 -0
- package/dist/interactions/actions/defaults/align.js.map +1 -0
- package/dist/interactions/actions/defaults/anchorEditing.js +235 -0
- package/dist/interactions/actions/defaults/anchorEditing.js.map +1 -0
- package/dist/interactions/actions/defaults/areaSelect.js +75 -0
- package/dist/interactions/actions/defaults/areaSelect.js.map +1 -0
- package/dist/interactions/actions/defaults/booleans.js +52 -0
- package/dist/interactions/actions/defaults/booleans.js.map +1 -0
- package/dist/interactions/actions/defaults/cancelGesture.js +24 -0
- package/dist/interactions/actions/defaults/cancelGesture.js.map +1 -0
- package/dist/interactions/actions/defaults/clearSelection.js +19 -0
- package/dist/interactions/actions/defaults/clearSelection.js.map +1 -0
- package/dist/interactions/actions/defaults/clipboard.js +78 -0
- package/dist/interactions/actions/defaults/clipboard.js.map +1 -0
- package/dist/interactions/actions/defaults/clone.js +96 -0
- package/dist/interactions/actions/defaults/clone.js.map +1 -0
- package/dist/interactions/actions/defaults/createOutlines.js +47 -0
- package/dist/interactions/actions/defaults/createOutlines.js.map +1 -0
- package/dist/interactions/actions/defaults/createPaintAction.js +85 -0
- package/dist/interactions/actions/defaults/createPaintAction.js.map +1 -0
- package/dist/interactions/actions/defaults/delete.js +61 -0
- package/dist/interactions/actions/defaults/delete.js.map +1 -0
- package/dist/interactions/actions/defaults/distribute.js +66 -0
- package/dist/interactions/actions/defaults/distribute.js.map +1 -0
- package/dist/interactions/actions/defaults/duplicate.js +83 -0
- package/dist/interactions/actions/defaults/duplicate.js.map +1 -0
- package/dist/interactions/actions/defaults/editAnchors.js +100 -0
- package/dist/interactions/actions/defaults/editAnchors.js.map +1 -0
- package/dist/interactions/actions/defaults/enterPathEdit.js +29 -0
- package/dist/interactions/actions/defaults/enterPathEdit.js.map +1 -0
- package/dist/interactions/actions/defaults/enterTextEdit.js +20 -0
- package/dist/interactions/actions/defaults/enterTextEdit.js.map +1 -0
- package/dist/interactions/actions/defaults/escape.js +26 -0
- package/dist/interactions/actions/defaults/escape.js.map +1 -0
- package/dist/interactions/actions/defaults/exitPathEdit.js +22 -0
- package/dist/interactions/actions/defaults/exitPathEdit.js.map +1 -0
- package/dist/interactions/actions/defaults/flip.js +119 -0
- package/dist/interactions/actions/defaults/flip.js.map +1 -0
- package/dist/interactions/actions/defaults/freshNodeId.js +10 -0
- package/dist/interactions/actions/defaults/freshNodeId.js.map +1 -0
- package/dist/interactions/actions/defaults/group.js +131 -0
- package/dist/interactions/actions/defaults/group.js.map +1 -0
- package/dist/interactions/actions/defaults/icons/actionGlyphIcons.js +40 -0
- package/dist/interactions/actions/defaults/icons/actionGlyphIcons.js.map +1 -0
- package/dist/interactions/actions/defaults/icons/actionGlyphs.js +10 -0
- package/dist/interactions/actions/defaults/icons/actionGlyphs.js.map +1 -0
- package/dist/interactions/actions/defaults/icons/alignIcons.js +173 -0
- package/dist/interactions/actions/defaults/icons/alignIcons.js.map +1 -0
- package/dist/interactions/actions/defaults/icons/booleanIcons.js +171 -0
- package/dist/interactions/actions/defaults/icons/booleanIcons.js.map +1 -0
- package/dist/interactions/actions/defaults/icons/distributeIcons.js +63 -0
- package/dist/interactions/actions/defaults/icons/distributeIcons.js.map +1 -0
- package/dist/interactions/actions/defaults/icons/editIcons.js +280 -0
- package/dist/interactions/actions/defaults/icons/editIcons.js.map +1 -0
- package/dist/interactions/actions/defaults/icons/outlineIcons.js +53 -0
- package/dist/interactions/actions/defaults/icons/outlineIcons.js.map +1 -0
- package/dist/interactions/actions/defaults/ingest.js +58 -0
- package/dist/interactions/actions/defaults/ingest.js.map +1 -0
- package/dist/interactions/actions/defaults/insert.js +288 -0
- package/dist/interactions/actions/defaults/insert.js.map +1 -0
- package/dist/interactions/actions/defaults/insertPathAnchor.js +50 -0
- package/dist/interactions/actions/defaults/insertPathAnchor.js.map +1 -0
- package/dist/interactions/actions/defaults/lassoSelect.js +156 -0
- package/dist/interactions/actions/defaults/lassoSelect.js.map +1 -0
- package/dist/interactions/actions/defaults/move.js +656 -0
- package/dist/interactions/actions/defaults/move.js.map +1 -0
- package/dist/interactions/actions/defaults/nudge.js +110 -0
- package/dist/interactions/actions/defaults/nudge.js.map +1 -0
- package/dist/interactions/actions/defaults/pinchZoom.js +63 -0
- package/dist/interactions/actions/defaults/pinchZoom.js.map +1 -0
- package/dist/interactions/actions/defaults/reorder.js +143 -0
- package/dist/interactions/actions/defaults/reorder.js.map +1 -0
- package/dist/interactions/actions/defaults/requiresSelection.js +10 -0
- package/dist/interactions/actions/defaults/requiresSelection.js.map +1 -0
- package/dist/interactions/actions/defaults/resize.js +332 -0
- package/dist/interactions/actions/defaults/resize.js.map +1 -0
- package/dist/interactions/actions/defaults/rotate.js +181 -0
- package/dist/interactions/actions/defaults/rotate.js.map +1 -0
- package/dist/interactions/actions/defaults/selectAll.js +27 -0
- package/dist/interactions/actions/defaults/selectAll.js.map +1 -0
- package/dist/interactions/actions/defaults/setFill.js +27 -0
- package/dist/interactions/actions/defaults/setFill.js.map +1 -0
- package/dist/interactions/actions/defaults/setFillOpacity.js +15 -0
- package/dist/interactions/actions/defaults/setFillOpacity.js.map +1 -0
- package/dist/interactions/actions/defaults/setStroke.js +36 -0
- package/dist/interactions/actions/defaults/setStroke.js.map +1 -0
- package/dist/interactions/actions/defaults/setStrokeOpacity.js +21 -0
- package/dist/interactions/actions/defaults/setStrokeOpacity.js.map +1 -0
- package/dist/interactions/actions/defaults/slice.js +39 -0
- package/dist/interactions/actions/defaults/slice.js.map +1 -0
- package/dist/interactions/actions/defaults/sliceOps.js +60 -0
- package/dist/interactions/actions/defaults/sliceOps.js.map +1 -0
- package/dist/interactions/actions/defaults/toolActivate.js +35 -0
- package/dist/interactions/actions/defaults/toolActivate.js.map +1 -0
- package/dist/interactions/actions/defaults/toolResetToDefault.js +26 -0
- package/dist/interactions/actions/defaults/toolResetToDefault.js.map +1 -0
- package/dist/interactions/actions/defaults/undoRedo.js +51 -0
- package/dist/interactions/actions/defaults/undoRedo.js.map +1 -0
- package/dist/interactions/actions/defaults/viewportDragPan.js +88 -0
- package/dist/interactions/actions/defaults/viewportDragPan.js.map +1 -0
- package/dist/interactions/actions/defaults/viewportWheelPan.js +57 -0
- package/dist/interactions/actions/defaults/viewportWheelPan.js.map +1 -0
- package/dist/interactions/actions/defaults/viewportZoom.js +143 -0
- package/dist/interactions/actions/defaults/viewportZoom.js.map +1 -0
- package/dist/interactions/actions/distribute/distribute.js +42 -0
- package/dist/interactions/actions/distribute/distribute.js.map +1 -0
- package/dist/interactions/actions/distribute/plan.js +29 -0
- package/dist/interactions/actions/distribute/plan.js.map +1 -0
- package/dist/interactions/actions/edit-anchors/geometry.js +61 -0
- package/dist/interactions/actions/edit-anchors/geometry.js.map +1 -0
- package/dist/interactions/actions/edit-anchors/handles.js +43 -0
- package/dist/interactions/actions/edit-anchors/handles.js.map +1 -0
- package/dist/interactions/actions/flip/helpers.js +35 -0
- package/dist/interactions/actions/flip/helpers.js.map +1 -0
- package/dist/interactions/actions/geometryProjection.js +18 -0
- package/dist/interactions/actions/geometryProjection.js.map +1 -0
- package/dist/interactions/actions/gestureLifecycle.js +44 -0
- package/dist/interactions/actions/gestureLifecycle.js.map +1 -0
- package/dist/interactions/actions/lasso-select/behaviors/selectFromLasso.js +39 -0
- package/dist/interactions/actions/lasso-select/behaviors/selectFromLasso.js.map +1 -0
- package/dist/interactions/actions/move/behaviors/snapBackOrDelete.js +36 -0
- package/dist/interactions/actions/move/behaviors/snapBackOrDelete.js.map +1 -0
- package/dist/interactions/actions/move/behaviors/snapToContainer.js +67 -0
- package/dist/interactions/actions/move/behaviors/snapToContainer.js.map +1 -0
- package/dist/interactions/actions/move/gestureAdapter.js +37 -0
- package/dist/interactions/actions/move/gestureAdapter.js.map +1 -0
- package/dist/interactions/actions/outlines/createOutlines.js +84 -0
- package/dist/interactions/actions/outlines/createOutlines.js.map +1 -0
- package/dist/interactions/actions/outlines/useCreateOutlinesAdapter.js +9 -0
- package/dist/interactions/actions/outlines/useCreateOutlinesAdapter.js.map +1 -0
- package/dist/interactions/actions/planeInput.js +168 -0
- package/dist/interactions/actions/planeInput.js.map +1 -0
- package/dist/interactions/actions/poseDescriptorDep.js +9 -0
- package/dist/interactions/actions/poseDescriptorDep.js.map +1 -0
- package/dist/interactions/actions/poseFrame.js +38 -0
- package/dist/interactions/actions/poseFrame.js.map +1 -0
- package/dist/interactions/actions/previewOverrides.js +25 -0
- package/dist/interactions/actions/previewOverrides.js.map +1 -0
- package/dist/interactions/actions/resize/autoPoseDescriptor.js +32 -0
- package/dist/interactions/actions/resize/autoPoseDescriptor.js.map +1 -0
- package/dist/interactions/actions/resize/behaviors/clampMinSize.js +18 -0
- package/dist/interactions/actions/resize/behaviors/clampMinSize.js.map +1 -0
- package/dist/interactions/actions/resize/behaviors/index.js +8 -0
- package/dist/interactions/actions/resize/behaviors/index.js.map +1 -0
- package/dist/interactions/actions/resize/behaviors/lockAspect.js +24 -0
- package/dist/interactions/actions/resize/behaviors/lockAspect.js.map +1 -0
- package/dist/interactions/actions/resize/cornerHandles.js +72 -0
- package/dist/interactions/actions/resize/cornerHandles.js.map +1 -0
- package/dist/interactions/actions/resolveOverlays.js +60 -0
- package/dist/interactions/actions/resolveOverlays.js.map +1 -0
- package/dist/interactions/actions/resolvePreviews.js +61 -0
- package/dist/interactions/actions/resolvePreviews.js.map +1 -0
- package/dist/interactions/actions/rotate/geometry.js +46 -0
- package/dist/interactions/actions/rotate/geometry.js.map +1 -0
- package/dist/interactions/actions/rotate/handle.js +27 -0
- package/dist/interactions/actions/rotate/handle.js.map +1 -0
- package/dist/interactions/actions/spatialReference.js +42 -0
- package/dist/interactions/actions/spatialReference.js.map +1 -0
- package/dist/interactions/actions/useStandardActions.js +142 -0
- package/dist/interactions/actions/useStandardActions.js.map +1 -0
- package/dist/interactions/gestures/dragGesture/dragGesture.js +111 -0
- package/dist/interactions/gestures/dragGesture/dragGesture.js.map +1 -0
- package/dist/interactions/gestures/dragRadial/dragRadial.js +117 -0
- package/dist/interactions/gestures/dragRadial/dragRadial.js.map +1 -0
- package/dist/interactions/gestures/dragRect/dragRect.js +164 -0
- package/dist/interactions/gestures/dragRect/dragRect.js.map +1 -0
- package/dist/interactions/gestures/handleDrag/handleDrag.js +46 -0
- package/dist/interactions/gestures/handleDrag/handleDrag.js.map +1 -0
- package/dist/interactions/gestures/pointerDrag/pointerDrag.js +118 -0
- package/dist/interactions/gestures/pointerDrag/pointerDrag.js.map +1 -0
- package/dist/interactions/gestures/shared/originProjection.js +42 -0
- package/dist/interactions/gestures/shared/originProjection.js.map +1 -0
- package/dist/interactions/gestures/shared/screenTolerance.js +21 -0
- package/dist/interactions/gestures/shared/screenTolerance.js.map +1 -0
- package/dist/interactions/gestures/shared/snap.js +24 -0
- package/dist/interactions/gestures/shared/snap.js.map +1 -0
- package/dist/interactions/gestures/thresholdDrag/thresholdDrag.js +30 -0
- package/dist/interactions/gestures/thresholdDrag/thresholdDrag.js.map +1 -0
- package/dist/layout/arrivals.js +36 -0
- package/dist/layout/arrivals.js.map +1 -0
- package/dist/{math-MCQcf_gc.d.ts → math-CUMxmZzn.d.ts} +8 -116
- package/dist/math.d.ts +4 -5
- package/dist/math.js +6 -4
- package/dist/mesh.d.ts +268 -0
- package/dist/mesh.js +7 -0
- package/dist/move.d.ts +7 -48
- package/dist/move.js +3 -142
- package/dist/originProjection-BSn4xiEy.d.ts +57 -0
- package/dist/patterns-builtin.js +3 -3
- package/dist/{poseDescriptor-rZa9W5hJ.d.ts → poseDescriptor-CjSXMf8X.d.ts} +3 -3
- package/dist/registerProgram-ateHDGjw.d.ts +193 -0
- package/dist/renderer/DrawCommand.js +6 -0
- package/dist/renderer/DrawCommand.js.map +1 -0
- package/dist/renderer/WeaselRenderer.js +328 -0
- package/dist/renderer/WeaselRenderer.js.map +1 -0
- package/dist/renderer/cache/GLImageCache.js +64 -0
- package/dist/renderer/cache/GLImageCache.js.map +1 -0
- package/dist/renderer/cache/GLMeshCache.js +102 -0
- package/dist/renderer/cache/GLMeshCache.js.map +1 -0
- package/dist/renderer/cache/GLTextureCache.js +51 -0
- package/dist/renderer/cache/GLTextureCache.js.map +1 -0
- package/dist/renderer/cache/GradientRampAtlas.js +82 -0
- package/dist/renderer/cache/GradientRampAtlas.js.map +1 -0
- package/dist/renderer/cache/cache.js +13 -0
- package/dist/renderer/cache/cache.js.map +1 -0
- package/dist/renderer/cache/markerCommandCache.js +59 -0
- package/dist/renderer/cache/markerCommandCache.js.map +1 -0
- package/dist/renderer/cache/outlineMeshCache.js +15 -0
- package/dist/renderer/cache/outlineMeshCache.js.map +1 -0
- package/dist/renderer/cache/outlineStrokeMeshCache.js +31 -0
- package/dist/renderer/cache/outlineStrokeMeshCache.js.map +1 -0
- package/dist/renderer/cache/strokeMeshCache.js +44 -0
- package/dist/renderer/cache/strokeMeshCache.js.map +1 -0
- package/dist/renderer/cullDrawCommands.js +89 -0
- package/dist/renderer/cullDrawCommands.js.map +1 -0
- package/dist/renderer/draw.js +1109 -0
- package/dist/renderer/draw.js.map +1 -0
- package/dist/renderer/drawBatch.js +168 -0
- package/dist/renderer/drawBatch.js.map +1 -0
- package/dist/renderer/effects/EffectTargets.js +45 -0
- package/dist/renderer/effects/EffectTargets.js.map +1 -0
- package/dist/renderer/effects/builtins.js +31 -0
- package/dist/renderer/effects/builtins.js.map +1 -0
- package/dist/renderer/effects/composite.js +9 -0
- package/dist/renderer/effects/composite.js.map +1 -0
- package/dist/renderer/effects/effectPrelude.js +10 -0
- package/dist/renderer/effects/effectPrelude.js.map +1 -0
- package/dist/renderer/effects/types.js +10 -0
- package/dist/renderer/effects/types.js.map +1 -0
- package/dist/renderer/index.js +19 -0
- package/dist/renderer/math/color.js +341 -0
- package/dist/renderer/math/color.js.map +1 -0
- package/dist/renderer/math/mat3.js +71 -0
- package/dist/renderer/math/mat3.js.map +1 -0
- package/dist/renderer/math/patternSpace.js +22 -0
- package/dist/renderer/math/patternSpace.js.map +1 -0
- package/dist/renderer/math/viewToMat3.js +19 -0
- package/dist/renderer/math/viewToMat3.js.map +1 -0
- package/dist/renderer/paintResources.js +18 -0
- package/dist/renderer/paintResources.js.map +1 -0
- package/dist/renderer/paintScratch.js +37 -0
- package/dist/renderer/paintScratch.js.map +1 -0
- package/dist/renderer/shaders/ShaderProgram.js +74 -0
- package/dist/renderer/shaders/ShaderProgram.js.map +1 -0
- package/dist/renderer/shaders/batchFill.js +118 -0
- package/dist/renderer/shaders/batchFill.js.map +1 -0
- package/dist/renderer/shaders/customPrelude.js +34 -0
- package/dist/renderer/shaders/customPrelude.js.map +1 -0
- package/dist/renderer/shaders/extractUniformNames.js +184 -0
- package/dist/renderer/shaders/extractUniformNames.js.map +1 -0
- package/dist/renderer/shaders/glyphPaint.js +61 -0
- package/dist/renderer/shaders/glyphPaint.js.map +1 -0
- package/dist/renderer/shaders/gradFill.js +30 -0
- package/dist/renderer/shaders/gradFill.js.map +1 -0
- package/dist/renderer/shaders/imageFill.js +14 -0
- package/dist/renderer/shaders/imageFill.js.map +1 -0
- package/dist/renderer/shaders/pathFill.js +13 -0
- package/dist/renderer/shaders/pathFill.js.map +1 -0
- package/dist/renderer/shaders/patternFill.js +24 -0
- package/dist/renderer/shaders/patternFill.js.map +1 -0
- package/dist/renderer/shaders/registerProgram.js +18 -0
- package/dist/renderer/shaders/registerProgram.js.map +1 -0
- package/dist/renderer/spriteSheet.js +14 -0
- package/dist/renderer/spriteSheet.js.map +1 -0
- package/dist/renderer/state/GroupState.js +77 -0
- package/dist/renderer/state/GroupState.js.map +1 -0
- package/dist/renderer/syntheticItalic.js +6 -0
- package/dist/renderer/syntheticItalic.js.map +1 -0
- package/dist/renderer/textures/registerTexture.js +14 -0
- package/dist/renderer/textures/registerTexture.js.map +1 -0
- package/dist/renderer.d.ts +18 -20
- package/dist/renderer.js +18 -13
- package/dist/resize.d.ts +10 -46
- package/dist/resize.js +7 -5
- package/dist/routing.d.ts +1 -1
- package/dist/routing.js +2 -3
- package/dist/scheduling/useVisibleRaf.js +69 -0
- package/dist/scheduling/useVisibleRaf.js.map +1 -0
- package/dist/test-hook/createTestHook.js +39 -0
- package/dist/test-hook/createTestHook.js.map +1 -0
- package/dist/test-hook/install.js +12 -0
- package/dist/test-hook/install.js.map +1 -0
- package/dist/test-seams-fYf6m5pu.d.ts +356 -0
- package/dist/test-seams.d.ts +6 -0
- package/dist/test-seams.js +3 -0
- package/dist/tools/builtin/ellipse/useEllipseTool.js +33 -0
- package/dist/tools/builtin/ellipse/useEllipseTool.js.map +1 -0
- package/dist/tools/builtin/eyedropper/useEyedropperTool.js +55 -0
- package/dist/tools/builtin/eyedropper/useEyedropperTool.js.map +1 -0
- package/dist/tools/builtin/hand/dragPanContribution.js +17 -0
- package/dist/tools/builtin/hand/dragPanContribution.js.map +1 -0
- package/dist/tools/builtin/hand/useHandTool.js +31 -0
- package/dist/tools/builtin/hand/useHandTool.js.map +1 -0
- package/dist/tools/builtin/image/useImageTool.js +41 -0
- package/dist/tools/builtin/image/useImageTool.js.map +1 -0
- package/dist/tools/builtin/lasso/useLassoTool.js +42 -0
- package/dist/tools/builtin/lasso/useLassoTool.js.map +1 -0
- package/dist/tools/builtin/line/useLineTool.js +33 -0
- package/dist/tools/builtin/line/useLineTool.js.map +1 -0
- package/dist/tools/builtin/pen/usePenTool.js +414 -0
- package/dist/tools/builtin/pen/usePenTool.js.map +1 -0
- package/dist/tools/builtin/pencil/usePencilTool.js +36 -0
- package/dist/tools/builtin/pencil/usePencilTool.js.map +1 -0
- package/dist/tools/builtin/pickTopMostHit.js +45 -0
- package/dist/tools/builtin/pickTopMostHit.js.map +1 -0
- package/dist/tools/builtin/polygon/usePolygonTool.js +81 -0
- package/dist/tools/builtin/polygon/usePolygonTool.js.map +1 -0
- package/dist/tools/builtin/rect/useRectTool.js +32 -0
- package/dist/tools/builtin/rect/useRectTool.js.map +1 -0
- package/dist/tools/builtin/select/selectionContributions.js +109 -0
- package/dist/tools/builtin/select/selectionContributions.js.map +1 -0
- package/dist/tools/builtin/select/useSelectTool.js +162 -0
- package/dist/tools/builtin/select/useSelectTool.js.map +1 -0
- package/dist/tools/builtin/shared/insertToolOptions.js +8 -0
- package/dist/tools/builtin/shared/insertToolOptions.js.map +1 -0
- package/dist/tools/builtin/slice/useSliceTool.js +263 -0
- package/dist/tools/builtin/slice/useSliceTool.js.map +1 -0
- package/dist/tools/builtin/star/useStarTool.js +82 -0
- package/dist/tools/builtin/star/useStarTool.js.map +1 -0
- package/dist/tools/builtin/text/useTextTool.js +177 -0
- package/dist/tools/builtin/text/useTextTool.js.map +1 -0
- package/dist/tools/overlayBinding.js +8 -0
- package/dist/tools/overlayBinding.js.map +1 -0
- package/dist/tools/prefs.js +47 -0
- package/dist/tools/prefs.js.map +1 -0
- package/dist/tools/useKeybindings.js +66 -0
- package/dist/tools/useKeybindings.js.map +1 -0
- package/dist/{types-CxC8P6W0.d.ts → types-CA54-mAZ.d.ts} +188 -17
- package/dist/{types-D_74YlWs.d.ts → types-DSjd6W3n.d.ts} +35 -12
- package/dist/util/color.js +26 -0
- package/dist/util/color.js.map +1 -0
- package/dist/util/constrainTo45.js +17 -0
- package/dist/util/constrainTo45.js.map +1 -0
- package/dist/util/paint.js +72 -0
- package/dist/util/paint.js.map +1 -0
- package/dist/version.js +6 -0
- package/dist/version.js.map +1 -0
- package/package.json +31 -18
- package/dist/chunk-44EWMJV2.js +0 -128
- package/dist/chunk-44EWMJV2.js.map +0 -1
- package/dist/chunk-4RJP2N2L.js +0 -143
- package/dist/chunk-4RJP2N2L.js.map +0 -1
- package/dist/chunk-BJN5ZRIJ.js +0 -167
- package/dist/chunk-BJN5ZRIJ.js.map +0 -1
- package/dist/chunk-D4AAWR64.js +0 -28
- package/dist/chunk-D4AAWR64.js.map +0 -1
- package/dist/chunk-DOBSZOPR.js +0 -29
- package/dist/chunk-DOBSZOPR.js.map +0 -1
- package/dist/chunk-H6N2JSZ3.js +0 -248
- package/dist/chunk-H6N2JSZ3.js.map +0 -1
- package/dist/chunk-HPFJUUTF.js +0 -167
- package/dist/chunk-HPFJUUTF.js.map +0 -1
- package/dist/chunk-L5YNZYEG.js +0 -648
- package/dist/chunk-L5YNZYEG.js.map +0 -1
- package/dist/chunk-MZAIDI6D.js +0 -32492
- package/dist/chunk-MZAIDI6D.js.map +0 -1
- package/dist/chunk-PNNZSYRD.js +0 -318
- package/dist/chunk-PNNZSYRD.js.map +0 -1
- package/dist/chunk-RMR4QMM6.js +0 -250
- package/dist/chunk-RMR4QMM6.js.map +0 -1
- package/dist/clipboard.js.map +0 -1
- package/dist/clone.js.map +0 -1
- package/dist/grid-BXdz8GF2.d.ts +0 -158
- package/dist/index.css.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/insert.d.ts +0 -37
- package/dist/insert.js +0 -81
- package/dist/insert.js.map +0 -1
- package/dist/math.js.map +0 -1
- package/dist/move.js.map +0 -1
- package/dist/options-CzjxFoYZ.d.ts +0 -67
- package/dist/path-JEV2c5If.d.ts +0 -48
- package/dist/patterns-builtin.js.map +0 -1
- package/dist/renderer.css +0 -86
- package/dist/renderer.css.map +0 -1
- package/dist/renderer.js.map +0 -1
- package/dist/resize.js.map +0 -1
- package/dist/routing.js.map +0 -1
- package/dist/types-D2tTKEU0.d.ts +0 -18
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"children.js","names":["createChildrenLayer","opts","getChildren","ids","out","id","sub","data","view","cmd"],"sources":["../../../src/features/groups/children.ts"],"sourcesContent":["/**\n * Z-ordered child renderer — replaces the manual `for (id of getChildren()) ...`\n * pattern with a `RenderLayer` factory that consumes an `OrderedAdapter`.\n *\n * Children are drawn in z-order (forward iteration: index 0 = bottom). The\n * caller supplies a `drawChild` callback that emits `DrawCommand[]` for one\n * object; this layer is the boilerplate-free way to plug a scene graph's\n * z-order into the layer composition system.\n *\n * If the adapter doesn't implement `getChildren` (it's optional on\n * `OrderedAdapter`), the layer is a silent no-op — adopt z-order incrementally\n * without breaking existing layers.\n */\n\nimport type { DrawCommand } from '../../renderer';\nimport type { RenderLayer } from 'core/layers/render';\nimport type { View } from 'core/viewport/view';\nimport type { OrderedAdapter } from 'core/adapters/types';\n\n/** Options for `createChildrenLayer`. */\nexport interface CreateChildrenLayerOpts<TData> {\n /** Layer id for the visibility/order map. Default `'children'`. */\n id?: string;\n /** Human-readable label. Default `'Children'`. */\n label?: string;\n /** Source of `getChildren`. Only the read side is used. */\n adapter: Pick<OrderedAdapter, 'getChildren'>;\n /** Parent id (null = root). Function form lets the layer follow a moving\n * selection or focus. Default `null`. */\n parentId?: string | null | (() => string | null);\n /** Draw one child. Called once per id in z-order (bottom → top). The\n * per-child outputs are concatenated into the layer's `DrawCommand[]`. */\n drawChild(id: string, data: TData, view: View): DrawCommand[];\n /** Forwarded to the produced `RenderLayer`. */\n defaultVisible?: boolean;\n /** Forwarded to the produced `RenderLayer`. */\n alwaysOn?: boolean;\n}\n\n/** Build a `RenderLayer` that draws an `OrderedAdapter`'s children in z-order. */\nexport function createChildrenLayer<TData = unknown>(\n opts: CreateChildrenLayerOpts<TData>,\n): RenderLayer<TData> {\n return {\n id: opts.id ?? 'children',\n label: opts.label ?? 'Children',\n defaultVisible: opts.defaultVisible,\n alwaysOn: opts.alwaysOn,\n draw: (data, view) => {\n const getChildren = opts.adapter.getChildren;\n if (!getChildren) return [];\n const parent =\n typeof opts.parentId === 'function'\n ? opts.parentId()\n : opts.parentId ?? null;\n const ids = getChildren(parent);\n const out: DrawCommand[] = [];\n for (const id of ids) {\n const sub = opts.drawChild(id, data, view);\n for (const cmd of sub) out.push(cmd);\n }\n return out;\n },\n };\n}\n"],"mappings":";AAwCA,SAAgBA,EACd,GACoB;CACpB,OAAO;EACL,IAAIC,EAAK,MAAM;EACf,OAAOA,EAAK,SAAS;EACrB,gBAAgBA,EAAK;EACrB,UAAUA,EAAK;EACf,OAAO,GAAM,MAAS;GACpB,IAAMC,IAAcD,EAAK,QAAQ;GACjC,IAAI,CAACC,GAAa,OAAO,CAAC;GAK1B,IAAMC,IAAMD,EAHV,OAAOD,EAAK,YAAa,aACrBA,EAAK,SAAS,IACdA,EAAK,YAAY,IACO,GACxBG,IAAqB,CAAC;GAC5B,KAAK,IAAMC,KAAMF,GAAK;IACpB,IAAMG,IAAML,EAAK,UAAUI,GAAIE,GAAMC,CAAI;IACzC,KAAK,IAAMC,KAAOH,GAAK,EAAI,KAAKG,CAAG;GACrC;GACA,OAAOL;EACT;CACF;AACF"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { IDENTITY_POSE_COMPOSITION as e, composeWorldPose as t, frameAtOrAbove as n, rebaseLocalPose as r } from "../../core/scene/composeFrame.js";
|
|
2
|
+
//#region src/features/groups/composePose.ts
|
|
3
|
+
function i(e, t) {
|
|
4
|
+
return {
|
|
5
|
+
...t,
|
|
6
|
+
x: e.x + t.x,
|
|
7
|
+
y: e.y + t.y
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
function a(e, t, n) {
|
|
11
|
+
return {
|
|
12
|
+
...e,
|
|
13
|
+
x: e.x + t,
|
|
14
|
+
y: e.y + n
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
function o(e, t) {
|
|
18
|
+
return {
|
|
19
|
+
...t,
|
|
20
|
+
x: t.x - e.x,
|
|
21
|
+
y: t.y - e.y
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
function s(e, t, n, r, i) {
|
|
25
|
+
let a = Math.cos(n), o = Math.sin(n);
|
|
26
|
+
return [e + (r - e) * a - (i - t) * o, t + (r - e) * o + (i - t) * a];
|
|
27
|
+
}
|
|
28
|
+
function c(e, t) {
|
|
29
|
+
let n = e.rotation ?? 0, [r, i] = s(e.x + e.width / 2, e.y + e.height / 2, n, e.x + t.x + t.width / 2, e.y + t.y + t.height / 2);
|
|
30
|
+
return {
|
|
31
|
+
...t,
|
|
32
|
+
x: r - t.width / 2,
|
|
33
|
+
y: i - t.height / 2,
|
|
34
|
+
rotation: (t.rotation ?? 0) + n
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
function l(e, t) {
|
|
38
|
+
let n = e.rotation ?? 0, [r, i] = s(e.x + e.width / 2, e.y + e.height / 2, -n, t.x + t.width / 2, t.y + t.height / 2);
|
|
39
|
+
return {
|
|
40
|
+
...t,
|
|
41
|
+
x: r - e.x - t.width / 2,
|
|
42
|
+
y: i - e.y - t.height / 2,
|
|
43
|
+
rotation: (t.rotation ?? 0) - n
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
var u = {
|
|
47
|
+
compose: i,
|
|
48
|
+
decompose: o,
|
|
49
|
+
closure: "translation"
|
|
50
|
+
}, d = {
|
|
51
|
+
compose: c,
|
|
52
|
+
decompose: l,
|
|
53
|
+
closure: "rigid"
|
|
54
|
+
};
|
|
55
|
+
function f(e, n) {
|
|
56
|
+
return (r) => {
|
|
57
|
+
try {
|
|
58
|
+
return t(e, r, n);
|
|
59
|
+
} catch {
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
//#endregion
|
|
65
|
+
export { e as IDENTITY_POSE_COMPOSITION, u as RECT_POSE_COMPOSITION, d as RIGID_POSE_COMPOSITION, i as composeRectPose, c as composeRigidPose, t as composeWorldPose, o as decomposeRectPose, l as decomposeRigidPose, n as frameAtOrAbove, r as rebaseLocalPose, a as translateRectPose, f as worldPoseLookup };
|
|
66
|
+
|
|
67
|
+
//# sourceMappingURL=composePose.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"composePose.js","names":["composeRectPose","child","parent","translateRectPose","pose","dx","dy","decomposeRectPose","world","turn","c","r","s","cx","x","y","cy","composeRigidPose","pr","wcx","wcy","decomposeRigidPose","ux","uy","RECT_POSE_COMPOSITION","RIGID_POSE_COMPOSITION","worldPoseLookup","composeWorldPose","adapter","id","compose","IDENTITY_POSE_COMPOSITION","frameAtOrAbove","rebaseLocalPose"],"sources":["../../../src/features/groups/composePose.ts"],"sourcesContent":["/**\n * Pose composition for hierarchical scene graphs.\n *\n * As of the nesting change, `getPose(id)` on adapters returns the\n * **local** pose — relative to the object's direct parent. Anything in the\n * kit that needs to draw, hit-test, snap, or otherwise reason about world\n * coordinates routes through `composeWorldPose`, which walks the parent\n * chain and folds local poses together via a consumer-supplied `compose`.\n *\n * Pose shape is generic, so the compose strategy is too. For the common\n * `{x, y, width, height}` axis-aligned rect, use `composeRectPose` —\n * translation only, child dimensions preserved. Custom pose shapes (paths,\n * matrix transforms) supply their own.\n *\n * The inverse — `rebaseLocalPose` — converts a world-space pose into a\n * local pose under a target parent. Used when reparenting so the visual\n * world position of a child is preserved across the parent change.\n */\n\n/** Re-exported; the declaration lives in `core/scene/types.ts`, which names\n * it and may not import from features. */\nimport type { RectPose } from 'core/scene/types';\nexport type { RectPose };\n\n/** Re-exported from `core/scene/composeFrame.ts`, for the same reason. */\nimport {\n IDENTITY_POSE_COMPOSITION,\n composeWorldPose,\n frameAtOrAbove,\n rebaseLocalPose,\n type PoseAdapter,\n type PoseClosure,\n type PoseComposition,\n} from 'core/scene/composeFrame';\nexport { IDENTITY_POSE_COMPOSITION, composeWorldPose, frameAtOrAbove, rebaseLocalPose };\nexport type { PoseAdapter, PoseClosure, PoseComposition };\n\n/**\n * Default `compose` for axis-aligned rectangles. Adds translation; preserves\n * child width/height. Treat as the canonical compose for any\n * `{x, y, width, height}` pose under a translation-only hierarchy.\n *\n * Generic over the concrete pose type so callers with a wider pose\n * (e.g. `RectPose & { rotation }`) can pass it through; the extra fields\n * are taken from the child unchanged.\n */\nexport function composeRectPose<TPose extends RectPose>(parent: TPose, child: TPose): TPose {\n return {\n ...child,\n x: parent.x + child.x,\n y: parent.y + child.y,\n };\n}\n\n/**\n * Translate a `RectPose`-shaped pose by `(dx, dy)`. Suitable as the default\n * `translatePose` for `useMove` when poses carry top-level `x`/`y`. Other\n * fields (width/height, plus any extra props on `TPose`) are preserved.\n */\nexport function translateRectPose<TPose extends RectPose>(pose: TPose, dx: number, dy: number): TPose {\n return { ...pose, x: pose.x + dx, y: pose.y + dy };\n}\n\n/** Inverse of `composeRectPose` — subtracts parent translation. */\nexport function decomposeRectPose<TPose extends RectPose>(parent: TPose, world: TPose): TPose {\n return {\n ...world,\n x: world.x - parent.x,\n y: world.y - parent.y,\n };\n}\n\n/** Turn `(x, y)` about `(cx, cy)` by `r` radians. */\nfunction turn(cx: number, cy: number, r: number, x: number, y: number): [number, number] {\n const c = Math.cos(r);\n const s = Math.sin(r);\n return [cx + (x - cx) * c - (y - cy) * s, cy + (x - cx) * s + (y - cy) * c];\n}\n\n/**\n * `compose` for a container whose pose defines a **frame**: the child's local\n * pose is offset into the parent's unrotated box, then the whole thing is\n * turned about the parent's center. Rotations add; the child keeps its size.\n *\n * Reduces to `composeRectPose` when the parent is upright, so a scene that\n * never rotates a container behaves identically under either strategy.\n *\n * Exact for translation and rotation. A parent carrying scale is outside what\n * this can express — see `PoseClosure`.\n */\nexport function composeRigidPose<TPose extends RectPose>(parent: TPose, child: TPose): TPose {\n const pr = parent.rotation ?? 0;\n const [wcx, wcy] = turn(\n parent.x + parent.width / 2,\n parent.y + parent.height / 2,\n pr,\n parent.x + child.x + child.width / 2,\n parent.y + child.y + child.height / 2,\n );\n return {\n ...child,\n x: wcx - child.width / 2,\n y: wcy - child.height / 2,\n rotation: (child.rotation ?? 0) + pr,\n };\n}\n\n/** Inverse of `composeRigidPose` — un-turns about the parent's center, then\n * subtracts the parent's offset. */\nexport function decomposeRigidPose<TPose extends RectPose>(parent: TPose, world: TPose): TPose {\n const pr = parent.rotation ?? 0;\n const [ux, uy] = turn(\n parent.x + parent.width / 2,\n parent.y + parent.height / 2,\n -pr,\n world.x + world.width / 2,\n world.y + world.height / 2,\n );\n return {\n ...world,\n x: ux - parent.x - world.width / 2,\n y: uy - parent.y - world.height / 2,\n rotation: (world.rotation ?? 0) - pr,\n };\n}\n\n/** Translation-only composition over `RectPose`. What a scene wants when a\n * container groups its children but never turns them. */\nexport const RECT_POSE_COMPOSITION: PoseComposition<RectPose> = {\n compose: composeRectPose,\n decompose: decomposeRectPose,\n closure: 'translation',\n};\n\n/** Composition over `RectPose` where a container's pose is a frame: rotating\n * the container rotates its contents. */\nexport const RIGID_POSE_COMPOSITION: PoseComposition<RectPose> = {\n compose: composeRigidPose,\n decompose: decomposeRigidPose,\n closure: 'rigid',\n};\n\n/**\n * Build a `(id) => world pose | null` callback over a `PoseAdapter`.\n * Convenience for RenderLayers that take a `getPose` callback (selection\n * overlays, debug layers, etc.) so consumers don't hand-write a\n * `composeWorldPose` call per layer.\n *\n * Returns `null` when `adapter.getPose` or `adapter.getParent` throws — the\n * common case is an id removed mid-render between selection state and the\n * next paint. Layers should treat `null` as \"skip this id.\"\n */\nexport function worldPoseLookup<TPose>(\n adapter: PoseAdapter<TPose>,\n compose: (parent: TPose, child: TPose) => TPose,\n): (id: string) => TPose | null {\n return (id: string) => {\n try {\n return composeWorldPose(adapter, id, compose);\n } catch {\n return null;\n }\n };\n}\n"],"mappings":";;AA8CA,SAAgBA,EAAwC,GAAe,GAAqB;CAC1F,OAAO;EACL,GAAGC;EACH,GAAGC,EAAO,IAAID,EAAM;EACpB,GAAGC,EAAO,IAAID,EAAM;CACtB;AACF;AAOA,SAAgBE,EAA0C,GAAa,GAAY,GAAmB;CACpG,OAAO;EAAE,GAAGC;EAAM,GAAGA,EAAK,IAAIC;EAAI,GAAGD,EAAK,IAAIE;CAAG;AACnD;AAGA,SAAgBC,EAA0C,GAAe,GAAqB;CAC5F,OAAO;EACL,GAAGC;EACH,GAAGA,EAAM,IAAIN,EAAO;EACpB,GAAGM,EAAM,IAAIN,EAAO;CACtB;AACF;AAGA,SAASO,EAAK,GAAY,GAAY,GAAW,GAAW,GAA6B;CACvF,IAAMC,IAAI,KAAK,IAAIC,CAAC,GACdC,IAAI,KAAK,IAAID,CAAC;CACpB,OAAO,CAACE,KAAMC,IAAID,KAAMH,KAAKK,IAAIC,KAAMJ,GAAGI,KAAMF,IAAID,KAAMD,KAAKG,IAAIC,KAAMN,CAAC;AAC5E;AAaA,SAAgBO,EAAyC,GAAe,GAAqB;CAC3F,IAAMC,IAAKhB,EAAO,YAAY,GACxB,CAACiB,GAAKC,KAAOX,EACjBP,EAAO,IAAIA,EAAO,QAAQ,GAC1BA,EAAO,IAAIA,EAAO,SAAS,GAC3BgB,GACAhB,EAAO,IAAID,EAAM,IAAIA,EAAM,QAAQ,GACnCC,EAAO,IAAID,EAAM,IAAIA,EAAM,SAAS,CACtC;CACA,OAAO;EACL,GAAGA;EACH,GAAGkB,IAAMlB,EAAM,QAAQ;EACvB,GAAGmB,IAAMnB,EAAM,SAAS;EACxB,WAAWA,EAAM,YAAY,KAAKiB;CACpC;AACF;AAIA,SAAgBG,EAA2C,GAAe,GAAqB;CAC7F,IAAMH,IAAKhB,EAAO,YAAY,GACxB,CAACoB,GAAIC,KAAMd,EACfP,EAAO,IAAIA,EAAO,QAAQ,GAC1BA,EAAO,IAAIA,EAAO,SAAS,GAC3B,CAACgB,GACDV,EAAM,IAAIA,EAAM,QAAQ,GACxBA,EAAM,IAAIA,EAAM,SAAS,CAC3B;CACA,OAAO;EACL,GAAGA;EACH,GAAGc,IAAKpB,EAAO,IAAIM,EAAM,QAAQ;EACjC,GAAGe,IAAKrB,EAAO,IAAIM,EAAM,SAAS;EAClC,WAAWA,EAAM,YAAY,KAAKU;CACpC;AACF;AAIA,IAAaM,IAAmD;CAC9D,SAASxB;CACT,WAAWO;CACX,SAAS;AACX,GAIakB,IAAoD;CAC/D,SAASR;CACT,WAAWI;CACX,SAAS;AACX;AAYA,SAAgBK,EACd,GACA,GAC8B;CAC9B,QAAQ,MAAe;EACrB,IAAI;GACF,OAAOC,EAAiBC,GAASC,GAAIC,CAAO;EAC9C,QAAQ;GACN,OAAO;EACT;CACF;AACF"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { worldPoseLookup as e } from "./composePose.js";
|
|
2
|
+
import { poseDescriptorForNode as t } from "../../core/geometry/poseDescriptor.js";
|
|
3
|
+
import { AUTO_POSE_DESCRIPTOR as n } from "../../interactions/actions/resize/autoPoseDescriptor.js";
|
|
4
|
+
//#region src/features/groups/nestedHit.ts
|
|
5
|
+
function r(r, i) {
|
|
6
|
+
let a = i.poseDescriptor ?? n, o = i.isGroup ?? (() => !1), s = e(r, i.composePose), c = (e) => {
|
|
7
|
+
let t = [], n = e;
|
|
8
|
+
for (; n !== null;) t.unshift(n), n = r.getParent(n);
|
|
9
|
+
return t;
|
|
10
|
+
}, l = (e, n) => {
|
|
11
|
+
let i = r.getNodes();
|
|
12
|
+
for (let r = i.length - 1; r >= 0; r--) {
|
|
13
|
+
let c = i[r];
|
|
14
|
+
if (o(c.id, c)) continue;
|
|
15
|
+
let l = s(c.id);
|
|
16
|
+
if (!l) continue;
|
|
17
|
+
let u = t(a, c).getBounds(l);
|
|
18
|
+
if (e >= u.x && e <= u.x + u.width && n >= u.y && n <= u.y + u.height) return c.id;
|
|
19
|
+
}
|
|
20
|
+
return null;
|
|
21
|
+
};
|
|
22
|
+
return {
|
|
23
|
+
pickOutermost: (e, t) => {
|
|
24
|
+
let n = l(e, t);
|
|
25
|
+
return n === null ? null : c(n)[0];
|
|
26
|
+
},
|
|
27
|
+
pickBest: (e, t, n, r) => {
|
|
28
|
+
let i = l(e, t);
|
|
29
|
+
if (i === null) return null;
|
|
30
|
+
let a = c(i);
|
|
31
|
+
if (!n) return a[0];
|
|
32
|
+
for (let e = a.length - 1; e >= 0; e--) if (r.includes(a[e])) return a[Math.min(e + 1, a.length - 1)];
|
|
33
|
+
return a[a.length - 1];
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
//#endregion
|
|
38
|
+
export { r as nestedHitTester };
|
|
39
|
+
|
|
40
|
+
//# sourceMappingURL=nestedHit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nestedHit.js","names":["nestedHitTester","d","opts","AUTO_POSE_DESCRIPTOR","isGroup","worldOf","worldPoseLookup","adapter","ancestorChain","chain","cur","id","hitLeaf","objs","i","o","w","b","poseDescriptorForNode","wx","wy","leaf","alt","selection"],"sources":["../../../src/features/groups/nestedHit.ts"],"sourcesContent":["import { worldPoseLookup } from './composePose';\nimport { poseDescriptorForNode, type PoseDescriptor } from 'core/geometry/poseDescriptor';\nimport { AUTO_POSE_DESCRIPTOR } from 'interactions/actions/resize/autoPoseDescriptor';\n\n/** @internal */\ninterface HitAdapter<TNode extends { id: string }, TPose> {\n getNode: (id: string) => TNode | undefined;\n getNodes: () => TNode[];\n getPose: (id: string) => TPose;\n getParent: (id: string) => string | null;\n}\n\n/** Options for `nestedHitTester`. */\nexport interface NestedHitOpts<TNode extends { id: string }, TPose> {\n /** Compose a child's local pose into world coords given its parent's world\n * pose. Same shape as `composeRectPose` (the default expectation). */\n composePose: (parent: TPose, child: TPose) => TPose;\n /** How to read world poses. Default `AUTO_POSE_DESCRIPTOR`. */\n poseDescriptor?: PoseDescriptor<TPose>;\n /** Predicate for \"this object is a nesting parent body\". The leaf scan\n * skips objects for which this returns true so a click on a parent's\n * painted body resolves to a child leaf, not the parent itself. Default:\n * never (treat every object as hittable). */\n isGroup?: (id: string, obj: TNode | undefined) => boolean;\n}\n\n/** Hit-test entry points for a nested scene: one that always picks the\n * outermost ancestor, and one that steps deeper on alt-click. */\nexport interface NestedHitTester {\n /** Outermost-ancestor pick. Suitable as the chrome-level `pickEvery`: a\n * casual click selects the whole top-level ancestor. Returns `null` on\n * empty space. */\n pickOutermost: (worldX: number, worldY: number) => string | null;\n /** Alt-aware selection-update pick. Without `alt`, returns the outermost\n * ancestor (same as `pickOutermost`). With `alt`, returns one level\n * deeper than the deepest currently-selected ancestor in the leaf's\n * chain — repeated alt-clicks step ancestor → descendant → leaf. With\n * `alt` and nothing in the chain selected, jumps straight to the leaf.\n * Plug into `useSelectTool({ pickBest })`. */\n pickBest: (\n worldX: number,\n worldY: number,\n alt: boolean,\n selection: readonly string[],\n ) => string | null;\n}\n\n/** Build hit-testers that respect containers: a plain click selects the\n * top-level ancestor, and alt-clicking descends one level at a time toward\n * the leaf actually under the pointer. */\nexport function nestedHitTester<TNode extends { id: string }, TPose>(\n adapter: HitAdapter<TNode, TPose>,\n opts: NestedHitOpts<TNode, TPose>,\n): NestedHitTester {\n const d = (opts.poseDescriptor ?? AUTO_POSE_DESCRIPTOR) as PoseDescriptor<TPose>;\n const isGroup = opts.isGroup ?? (() => false);\n const worldOf = worldPoseLookup(adapter, opts.composePose);\n\n const ancestorChain = (id: string): string[] => {\n const chain: string[] = [];\n let cur: string | null = id;\n while (cur !== null) {\n chain.unshift(cur);\n cur = adapter.getParent(cur);\n }\n return chain;\n };\n\n const hitLeaf = (wx: number, wy: number): string | null => {\n const objs = adapter.getNodes();\n for (let i = objs.length - 1; i >= 0; i--) {\n const o = objs[i];\n if (isGroup(o.id, o)) continue;\n const w = worldOf(o.id);\n if (!w) continue;\n const b = poseDescriptorForNode(d, o).getBounds(w);\n if (wx >= b.x && wx <= b.x + b.width && wy >= b.y && wy <= b.y + b.height) {\n return o.id;\n }\n }\n return null;\n };\n\n const pickOutermost = (wx: number, wy: number): string | null => {\n const leaf = hitLeaf(wx, wy);\n return leaf === null ? null : ancestorChain(leaf)[0];\n };\n\n const pickBest = (\n wx: number,\n wy: number,\n alt: boolean,\n selection: readonly string[],\n ): string | null => {\n const leaf = hitLeaf(wx, wy);\n if (leaf === null) return null;\n const chain = ancestorChain(leaf);\n if (!alt) return chain[0];\n for (let i = chain.length - 1; i >= 0; i--) {\n if (selection.includes(chain[i])) {\n return chain[Math.min(i + 1, chain.length - 1)];\n }\n }\n return chain[chain.length - 1];\n };\n\n return { pickOutermost, pickBest };\n}\n"],"mappings":";;;;AAkDA,SAAgBA,EACd,GACA,GACiB;CACjB,IAAMC,IAAKC,EAAK,kBAAkBC,GAC5BC,IAAUF,EAAK,kBAAkB,KACjCG,IAAUC,EAAgBC,GAASL,EAAK,WAAW,GAEnDM,KAAiB,MAAyB;EAC9C,IAAMC,IAAkB,CAAC,GACrBC,IAAqBC;EACzB,OAAOD,MAAQ,OAEb,AADAD,EAAM,QAAQC,CAAG,GACjB,IAAMH,EAAQ,UAAUG,CAAG;EAE7B,OAAOD;CACT,GAEMG,KAAW,GAAY,MAA8B;EACzD,IAAMC,IAAON,EAAQ,SAAS;EAC9B,KAAK,IAAIO,IAAID,EAAK,SAAS,GAAGC,KAAK,GAAG,KAAK;GACzC,IAAMC,IAAIF,EAAKC;GACf,IAAIV,EAAQW,EAAE,IAAIA,CAAC,GAAG;GACtB,IAAMC,IAAIX,EAAQU,EAAE,EAAE;GACtB,IAAI,CAACC,GAAG;GACR,IAAMC,IAAIC,EAAsBjB,GAAGc,CAAC,CAAC,CAAC,UAAUC,CAAC;GACjD,IAAIG,KAAMF,EAAE,KAAKE,KAAMF,EAAE,IAAIA,EAAE,SAASG,KAAMH,EAAE,KAAKG,KAAMH,EAAE,IAAIA,EAAE,QACjE,OAAOF,EAAE;EAEb;EACA,OAAO;CACT;CAyBA,OAAO;EAAE,gBAvBc,GAAY,MAA8B;GAC/D,IAAMM,IAAOT,EAAQO,GAAIC,CAAE;GAC3B,OAAOC,MAAS,OAAO,OAAOb,EAAca,CAAI,CAAC,CAAC;EACpD;EAoBwB,WAjBtB,GACA,GACA,GACA,MACkB;GAClB,IAAMA,IAAOT,EAAQO,GAAIC,CAAE;GAC3B,IAAIC,MAAS,MAAM,OAAO;GAC1B,IAAMZ,IAAQD,EAAca,CAAI;GAChC,IAAI,CAACC,GAAK,OAAOb,EAAM;GACvB,KAAK,IAAIK,IAAIL,EAAM,SAAS,GAAGK,KAAK,GAAG,KACrC,IAAIS,EAAU,SAASd,EAAMK,EAAE,GAC7B,OAAOL,EAAM,KAAK,IAAIK,IAAI,GAAGL,EAAM,SAAS,CAAC;GAGjD,OAAOA,EAAMA,EAAM,SAAS;EAC9B;CAEiC;AACnC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { unionAABB as e } from "../../core/geometry/unionBounds.js";
|
|
2
|
+
import { poseDescriptorForNode as t, visualBoundsViaDescriptor as n } from "../../core/geometry/poseDescriptor.js";
|
|
3
|
+
//#region src/features/groups/unionOfChildren.ts
|
|
4
|
+
function r(r) {
|
|
5
|
+
return (i, a) => {
|
|
6
|
+
let o = [];
|
|
7
|
+
for (let e of a) e !== void 0 && o.push(n(e.pose, t(r, e)));
|
|
8
|
+
let s = e(o);
|
|
9
|
+
return s === null ? null : t(r, i).fromBounds(s, i.pose);
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
//#endregion
|
|
13
|
+
export { r as unionOfChildrenVia };
|
|
14
|
+
|
|
15
|
+
//# sourceMappingURL=unionOfChildren.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unionOfChildren.js","names":["unionOfChildrenVia","boxes","d","deps","visualBoundsViaDescriptor","poseDescriptorForNode","descriptor","u","unionAABB","node"],"sources":["../../../src/features/groups/unionOfChildren.ts"],"sourcesContent":["import { unionAABB } from 'core/geometry/unionBounds';\nimport {\n poseDescriptorForNode,\n visualBoundsViaDescriptor,\n type PoseDescriptor,\n} from 'interactions/actions/resize/geometry';\nimport type { DerivePoseFn } from 'core/scene/types';\n\n/**\n * A container's pose as the envelope of what it holds, read through\n * `descriptor` — a rotated member contributes the extent of its ink. Register\n * the result under `UNION_OF_CHILDREN` in `createScene`'s `registry` to teach\n * a scene how to size its groups around a pose shape the kit cannot read.\n *\n * Returns `null` for an emptied container, which falls back to its authored\n * pose rather than collapsing to a zero box at the origin.\n */\nexport function unionOfChildrenVia<TPose>(\n descriptor: PoseDescriptor<TPose>,\n): DerivePoseFn<TPose> {\n return (node, deps) => {\n const boxes = [];\n for (const d of deps) {\n if (d !== undefined) {\n boxes.push(visualBoundsViaDescriptor(d.pose, poseDescriptorForNode(descriptor, d)));\n }\n }\n const u = unionAABB(boxes);\n return u === null\n ? null\n : poseDescriptorForNode(descriptor, node).fromBounds(u, node.pose);\n };\n}\n"],"mappings":";;;AAiBA,SAAgBA,EACd,GACqB;CACrB,QAAQ,GAAM,MAAS;EACrB,IAAMC,IAAQ,CAAC;EACf,KAAK,IAAMC,KAAKC,GACd,AAAID,MAAM,KAAA,KACRD,EAAM,KAAKG,EAA0BF,EAAE,MAAMG,EAAsBC,GAAYJ,CAAC,CAAC,CAAC;EAGtF,IAAMK,IAAIC,EAAUP,CAAK;EACzB,OAAOM,MAAM,OACT,OACAF,EAAsBC,GAAYG,CAAI,CAAC,CAAC,WAAWF,GAAGE,EAAK,IAAI;CACrE;AACF"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { maxImageTextureSide as e, releaseImageSource as t } from "../../renderer/cache/GLImageCache.js";
|
|
2
|
+
//#region src/features/images/imageCache.ts
|
|
3
|
+
var n = 16777216, r = 4, i = 300, a = 150, o = /* @__PURE__ */ new Map(), s = /* @__PURE__ */ new Set(), c = /* @__PURE__ */ new Map();
|
|
4
|
+
function l(e) {
|
|
5
|
+
return /^data:image\/svg\+xml[;,]/i.test(e) ? !0 : !/^(data|blob):/i.test(e) && /\.svgz?$/i.test(e.replace(/[?#].*$/, ""));
|
|
6
|
+
}
|
|
7
|
+
function u() {
|
|
8
|
+
if (typeof Image > "u" || typeof createImageBitmap > "u") throw Error("weasel imageCache: no DOM image loader in this environment");
|
|
9
|
+
}
|
|
10
|
+
async function d(e) {
|
|
11
|
+
let t = new Image();
|
|
12
|
+
return t.crossOrigin = "anonymous", t.src = e, await t.decode(), t;
|
|
13
|
+
}
|
|
14
|
+
function f(e) {
|
|
15
|
+
let t = c.get(e);
|
|
16
|
+
return t || (t = d(e), c.set(e, t), t.catch(() => c.delete(e))), t;
|
|
17
|
+
}
|
|
18
|
+
async function p(e, t) {
|
|
19
|
+
let n = await f(e), r = t?.width ?? (n.naturalWidth || i), o = t?.height ?? (n.naturalHeight || a), s = typeof OffscreenCanvas < "u" ? new OffscreenCanvas(r, o) : Object.assign(document.createElement("canvas"), {
|
|
20
|
+
width: r,
|
|
21
|
+
height: o
|
|
22
|
+
}), c = s.getContext("2d");
|
|
23
|
+
if (!c) throw Error("weasel imageCache: no 2D context to rasterize an SVG");
|
|
24
|
+
return c.drawImage(n, 0, 0, r, o), createImageBitmap(s);
|
|
25
|
+
}
|
|
26
|
+
var m = async (e, t) => (u(), l(e) ? p(e, t) : createImageBitmap(await d(e)));
|
|
27
|
+
function h() {
|
|
28
|
+
for (let e of s) e();
|
|
29
|
+
}
|
|
30
|
+
function g(e) {
|
|
31
|
+
let t = { status: "loading" };
|
|
32
|
+
o.set(e, t), m(e).then((n) => {
|
|
33
|
+
o.get(e) === t && (o.set(e, {
|
|
34
|
+
status: "ready",
|
|
35
|
+
bitmap: n,
|
|
36
|
+
...l(e) ? { vector: {
|
|
37
|
+
natural: {
|
|
38
|
+
width: n.width,
|
|
39
|
+
height: n.height
|
|
40
|
+
},
|
|
41
|
+
scale: 1,
|
|
42
|
+
failed: /* @__PURE__ */ new Set()
|
|
43
|
+
} } : {}
|
|
44
|
+
}), h());
|
|
45
|
+
}, () => {
|
|
46
|
+
o.get(e) === t && (o.set(e, { status: "error" }), h());
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
function _(t, r) {
|
|
50
|
+
let i = Math.max(r.width / t.width, r.height / t.height);
|
|
51
|
+
if (!(i > 0) || !Number.isFinite(i)) return;
|
|
52
|
+
let a = e(), o = Math.min(a / t.width, a / t.height, Math.sqrt(n / (t.width * t.height)));
|
|
53
|
+
return Math.min(2 ** Math.ceil(Math.log2(i)), o);
|
|
54
|
+
}
|
|
55
|
+
function v(e, n, i, a) {
|
|
56
|
+
if (i.pending !== void 0) return;
|
|
57
|
+
let s = _(i.natural, a);
|
|
58
|
+
if (s === void 0) return;
|
|
59
|
+
let c = s > i.scale;
|
|
60
|
+
if (!(!c && s * r > i.scale)) {
|
|
61
|
+
for (let e of i.failed) if (s === e || c && e > i.scale && s >= e) return;
|
|
62
|
+
i.pending = s, m(e, {
|
|
63
|
+
width: Math.max(1, Math.round(i.natural.width * s)),
|
|
64
|
+
height: Math.max(1, Math.round(i.natural.height * s))
|
|
65
|
+
}).then((r) => {
|
|
66
|
+
if (o.get(e) !== n) return;
|
|
67
|
+
i.pending = void 0;
|
|
68
|
+
let a = n.bitmap;
|
|
69
|
+
n.bitmap = r, i.scale = s, a && a !== r && t(a), h();
|
|
70
|
+
}, () => {
|
|
71
|
+
o.get(e) === n && (i.pending = void 0, i.failed.add(s));
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
function y(e, t) {
|
|
76
|
+
let n = o.get(e);
|
|
77
|
+
if (!n) {
|
|
78
|
+
g(e);
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
return t && n.vector && v(e, n, n.vector, t), n.bitmap;
|
|
82
|
+
}
|
|
83
|
+
function b(e) {
|
|
84
|
+
return o.get(e)?.status ?? "idle";
|
|
85
|
+
}
|
|
86
|
+
function x(e) {
|
|
87
|
+
return s.add(e), () => {
|
|
88
|
+
s.delete(e);
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
//#endregion
|
|
92
|
+
export { y as getImageBitmap, b as imageStatus, l as isVectorImageSrc, x as subscribeImageReady };
|
|
93
|
+
|
|
94
|
+
//# sourceMappingURL=imageCache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"imageCache.js","names":["MAX_VECTOR_RASTER_PIXELS","SHRINK_SLACK","FALLBACK_WIDTH","FALLBACK_HEIGHT","cache","subscribers","decodedVectors","isVectorImageSrc","src","requireDom","decodeImage","img","decodeVector","decoded","rasterizeVector","width","size","height","canvas","c2d","loader","notify","cb","startLoad","entry","bitmap","rasterScaleFor","need","drawnAt","natural","side","maxImageTextureSide","cap","maybeReraster","v","target","grow","f","old","releaseImageSource","getImageBitmap","imageStatus","subscribeImageReady"],"sources":["../../../src/features/images/imageCache.ts"],"sourcesContent":["/**\n * imageCache — the kit's per-`src` image loader + cache.\n *\n * The shape-painter chain (`kit:image` in `NodeShape.ts`) is synchronous, but\n * decoding an image is async. This module bridges the two: `getImageBitmap` is\n * a synchronous read that returns the decoded `ImageBitmap` when ready, and\n * otherwise returns `undefined` and lazily kicks off a de-duped async load.\n * When a load resolves (or errors), every `subscribeImageReady` listener fires\n * — `<SceneCanvas>` subscribes and calls `requestRedraw()`, so the painter\n * re-runs and emits the now-ready bitmap.\n *\n * `src` is any browser-loadable image string: a remote URL, a `blob:` URL, or\n * a `data:image/…;base64,…` URI (the embedded-bytes path). The decoded bitmap\n * lives only here, keyed by `src` — never in node `data` — so `scene.toJSON()`\n * round-trips the (serializable) `src` string untouched.\n */\n\nimport { maxImageTextureSide, releaseImageSource } from 'renderer/cache/GLImageCache';\n\n/** Public shape of an image node's `data`. `src` round-trips through\n * serialization; the decoded bitmap is held in this cache, not on the node. */\nexport interface ImageNodeData {\n image: {\n src: string;\n opacity?: number;\n /** The part of the bitmap drawn into the pose rect, as fractions of the\n * bitmap's width and height from its top-left. Omitted draws the whole\n * bitmap. Fractions, so the data means the same thing before the bitmap\n * has decoded and after `src` is swapped for another resolution. */\n source?: { x: number; y: number; width: number; height: number };\n /** Mirror the drawn region within the pose rect. The rect does not move. */\n flipX?: boolean;\n flipY?: boolean;\n };\n}\n\n/** Where an image is in its load: never requested, in flight, decoded, or\n * failed. Renderers paint a placeholder for anything but `'ready'`. */\nexport type ImageStatus = 'idle' | 'loading' | 'ready' | 'error';\n\n/** A size in device pixels. */\nexport interface ImageRasterSize {\n width: number;\n height: number;\n}\n\n/** A vector source's raster bookkeeping. `scale` is the current raster's size\n * over the natural one, always a power of two unless a cap cut it short. */\ninterface VectorRaster {\n natural: ImageRasterSize;\n scale: number;\n pending?: number;\n failed: Set<number>;\n}\n\ninterface Entry {\n status: ImageStatus;\n bitmap?: ImageBitmap;\n vector?: VectorRaster;\n}\n\n/** `size` is absent for the first load, which decodes at natural size. */\ntype Loader = (src: string, size?: ImageRasterSize) => Promise<ImageBitmap>;\n\n/** One vector raster may hold at most 64MB of RGBA. */\nconst MAX_VECTOR_RASTER_PIXELS = 4096 * 4096;\n/** A raster is only shrunk once it is this many times larger than needed, so\n * zooming back and forth across a bucket edge does not re-raster each way. */\nconst SHRINK_SLACK = 4;\n// CSS default object size, as `kit:svg` measures a viewBox-only SVG.\nconst FALLBACK_WIDTH = 300;\nconst FALLBACK_HEIGHT = 150;\n\nconst cache = new Map<string, Entry>();\nconst subscribers = new Set<() => void>();\nconst decodedVectors = new Map<string, Promise<HTMLImageElement>>();\n\n/** True when `src` names SVG — a `data:image/svg+xml` URI, or a URL whose path\n * ends in `.svg`/`.svgz`. Such sources re-rasterize at the size they are drawn\n * at; everything else decodes once. A `blob:` URL carries no type and counts\n * as raster. */\nexport function isVectorImageSrc(src: string): boolean {\n if (/^data:image\\/svg\\+xml[;,]/i.test(src)) return true;\n if (/^(data|blob):/i.test(src)) return false;\n return /\\.svgz?$/i.test(src.replace(/[?#].*$/, ''));\n}\n\nfunction requireDom(): void {\n if (typeof Image === 'undefined' || typeof createImageBitmap === 'undefined') {\n throw new Error('weasel imageCache: no DOM image loader in this environment');\n }\n}\n\nasync function decodeImage(src: string): Promise<HTMLImageElement> {\n const img = new Image();\n img.crossOrigin = 'anonymous';\n img.src = src;\n await img.decode();\n return img;\n}\n\nfunction decodeVector(src: string): Promise<HTMLImageElement> {\n let decoded = decodedVectors.get(src);\n if (!decoded) {\n decoded = decodeImage(src);\n decodedVectors.set(src, decoded);\n decoded.catch(() => decodedVectors.delete(src));\n }\n return decoded;\n}\n\n// `createImageBitmap` rejects SVG blobs and resamples an SVG `<img>` rather\n// than re-drawing it, so vectors go through a canvas `drawImage` at full size.\nasync function rasterizeVector(src: string, size?: ImageRasterSize): Promise<ImageBitmap> {\n const img = await decodeVector(src);\n const width = size?.width ?? (img.naturalWidth || FALLBACK_WIDTH);\n const height = size?.height ?? (img.naturalHeight || FALLBACK_HEIGHT);\n const canvas: OffscreenCanvas | HTMLCanvasElement = typeof OffscreenCanvas !== 'undefined'\n ? new OffscreenCanvas(width, height)\n : Object.assign(document.createElement('canvas'), { width, height });\n const c2d = canvas.getContext('2d') as CanvasDrawImage | null;\n if (!c2d) throw new Error('weasel imageCache: no 2D context to rasterize an SVG');\n c2d.drawImage(img, 0, 0, width, height);\n return createImageBitmap(canvas);\n}\n\nconst defaultLoader: Loader = async (src, size) => {\n requireDom();\n if (isVectorImageSrc(src)) return rasterizeVector(src, size);\n return createImageBitmap(await decodeImage(src));\n};\n\nlet loader: Loader = defaultLoader;\n\nfunction notify(): void {\n for (const cb of subscribers) cb();\n}\n\nfunction startLoad(src: string): void {\n const entry: Entry = { status: 'loading' };\n cache.set(src, entry);\n loader(src).then(\n (bitmap) => {\n // The entry may have been replaced/cleared mid-flight (reset, etc.);\n // only commit if this src is still the one we started loading.\n if (cache.get(src) !== entry) return;\n cache.set(src, {\n status: 'ready',\n bitmap,\n ...(isVectorImageSrc(src)\n ? { vector: { natural: { width: bitmap.width, height: bitmap.height }, scale: 1, failed: new Set<number>() } }\n : {}),\n });\n notify();\n },\n () => {\n // Cache the error so a broken `src` doesn't reload-storm.\n if (cache.get(src) !== entry) return;\n cache.set(src, { status: 'error' });\n notify();\n },\n );\n}\n\n/** The raster scale `drawnAt` calls for: the next power of two at or above the\n * natural-to-drawn ratio, capped by texture size and the pixel ceiling. */\nfunction rasterScaleFor(natural: ImageRasterSize, drawnAt: ImageRasterSize): number | undefined {\n const need = Math.max(drawnAt.width / natural.width, drawnAt.height / natural.height);\n if (!(need > 0) || !Number.isFinite(need)) return undefined;\n const side = maxImageTextureSide();\n const cap = Math.min(\n side / natural.width,\n side / natural.height,\n Math.sqrt(MAX_VECTOR_RASTER_PIXELS / (natural.width * natural.height)),\n );\n return Math.min(2 ** Math.ceil(Math.log2(need)), cap);\n}\n\nfunction maybeReraster(src: string, entry: Entry, v: VectorRaster, drawnAt: ImageRasterSize): void {\n if (v.pending !== undefined) return;\n const target = rasterScaleFor(v.natural, drawnAt);\n if (target === undefined) return;\n const grow = target > v.scale;\n if (!grow && target * SHRINK_SLACK > v.scale) return;\n for (const f of v.failed) if (target === f || (grow && f > v.scale && target >= f)) return;\n\n v.pending = target;\n const size = {\n width: Math.max(1, Math.round(v.natural.width * target)),\n height: Math.max(1, Math.round(v.natural.height * target)),\n };\n loader(src, size).then(\n (bitmap) => {\n if (cache.get(src) !== entry) return;\n v.pending = undefined;\n const old = entry.bitmap;\n entry.bitmap = bitmap;\n v.scale = target;\n if (old && old !== bitmap) releaseImageSource(old);\n notify();\n },\n () => {\n // The previous raster keeps painting; only this scale is given up on.\n if (cache.get(src) !== entry) return;\n v.pending = undefined;\n v.failed.add(target);\n },\n );\n}\n\n/** Synchronous read. Returns the decoded bitmap when ready; otherwise returns\n * `undefined` and lazily starts a de-duped async load for `src`.\n *\n * `drawnAt` is the size in device pixels the image is about to cover. A\n * vector source ({@link isVectorImageSrc}) uses it to re-rasterize in\n * power-of-two steps — the current raster is returned until the sharper one\n * is ready. Raster sources ignore it. */\nexport function getImageBitmap(src: string, drawnAt?: ImageRasterSize): ImageBitmap | undefined {\n const entry = cache.get(src);\n if (!entry) {\n startLoad(src);\n return undefined;\n }\n if (drawnAt && entry.vector) maybeReraster(src, entry, entry.vector, drawnAt);\n return entry.bitmap;\n}\n\n/** Current load status for `src` (`'idle'` if never requested). */\nexport function imageStatus(src: string): ImageStatus {\n return cache.get(src)?.status ?? 'idle';\n}\n\n/** Subscribe to load-resolution events (fires after any `src` resolves or\n * errors). Returns an unsubscribe. */\nexport function subscribeImageReady(cb: () => void): () => void {\n subscribers.add(cb);\n return () => {\n subscribers.delete(cb);\n };\n}\n\n/** @internal test seam — override the async loader so unit tests don't need\n * a real DOM image. Not part of the public barrel. */\nexport function __setImageLoaderForTests(fn: Loader): void {\n loader = fn;\n}\n\n/** @internal test seam — clear cache + subscribers and restore the default\n * loader. Not part of the public barrel. */\nexport function _resetImageCacheForTests(): void {\n cache.clear();\n subscribers.clear();\n decodedVectors.clear();\n loader = defaultLoader;\n}\n"],"mappings":";;AAiEA,IAAMA,IAA2B,UAG3BC,IAAe,GAEfC,IAAiB,KACjBC,IAAkB,KAElBC,oBAAQ,IAAI,IAAmB,GAC/BC,oBAAc,IAAI,IAAgB,GAClCC,oBAAiB,IAAI,IAAuC;AAMlE,SAAgBC,EAAiB,GAAsB;CAGrD,OAFI,6BAA6B,KAAKC,CAAG,IAAU,KACnD,CAAI,iBAAiB,KAAKA,CAAG,KACtB,YAAY,KAAKA,EAAI,QAAQ,WAAW,EAAE,CAAC;AACpD;AAEA,SAASC,IAAmB;CAC1B,IAAI,OAAO,QAAU,OAAe,OAAO,oBAAsB,KAC/D,MAAU,MAAM,4DAA4D;AAEhF;AAEA,eAAeC,EAAY,GAAwC;CACjE,IAAMC,IAAM,IAAI,MAAM;CAItB,OAHA,EAAI,cAAc,aAClB,EAAI,MAAMH,GACV,MAAMG,EAAI,OAAO,GACVA;AACT;AAEA,SAASC,EAAa,GAAwC;CAC5D,IAAIC,IAAUP,EAAe,IAAIE,CAAG;CAMpC,OALKK,MACH,IAAUH,EAAYF,CAAG,GACzBF,EAAe,IAAIE,GAAKK,CAAO,GAC/BA,EAAQ,YAAYP,EAAe,OAAOE,CAAG,CAAC,IAEzCK;AACT;AAIA,eAAeC,EAAgB,GAAa,GAA8C;CACxF,IAAMH,IAAM,MAAMC,EAAaJ,CAAG,GAC5BO,IAAQC,GAAM,UAAUL,EAAI,gBAAgBT,IAC5Ce,IAASD,GAAM,WAAWL,EAAI,iBAAiBR,IAC/Ce,IAA8C,OAAO,kBAAoB,MAC3E,IAAI,gBAAgBH,GAAOE,CAAM,IACjC,OAAO,OAAO,SAAS,cAAc,QAAQ,GAAG;EAAE;EAAO;CAAO,CAAC,GAC/DE,IAAMD,EAAO,WAAW,IAAI;CAClC,IAAI,CAACC,GAAK,MAAU,MAAM,sDAAsD;CAEhF,OADAA,EAAI,UAAUR,GAAK,GAAG,GAAGI,GAAOE,CAAM,GAC/B,kBAAkBC,CAAM;AACjC;AAQA,IAAIE,IAAiB,OANgB,GAAK,OACxCX,EAAW,GACPF,EAAiBC,CAAG,IAAUM,EAAgBN,GAAKQ,CAAI,IACpD,kBAAkB,MAAMN,EAAYF,CAAG,CAAC;AAKjD,SAASa,IAAe;CACtB,KAAK,IAAMC,KAAMjB,GAAa,EAAG;AACnC;AAEA,SAASkB,EAAU,GAAmB;CACpC,IAAMC,IAAe,EAAE,QAAQ,UAAU;CAEzC,AADApB,EAAM,IAAII,GAAKgB,CAAK,GACpBJ,EAAOZ,CAAG,CAAC,CAAC,MACT,MAAW;EAGV,AAAIJ,EAAM,IAAII,CAAG,MAAMgB,MACvBpB,EAAM,IAAII,GAAK;GACb,QAAQ;GACR;GACA,GAAID,EAAiBC,CAAG,IACpB,EAAE,QAAQ;IAAE,SAAS;KAAE,OAAOiB,EAAO;KAAO,QAAQA,EAAO;IAAO;IAAG,OAAO;IAAG,wBAAQ,IAAI,IAAY;GAAE,EAAE,IAC3G,CAAC;EACP,CAAC,GACDJ,EAAO;CACT,SACM;EAEJ,AAAIjB,EAAM,IAAII,CAAG,MAAMgB,MACvBpB,EAAM,IAAII,GAAK,EAAE,QAAQ,QAAQ,CAAC,GAClCa,EAAO;CACT,CACF;AACF;AAIA,SAASK,EAAe,GAA0B,GAA8C;CAC9F,IAAMC,IAAO,KAAK,IAAIC,EAAQ,QAAQC,EAAQ,OAAOD,EAAQ,SAASC,EAAQ,MAAM;CACpF,IAAI,EAAEF,IAAO,MAAM,CAAC,OAAO,SAASA,CAAI,GAAG;CAC3C,IAAMG,IAAOC,EAAoB,GAC3BC,IAAM,KAAK,IACfF,IAAOD,EAAQ,OACfC,IAAOD,EAAQ,QACf,KAAK,KAAK7B,KAA4B6B,EAAQ,QAAQA,EAAQ,OAAO,CACvE;CACA,OAAO,KAAK,IAAI,KAAK,KAAK,KAAK,KAAK,KAAKF,CAAI,CAAC,GAAGK,CAAG;AACtD;AAEA,SAASC,EAAc,GAAa,GAAc,GAAiB,GAAgC;CACjG,IAAIC,EAAE,YAAY,KAAA,GAAW;CAC7B,IAAMC,IAAST,EAAeQ,EAAE,SAASN,CAAO;CAChD,IAAIO,MAAW,KAAA,GAAW;CAC1B,IAAMC,IAAOD,IAASD,EAAE;CACxB,IAAI,GAACE,KAAQD,IAASlC,IAAeiC,EAAE,QACvC;OAAK,IAAMG,KAAKH,EAAE,QAAQ,IAAIC,MAAWE,KAAMD,KAAQC,IAAIH,EAAE,SAASC,KAAUE,GAAI;EAOpF,AALA,EAAE,UAAUF,GAKZf,EAAOZ,GAAK;GAHV,OAAO,KAAK,IAAI,GAAG,KAAK,MAAM0B,EAAE,QAAQ,QAAQC,CAAM,CAAC;GACvD,QAAQ,KAAK,IAAI,GAAG,KAAK,MAAMD,EAAE,QAAQ,SAASC,CAAM,CAAC;EAE/C,CAAI,CAAC,CAAC,MACf,MAAW;GACV,IAAI/B,EAAM,IAAII,CAAG,MAAMgB,GAAO;GAC9B,EAAE,UAAU,KAAA;GACZ,IAAMc,IAAMd,EAAM;GAIlB,AAHA,EAAM,SAASC,GACf,EAAE,QAAQU,GACNG,KAAOA,MAAQb,KAAQc,EAAmBD,CAAG,GACjDjB,EAAO;EACT,SACM;GAEJ,AAAIjB,EAAM,IAAII,CAAG,MAAMgB,MACvB,EAAE,UAAU,KAAA,GACZU,EAAE,OAAO,IAAIC,CAAM;EACrB,CACF;CAvBoF;AAwBtF;AASA,SAAgBK,EAAe,GAAa,GAAoD;CAC9F,IAAMhB,IAAQpB,EAAM,IAAII,CAAG;CAC3B,IAAI,CAACgB,GAAO;EACV,EAAUhB,CAAG;EACb;CACF;CAEA,OADIoB,KAAWJ,EAAM,UAAQS,EAAczB,GAAKgB,GAAOA,EAAM,QAAQI,CAAO,GACrEJ,EAAM;AACf;AAGA,SAAgBiB,EAAY,GAA0B;CACpD,OAAOrC,EAAM,IAAII,CAAG,CAAC,EAAE,UAAU;AACnC;AAIA,SAAgBkC,EAAoB,GAA4B;CAE9D,OADArC,EAAY,IAAIiB,CAAE,SACL;EACX,EAAY,OAAOA,CAAE;CACvB;AACF"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { dwarn as e } from "../../debug/flag.js";
|
|
2
|
+
import { mimeMatchesGlob as t } from "@weasel-js/gestures";
|
|
3
|
+
//#region src/features/ingestion/contentHandlers.ts
|
|
4
|
+
var n = [];
|
|
5
|
+
function r(e) {
|
|
6
|
+
return n.push(e), () => {
|
|
7
|
+
let t = n.indexOf(e);
|
|
8
|
+
t >= 0 && n.splice(t, 1);
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
function i() {
|
|
12
|
+
return [...n].sort((e, t) => (t.priority ?? 0) - (e.priority ?? 0));
|
|
13
|
+
}
|
|
14
|
+
function a(e, n) {
|
|
15
|
+
let { match: r } = e;
|
|
16
|
+
if (typeof r == "function") try {
|
|
17
|
+
return r(n);
|
|
18
|
+
} catch (t) {
|
|
19
|
+
return console.warn(`weasel ingest: handler "${e.id}" match predicate threw`, t), !1;
|
|
20
|
+
}
|
|
21
|
+
return (Array.isArray(r) ? r : [r]).some((e) => t(n.mime, e));
|
|
22
|
+
}
|
|
23
|
+
async function o(t, n) {
|
|
24
|
+
let r = t, o = [];
|
|
25
|
+
for (let e of i()) {
|
|
26
|
+
if (r.length === 0) break;
|
|
27
|
+
let t = r.filter((t) => a(e, t));
|
|
28
|
+
t.length !== 0 && (r = r.filter((e) => !t.includes(e)), o.push(Promise.resolve().then(() => e.handle(t, n)).catch((t) => {
|
|
29
|
+
console.warn(`weasel ingest: handler "${e.id}" threw`, t);
|
|
30
|
+
})));
|
|
31
|
+
}
|
|
32
|
+
r.length > 0 && e("ingest", `no content handler matched ${r.length} item(s):`, r.map((e) => e.mime).join(", ")), await Promise.all(o);
|
|
33
|
+
}
|
|
34
|
+
//#endregion
|
|
35
|
+
export { i as getContentHandlers, r as registerContentHandler, o as runIngest };
|
|
36
|
+
|
|
37
|
+
//# sourceMappingURL=contentHandlers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contentHandlers.js","names":["HANDLERS","registerContentHandler","entry","i","getContentHandlers","b","a","entryMatches","match","item","err","mimeMatchesGlob","g","runIngest","remaining","items","runs","mine","it","ctx","dwarn"],"sources":["../../../src/features/ingestion/contentHandlers.ts"],"sourcesContent":["/**\n * Content-handler registry — the \"registry out\" half of external-content\n * ingestion (spec: docs/superpowers/specs/2026-07-03-content-ingestion-design.md).\n *\n * All three arrival paths (OS drop, clipboard paste, file picker /\n * `CanvasExtensionApi.ingest`) converge here: the `ingest` action calls\n * `runIngest(items, ctx)`, which partitions the items across registered\n * handlers in priority order — the first matching handler takes every item\n * it matches; leftovers continue down the list. Same per-trait registry\n * idiom as `NodeShape` / `NodeRouting`.\n *\n * MIME matching delegates to `mimeMatchesGlob` from `@weasel-js/gestures` —\n * the SAME matcher the binding-level `types` filter uses, so a binding that\n * matched can never disagree with the registry about what a glob means.\n */\nimport { mimeMatchesGlob } from '@weasel-js/gestures';\nimport { dwarn } from '../../debug';\nimport type { Scene } from 'core/scene/types';\nimport type { SelectionApi } from 'core/selection/useSelection';\nimport type { Op } from 'core/ops/types';\nimport type { ClipboardIngestCtx, InsertDep, SvgIngestOptions } from 'interactions/actions/depSchema';\nimport type { ActionDeps } from '@weasel-js/routing';\nimport type { IngestItem } from '@weasel-js/routing';\n\n/** Context handed to every content handler for one ingest event. */\nexport interface IngestCtx {\n /** World-space arrival point (drop / pointed imperative ingest); `null`\n * for paste and point-less calls — handlers pick their own policy\n * (the kit image handler centers on the viewport). */\n point: { x: number; y: number } | null;\n /** Visible canvas area in world coordinates. */\n viewportWorldRect(): { x: number; y: number; width: number; height: number };\n /** The kit insert dep — id/layer/undoable-op supplied; the canonical way\n * for a handler to mint a node (`insert.commit(bounds, { kind, ... })`). */\n insert: InsertDep;\n /** Raw op commit for handlers that build their own ops. */\n applyOps(ops: Op[], label?: string): void;\n scene: Scene<unknown, string, unknown>;\n selection: SelectionApi;\n /** Consumer file→src resolver (SceneCanvas `ingestion.resolveSrc`).\n * When absent, the kit image handler embeds as a `data:` URI. */\n resolveSrc?: (file: File) => Promise<string>;\n /** Kit SVG-handler options (SceneCanvas `ingestion.svg`) — e.g.\n * `{ unpack: unpackSvgFiles }` (from `@weasel-js/svg`) to parse SVG files\n * into scene nodes. */\n svg?: SvgIngestOptions;\n /** Clipboard-paste seam — present when the hosting `SceneCanvas` supplied\n * an adapter with `commitPaste`. `reviver` comes from\n * `SceneCanvasProps.ingestion.clipboard`. Absent ⇒ the kit weasel-JSON\n * handler declines inert (dwarn, nothing ingested) — its matched items\n * were already consumed at match time, so they do NOT fall through;\n * only match-level misses flow on to other handlers. */\n clipboard?: ClipboardIngestCtx;\n /** Set to `true` by the kit weasel-JSON handler when it successfully\n * pastes a payload in this event. The `ctx` object is shared across all\n * handlers in one `runIngest` call, and higher-priority handlers' `handle`\n * bodies run (synchronously) before lower ones — so `kit:svg`'s\n * `text/plain` SVG fallback reads this to decline the SVG flavor of a copy\n * whose canonical weasel-JSON flavor already ingested (avoids a\n * double-paste when both flavors ride one clipboard event). */\n consumedWeaselPayload?: boolean;\n /** Full action-deps bag, for consumer handlers that need more. */\n deps: ActionDeps;\n}\n\n/** A handler for content arriving by paste, drop or file picker. Handlers are\n * matched by MIME glob or predicate and run highest-priority first; the kit's\n * own register at a low priority so a consumer's handler wins by default. */\nexport interface ContentHandlerEntry {\n /** Stable identifier — used for unregistration and debugging\n * (`'kit:image'`, `'app:csv'`). */\n id: string;\n /** MIME glob(s) (`'image/*'`, `'text/csv'`) or an item predicate. */\n match: string | string[] | ((item: IngestItem) => boolean);\n /** Higher runs earlier. Kit defaults register at -100 so any consumer\n * handler (default 0) beats them. */\n priority?: number;\n handle(items: IngestItem[], ctx: IngestCtx): void | Promise<void>;\n}\n\nconst HANDLERS: ContentHandlerEntry[] = [];\n\n/** Register a content handler. Returns a disposer that removes it. */\nexport function registerContentHandler(entry: ContentHandlerEntry): () => void {\n HANDLERS.push(entry);\n return () => {\n const i = HANDLERS.indexOf(entry);\n if (i >= 0) HANDLERS.splice(i, 1);\n };\n}\n\n/** Snapshot of registered handlers, priority-ordered (stable within ties —\n * registration order; Array.prototype.sort is stable per ES2019). */\nexport function getContentHandlers(): readonly ContentHandlerEntry[] {\n return [...HANDLERS].sort((a, b) => (b.priority ?? 0) - (a.priority ?? 0));\n}\n\nfunction entryMatches(entry: ContentHandlerEntry, item: IngestItem): boolean {\n const { match } = entry;\n if (typeof match === 'function') {\n try {\n return match(item);\n } catch (err) {\n console.warn(`weasel ingest: handler \"${entry.id}\" match predicate threw`, err);\n return false;\n }\n }\n const globs = Array.isArray(match) ? match : [match];\n return globs.some((g) => mimeMatchesGlob(item.mime, g));\n}\n\n/**\n * Route one ingest event's items through the registry. Handlers are queued\n * as microtasks in priority order and their async work then overlaps (each\n * already owns a disjoint item set); a throwing or rejecting handler\n * `console.warn`s and doesn't block the others. The queue order is a real\n * invariant: a higher-priority handler's `handle` body runs before lower\n * ones start, so ctx-flag coordination (e.g. `consumedWeaselPayload`)\n * works — but only while the writing handler stays synchronous up to the\n * write and the reading handler reads before its first `await`.\n * Unmatched items are ignored with a debug-gated `dwarn('ingest', ...)`.\n */\nexport async function runIngest(items: IngestItem[], ctx: IngestCtx): Promise<void> {\n let remaining = items;\n const runs: Promise<void>[] = [];\n\n for (const entry of getContentHandlers()) {\n if (remaining.length === 0) break;\n const mine = remaining.filter((it) => entryMatches(entry, it));\n if (mine.length === 0) continue;\n remaining = remaining.filter((it) => !mine.includes(it));\n runs.push(\n Promise.resolve()\n .then(() => entry.handle(mine, ctx))\n .catch((err) => {\n console.warn(`weasel ingest: handler \"${entry.id}\" threw`, err);\n }),\n );\n }\n\n if (remaining.length > 0) {\n dwarn(\n 'ingest',\n `no content handler matched ${remaining.length} item(s):`,\n remaining.map((it) => it.mime).join(', '),\n );\n }\n\n await Promise.all(runs);\n}\n\n/** @internal test seam — clear the registry. Not part of the public barrel. */\nexport function _resetContentHandlersForTests(): void {\n HANDLERS.length = 0;\n}\n"],"mappings":";;;AAgFA,IAAMA,IAAkC,CAAC;AAGzC,SAAgBC,EAAuB,GAAwC;CAE7E,OADAD,EAAS,KAAKE,CAAK,SACN;EACX,IAAMC,IAAIH,EAAS,QAAQE,CAAK;EAChC,AAAIC,KAAK,KAAGH,EAAS,OAAOG,GAAG,CAAC;CAClC;AACF;AAIA,SAAgBC,IAAqD;CACnE,OAAO,CAAC,GAAGJ,CAAQ,CAAC,CAAC,MAAM,GAAG,OAAOK,EAAE,YAAY,MAAMC,EAAE,YAAY,EAAE;AAC3E;AAEA,SAASC,EAAa,GAA4B,GAA2B;CAC3E,IAAM,EAAE,aAAUL;CAClB,IAAI,OAAOM,KAAU,YACnB,IAAI;EACF,OAAOA,EAAMC,CAAI;CACnB,SAASC,GAAK;EAEZ,OADA,QAAQ,KAAK,2BAA2BR,EAAM,GAAG,0BAA0BQ,CAAG,GACvE;CACT;CAGF,QADc,MAAM,QAAQF,CAAK,IAAIA,IAAQ,CAACA,CAAK,EAAA,CACtC,MAAM,MAAMG,EAAgBF,EAAK,MAAMG,CAAC,CAAC;AACxD;AAaA,eAAsBC,EAAU,GAAqB,GAA+B;CAClF,IAAIC,IAAYC,GACVC,IAAwB,CAAC;CAE/B,KAAK,IAAMd,KAASE,EAAmB,GAAG;EACxC,IAAIU,EAAU,WAAW,GAAG;EAC5B,IAAMG,IAAOH,EAAU,QAAQ,MAAOP,EAAaL,GAAOgB,CAAE,CAAC;EAC7D,AAAID,EAAK,WAAW,MACpB,IAAYH,EAAU,QAAQ,MAAO,CAACG,EAAK,SAASC,CAAE,CAAC,GACvDF,EAAK,KACH,QAAQ,QAAQ,CAAC,CACd,WAAWd,EAAM,OAAOe,GAAME,CAAG,CAAC,CAAC,CACnC,OAAO,MAAQ;GACd,QAAQ,KAAK,2BAA2BjB,EAAM,GAAG,UAAUQ,CAAG;EAChE,CAAC,CACL;CACF;CAUA,AARII,EAAU,SAAS,KACrBM,EACE,UACA,8BAA8BN,EAAU,OAAO,YAC/CA,EAAU,KAAK,MAAOI,EAAG,IAAI,CAAC,CAAC,KAAK,IAAI,CAC1C,GAGF,MAAM,QAAQ,IAAIF,CAAI;AACxB"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
//#region src/features/ingestion/imageHandler.ts
|
|
2
|
+
var e = .9, t = async (e) => {
|
|
3
|
+
let t = await createImageBitmap(e), n = {
|
|
4
|
+
width: t.width,
|
|
5
|
+
height: t.height
|
|
6
|
+
};
|
|
7
|
+
return t.close(), n;
|
|
8
|
+
}, n = (e) => new Promise((t, n) => {
|
|
9
|
+
let r = new FileReader();
|
|
10
|
+
r.onload = () => t(r.result), r.onerror = () => n(r.error), r.readAsDataURL(e);
|
|
11
|
+
}), r = t, i = n;
|
|
12
|
+
async function a(t, n, a = {}) {
|
|
13
|
+
let o = 0;
|
|
14
|
+
for (let s of t) try {
|
|
15
|
+
let t = await (a.measure ?? r)(s), c = n.resolveSrc ? await n.resolveSrc(s) : await i(s);
|
|
16
|
+
!n.resolveSrc && a.mimeOverride && (c = c.replace(/^data:[^;,]*/, `data:${a.mimeOverride}`));
|
|
17
|
+
let l = n.viewportWorldRect(), u = Math.min(1, l.width * e / t.width, l.height * e / t.height), d = t.width * u, f = t.height * u, p = n.point ?? {
|
|
18
|
+
x: l.x + l.width / 2,
|
|
19
|
+
y: l.y + l.height / 2
|
|
20
|
+
}, m = o * 24;
|
|
21
|
+
n.insert.commit({
|
|
22
|
+
x: p.x - d / 2 + m,
|
|
23
|
+
y: p.y - f / 2 + m,
|
|
24
|
+
width: d,
|
|
25
|
+
height: f
|
|
26
|
+
}, {
|
|
27
|
+
kind: "image",
|
|
28
|
+
src: c
|
|
29
|
+
}), o++;
|
|
30
|
+
} catch (e) {
|
|
31
|
+
console.warn(`weasel ingest: image "${s.name}" failed to load`, e);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
var o = {
|
|
35
|
+
id: "kit:image",
|
|
36
|
+
match: (e) => e.kind === "file" && e.mime.startsWith("image/"),
|
|
37
|
+
priority: -100,
|
|
38
|
+
handle(e, t) {
|
|
39
|
+
return a(e.flatMap((e) => e.kind === "file" ? [e.file] : []), t);
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
//#endregion
|
|
43
|
+
export { a as embedFilesAsImageNodes, o as kitImageHandler };
|
|
44
|
+
|
|
45
|
+
//# sourceMappingURL=imageHandler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"imageHandler.js","names":["VIEWPORT_FIT","defaultMeasure","bitmap","file","size","defaultToDataUri","reader","resolve","reject","measure","toDataUri","embedFilesAsImageNodes","index","files","natural","opts","src","ctx","view","scale","width","height","center","offset","err","kitImageHandler","item","items","it"],"sources":["../../../src/features/ingestion/imageHandler.ts"],"sourcesContent":["/**\n * The kit's `image/*` content handler — the one handler shipped by default.\n *\n * For each image file: resolve a `src` (consumer `resolveSrc` when provided,\n * else embed as a `data:` URI so the scene stays serializable), measure the\n * natural pixel size, fit-clamp to 90% of the visible viewport, and insert a\n * leaf node with `data.image = { src }` via the insert dep (id/layer/undoable\n * op supplied there — same contract as `useImageTool`).\n *\n * Placement: centered on `ctx.point` (drop / pointed ingest) or the viewport\n * center (paste / point-less). Multi-file ingests cascade by a fixed offset.\n *\n * Registered at priority -100 so any consumer handler (default 0) can take\n * image files first.\n */\nimport type { ContentHandlerEntry, IngestCtx } from './contentHandlers';\nimport type { IngestItem } from '@weasel-js/routing';\n\nconst CASCADE_OFFSET_PX = 24;\nconst VIEWPORT_FIT = 0.9;\n\nexport type Measure = (file: File) => Promise<{ width: number; height: number }>;\ntype ToDataUri = (file: File) => Promise<string>;\n\nconst defaultMeasure: Measure = async (file) => {\n const bitmap = await createImageBitmap(file);\n const size = { width: bitmap.width, height: bitmap.height };\n bitmap.close();\n return size;\n};\n\nconst defaultToDataUri: ToDataUri = (file) =>\n new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onload = () => resolve(reader.result as string);\n reader.onerror = () => reject(reader.error);\n reader.readAsDataURL(file);\n });\n\nlet measure: Measure = defaultMeasure;\nlet toDataUri: ToDataUri = defaultToDataUri;\n\n/** @internal Options for {@link embedFilesAsImageNodes} — used by the kit\n * SVG handler, whose files can't go through `createImageBitmap`. */\nexport interface EmbedImageOptions {\n /** Replace the raster measurer for these files (the SVG handler supplies\n * an `Image`-element one). Defaults to the module measurer (seam-aware). */\n measure?: Measure;\n /** Force the data-URI MIME. A sniffed `.svg` whose `File.type` was empty\n * would otherwise embed as `data:application/octet-stream;…`, which\n * browsers refuse to rasterize. No effect on `resolveSrc` output. */\n mimeOverride?: string;\n}\n\n/**\n * @internal The shared embed engine: for each file, measure → resolve a\n * `src` → fit-clamp to 90% of the visible viewport → insert one image node\n * centered on `ctx.point` (or the viewport center), cascading multi-file\n * batches by a fixed offset. A file that fails to measure or resolve is\n * skipped with a `console.warn`; the rest proceed.\n */\nexport async function embedFilesAsImageNodes(\n files: File[],\n ctx: IngestCtx,\n opts: EmbedImageOptions = {},\n): Promise<void> {\n let index = 0;\n for (const file of files) {\n try {\n // Measure first: a corrupt file should fail cheaply here, not after\n // a consumer `resolveSrc` has already uploaded it somewhere.\n const natural = await (opts.measure ?? measure)(file);\n let src = ctx.resolveSrc ? await ctx.resolveSrc(file) : await toDataUri(file);\n if (!ctx.resolveSrc && opts.mimeOverride) {\n src = src.replace(/^data:[^;,]*/, `data:${opts.mimeOverride}`);\n }\n const view = ctx.viewportWorldRect();\n const scale = Math.min(\n 1,\n (view.width * VIEWPORT_FIT) / natural.width,\n (view.height * VIEWPORT_FIT) / natural.height,\n );\n const width = natural.width * scale;\n const height = natural.height * scale;\n const center = ctx.point ?? {\n x: view.x + view.width / 2,\n y: view.y + view.height / 2,\n };\n const offset = index * CASCADE_OFFSET_PX;\n ctx.insert.commit(\n {\n x: center.x - width / 2 + offset,\n y: center.y - height / 2 + offset,\n width,\n height,\n },\n { kind: 'image', src },\n );\n index++;\n } catch (err) {\n console.warn(`weasel ingest: image \"${file.name}\" failed to load`, err);\n }\n }\n}\n\nexport const kitImageHandler: ContentHandlerEntry = {\n id: 'kit:image',\n match: (item: IngestItem) => item.kind === 'file' && item.mime.startsWith('image/'),\n priority: -100,\n handle(items, ctx: IngestCtx) {\n const files = items.flatMap((it) => (it.kind === 'file' ? [it.file] : []));\n return embedFilesAsImageNodes(files, ctx);\n },\n};\n\n/** @internal test seam — override the bitmap measurer (jsdom has no\n * `createImageBitmap`). Not part of the public barrel. */\nexport function __setImageMeasureForTests(fn: Measure): void {\n measure = fn;\n}\n\n/** @internal test seam — override the FileReader embed. */\nexport function __setFileToDataUriForTests(fn: ToDataUri): void {\n toDataUri = fn;\n}\n\n/** @internal test seam — restore default seams. */\nexport function _resetImageHandlerSeamsForTests(): void {\n measure = defaultMeasure;\n toDataUri = defaultToDataUri;\n}\n"],"mappings":";AAkBA,IACMA,IAAe,IAKfC,IAA0B,OAAO,MAAS;CAC9C,IAAMC,IAAS,MAAM,kBAAkBC,CAAI,GACrCC,IAAO;EAAE,OAAOF,EAAO;EAAO,QAAQA,EAAO;CAAO;CAE1D,OADAA,EAAO,MAAM,GACNE;AACT,GAEMC,KAA+B,MACnC,IAAI,SAAS,GAAS,MAAW;CAC/B,IAAMC,IAAS,IAAI,WAAW;CAG9B,AAFA,EAAO,eAAeC,EAAQD,EAAO,MAAgB,GACrD,EAAO,gBAAgBE,EAAOF,EAAO,KAAK,GAC1CA,EAAO,cAAcH,CAAI;AAC3B,CAAC,GAECM,IAAmBR,GACnBS,IAAuBL;AAqB3B,eAAsBM,EACpB,GACA,GACA,IAA0B,CAAC,GACZ;CACf,IAAIC,IAAQ;CACZ,KAAK,IAAMT,KAAQU,GACjB,IAAI;EAGF,IAAMC,IAAU,OAAOC,EAAK,WAAWN,EAAA,CAASN,CAAI,GAChDa,IAAMC,EAAI,aAAa,MAAMA,EAAI,WAAWd,CAAI,IAAI,MAAMO,EAAUP,CAAI;EAC5E,AAAI,CAACc,EAAI,cAAcF,EAAK,iBAC1B,IAAMC,EAAI,QAAQ,gBAAgB,QAAQD,EAAK,cAAc;EAE/D,IAAMG,IAAOD,EAAI,kBAAkB,GAC7BE,IAAQ,KAAK,IACjB,GACCD,EAAK,QAAQlB,IAAgBc,EAAQ,OACrCI,EAAK,SAASlB,IAAgBc,EAAQ,MACzC,GACMM,IAAQN,EAAQ,QAAQK,GACxBE,IAASP,EAAQ,SAASK,GAC1BG,IAASL,EAAI,SAAS;GAC1B,GAAGC,EAAK,IAAIA,EAAK,QAAQ;GACzB,GAAGA,EAAK,IAAIA,EAAK,SAAS;EAC5B,GACMK,IAASX,IAAQ;EAUvB,AATAK,EAAI,OAAO,OACT;GACE,GAAGK,EAAO,IAAIF,IAAQ,IAAIG;GAC1B,GAAGD,EAAO,IAAID,IAAS,IAAIE;GAC3B;GACA;EACF,GACA;GAAE,MAAM;GAAS;EAAI,CACvB,GACA;CACF,SAASC,GAAK;EACZ,QAAQ,KAAK,yBAAyBrB,EAAK,KAAK,mBAAmBqB,CAAG;CACxE;AAEJ;AAEA,IAAaC,IAAuC;CAClD,IAAI;CACJ,QAAQ,MAAqBC,EAAK,SAAS,UAAUA,EAAK,KAAK,WAAW,QAAQ;CAClF,UAAU;CACV,OAAO,GAAO,GAAgB;EAE5B,OAAOf,EADOgB,EAAM,SAAS,MAAQC,EAAG,SAAS,SAAS,CAACA,EAAG,IAAI,IAAI,CAAC,CACzC,GAAOX,CAAG;CAC1C;AACF"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { registerContentHandler as e } from "./contentHandlers.js";
|
|
2
|
+
import "./imageHandler.js";
|
|
3
|
+
import "./svgHandler.js";
|
|
4
|
+
import "./weaselJsonHandler.js";
|
|
5
|
+
import { acquireKitContentHandlers as t } from "./registerKitHandlers.js";
|
|
6
|
+
import { openFilePicker as n } from "./openFilePicker.js";
|
|
7
|
+
import { itemsFromFiles as r } from "@weasel-js/routing";
|
|
8
|
+
export { t as acquireKitContentHandlers, r as itemsFromFiles, n as openFilePicker, e as registerContentHandler };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
//#region src/features/ingestion/openFilePicker.ts
|
|
2
|
+
function e(e = {}) {
|
|
3
|
+
return new Promise((t) => {
|
|
4
|
+
let n = document.createElement("input");
|
|
5
|
+
n.type = "file", n.hidden = !0, e.accept && (n.accept = e.accept), e.multiple && (n.multiple = !0), document.body.appendChild(n);
|
|
6
|
+
let r = (e) => {
|
|
7
|
+
n.remove(), t(e);
|
|
8
|
+
};
|
|
9
|
+
n.addEventListener("change", () => r(Array.from(n.files ?? [])), { once: !0 }), n.addEventListener("cancel", () => r([]), { once: !0 }), n.click();
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
//#endregion
|
|
13
|
+
export { e as openFilePicker };
|
|
14
|
+
|
|
15
|
+
//# sourceMappingURL=openFilePicker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openFilePicker.js","names":["openFilePicker","input","opts","finish","resolve","files"],"sources":["../../../src/features/ingestion/openFilePicker.ts"],"sourcesContent":["/**\n * `openFilePicker` — tiny DOM helper opening the OS file dialog and resolving\n * the chosen `File[]` ([] on cancel). Pairs with `CanvasExtensionApi.ingest`:\n *\n * ```ts\n * const files = await openFilePicker({ accept: 'image/*', multiple: true });\n * canvasRef.current?.ingest(files);\n * ```\n *\n * Must be called from a user-activation context (a click handler) — browsers\n * block programmatic `input.click()` otherwise.\n */\nexport interface OpenFilePickerOptions {\n /** `<input accept>` filter, e.g. `'image/*'` or `'.csv,text/csv'`. */\n accept?: string;\n /** Allow multi-select. Default false. */\n multiple?: boolean;\n}\n\n/** Show the browser's file picker and resolve with what the user chose —\n * empty when they cancel. Must be called from a user gesture. */\nexport function openFilePicker(opts: OpenFilePickerOptions = {}): Promise<File[]> {\n return new Promise((resolve) => {\n const input = document.createElement('input');\n input.type = 'file';\n input.hidden = true;\n if (opts.accept) input.accept = opts.accept;\n if (opts.multiple) input.multiple = true;\n document.body.appendChild(input);\n const finish = (files: File[]) => {\n input.remove();\n resolve(files);\n };\n input.addEventListener('change', () => finish(Array.from(input.files ?? [])), { once: true });\n // Fired by browsers that support it when the dialog is dismissed. When\n // unsupported, the input simply leaks until the page unloads — acceptable\n // for a hidden element; no timer heuristics.\n input.addEventListener('cancel', () => finish([]), { once: true });\n input.click();\n });\n}\n"],"mappings":";AAqBA,SAAgBA,EAAe,IAA8B,CAAC,GAAoB;CAChF,OAAO,IAAI,SAAS,MAAY;EAC9B,IAAMC,IAAQ,SAAS,cAAc,OAAO;EAK5C,AAJA,EAAM,OAAO,QACb,EAAM,SAAS,IACXC,EAAK,WAAQ,EAAM,SAASA,EAAK,SACjCA,EAAK,aAAU,EAAM,WAAW,KACpC,SAAS,KAAK,YAAYD,CAAK;EAC/B,IAAME,KAAU,MAAkB;GAEhC,AADAF,EAAM,OAAO,GACbG,EAAQC,CAAK;EACf;EAMA,AALAJ,EAAM,iBAAiB,gBAAgBE,EAAO,MAAM,KAAKF,EAAM,SAAS,CAAC,CAAC,CAAC,GAAG,EAAE,MAAM,GAAK,CAAC,GAI5FA,EAAM,iBAAiB,gBAAgBE,EAAO,CAAC,CAAC,GAAG,EAAE,MAAM,GAAK,CAAC,GACjEF,EAAM,MAAM;CACd,CAAC;AACH"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { registerContentHandler as e } from "./contentHandlers.js";
|
|
2
|
+
import { kitImageHandler as t } from "./imageHandler.js";
|
|
3
|
+
import { kitSvgHandler as n } from "./svgHandler.js";
|
|
4
|
+
import { kitWeaselJsonHandler as r } from "./weaselJsonHandler.js";
|
|
5
|
+
//#region src/features/ingestion/registerKitHandlers.ts
|
|
6
|
+
var i = 0, a = null;
|
|
7
|
+
function o() {
|
|
8
|
+
if (i++, i === 1) {
|
|
9
|
+
let i = [
|
|
10
|
+
t,
|
|
11
|
+
n,
|
|
12
|
+
r
|
|
13
|
+
].map(e);
|
|
14
|
+
a = () => {
|
|
15
|
+
for (let e of i) e();
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
let o = !1;
|
|
19
|
+
return () => {
|
|
20
|
+
o || (o = !0, i--, i === 0 && (a?.(), a = null));
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
//#endregion
|
|
24
|
+
export { o as acquireKitContentHandlers };
|
|
25
|
+
|
|
26
|
+
//# sourceMappingURL=registerKitHandlers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registerKitHandlers.js","names":["refs","dispose","acquireKitContentHandlers","disposers","kitImageHandler","kitSvgHandler","kitWeaselJsonHandler","registerContentHandler","d","released"],"sources":["../../../src/features/ingestion/registerKitHandlers.ts"],"sourcesContent":["/**\n * Refcounted registration of the kit's default content handlers.\n * Each mounted `<SceneCanvas>` calls this on mount and disposes on unmount;\n * the kit handlers stay registered while at least one canvas is up. (A naive\n * skip-if-present would break the two-canvas case: if the mount that\n * registered `kit:image` unmounts first, the survivor would lose its image\n * handler.)\n */\nimport { registerContentHandler } from './contentHandlers';\nimport { kitImageHandler } from './imageHandler';\nimport { kitSvgHandler } from './svgHandler';\nimport { kitWeaselJsonHandler } from './weaselJsonHandler';\n\nlet refs = 0;\nlet dispose: (() => void) | null = null;\n\nexport function acquireKitContentHandlers(): () => void {\n refs++;\n if (refs === 1) {\n const disposers = [kitImageHandler, kitSvgHandler, kitWeaselJsonHandler].map(registerContentHandler);\n dispose = () => { for (const d of disposers) d(); };\n }\n let released = false;\n return () => {\n if (released) return;\n released = true;\n refs--;\n if (refs === 0) {\n dispose?.();\n dispose = null;\n }\n };\n}\n\n/** @internal test seam. */\nexport function _resetKitContentHandlersForTests(): void {\n refs = 0;\n dispose = null;\n}\n"],"mappings":";;;;;AAaA,IAAIA,IAAO,GACPC,IAA+B;AAEnC,SAAgBC,IAAwC;CAEtD,IADA,KACIF,MAAS,GAAG;EACd,IAAMG,IAAY;GAACC;GAAiBC;GAAeC;EAAoB,CAAC,CAAC,IAAIC,CAAsB;EACnG,UAAgB;GAAE,KAAK,IAAMC,KAAKL,GAAW,EAAE;EAAG;CACpD;CACA,IAAIM,IAAW;CACf,aAAa;EACX,AAAIA,MACJ,IAAW,IACX,KACIT,MAAS,MACXC,IAAU,GACV,IAAU;CAEd;AACF"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { embedFilesAsImageNodes as e } from "./imageHandler.js";
|
|
2
|
+
//#region src/features/ingestion/svgHandler.ts
|
|
3
|
+
var t = "image/svg+xml", n = 300, r = 150;
|
|
4
|
+
function i(e) {
|
|
5
|
+
return e.kind === "file" ? e.mime === t || e.mime === "application/octet-stream" && /\.svg$/i.test(e.file.name) : !1;
|
|
6
|
+
}
|
|
7
|
+
function a(e) {
|
|
8
|
+
let t = e.trimStart();
|
|
9
|
+
if (t.startsWith("<?xml")) {
|
|
10
|
+
let e = t.indexOf("?>");
|
|
11
|
+
if (e < 0) return !1;
|
|
12
|
+
t = t.slice(e + 2);
|
|
13
|
+
}
|
|
14
|
+
for (;;) {
|
|
15
|
+
if (t = t.trimStart(), t.startsWith("<!--")) {
|
|
16
|
+
let e = t.indexOf("-->");
|
|
17
|
+
if (e < 0) return !1;
|
|
18
|
+
t = t.slice(e + 3);
|
|
19
|
+
continue;
|
|
20
|
+
}
|
|
21
|
+
if (/^<!doctype/i.test(t)) {
|
|
22
|
+
let e = t.indexOf(">");
|
|
23
|
+
if (e < 0) return !1;
|
|
24
|
+
t = t.slice(e + 1);
|
|
25
|
+
continue;
|
|
26
|
+
}
|
|
27
|
+
break;
|
|
28
|
+
}
|
|
29
|
+
return /^<svg[\s>/]/i.test(t);
|
|
30
|
+
}
|
|
31
|
+
var o = async (e) => {
|
|
32
|
+
let t = URL.createObjectURL(e);
|
|
33
|
+
try {
|
|
34
|
+
let e = new Image();
|
|
35
|
+
return e.src = t, await e.decode(), {
|
|
36
|
+
width: e.naturalWidth || n,
|
|
37
|
+
height: e.naturalHeight || r
|
|
38
|
+
};
|
|
39
|
+
} finally {
|
|
40
|
+
URL.revokeObjectURL(t);
|
|
41
|
+
}
|
|
42
|
+
}, s = {
|
|
43
|
+
id: "kit:svg",
|
|
44
|
+
match: (e) => i(e) || e.kind === "string" && e.mime === "text/plain" && a(e.text),
|
|
45
|
+
priority: -90,
|
|
46
|
+
handle(n, r) {
|
|
47
|
+
let i = n.flatMap((e) => e.kind === "file" ? [e.file] : []);
|
|
48
|
+
if (!r.consumedWeaselPayload) for (let e of n) e.kind === "string" && i.push(new File([e.text], "pasted.svg", { type: t }));
|
|
49
|
+
if (i.length !== 0) return r.svg?.unpack ? r.svg.unpack(i, r) : e(i, r, {
|
|
50
|
+
measure: (e) => o(e),
|
|
51
|
+
mimeOverride: t
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
//#endregion
|
|
56
|
+
export { t as SVG_MIME, i as isSvgFileItem, s as kitSvgHandler, a as sniffSvgText };
|
|
57
|
+
|
|
58
|
+
//# sourceMappingURL=svgHandler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"svgHandler.js","names":["SVG_MIME","FALLBACK_WIDTH","FALLBACK_HEIGHT","isSvgFileItem","item","sniffSvgText","text","end","measure","url","file","img","kitSvgHandler","files","items","it","ctx","embedFilesAsImageNodes","f"],"sources":["../../../src/features/ingestion/svgHandler.ts"],"sourcesContent":["/**\n * The kit's `image/svg+xml` content handler.\n *\n * Default: a dropped SVG stays **one scene node** — the standard\n * embedded-image contract (`data.image.src` as a `data:image/svg+xml;…`\n * URI, source bytes preserved verbatim). Rendering rides the normal\n * `imageCache` path: browsers rasterize SVG in an `<img>`, so only the\n * ingest-time measurement needs special handling — Chromium's\n * `createImageBitmap` rejects raw SVG blobs, so this handler measures via\n * an `Image` element instead, falling back to 300×150 (the CSS default\n * object size) when the file declares no intrinsic dimensions.\n *\n * `<SceneCanvas ingestion={{ svg: { unpack: unpackSvgFiles } }}>` switches to\n * parsing the file into native scene nodes. The unpacker is injected (see\n * `SvgIngestOptions.unpack`) because the SVG parser lives in\n * `@weasel-js/svg`, which depends on this package.\n *\n * Registered at priority -90: ahead of `kit:image` (-100) so SVG files\n * never hit the raster measure path, still behind any consumer handler\n * (default 0).\n */\nimport type { ContentHandlerEntry, IngestCtx } from './contentHandlers';\nimport type { IngestItem } from '@weasel-js/routing';\nimport { embedFilesAsImageNodes, type Measure } from './imageHandler';\n\nexport const SVG_MIME = 'image/svg+xml';\n\n// CSS default object size — what browsers use for replaced content with no\n// intrinsic dimensions (e.g. a viewBox-only SVG in an <img>).\nconst FALLBACK_WIDTH = 300;\nconst FALLBACK_HEIGHT = 150;\n\n/**\n * True for file items that are SVG by MIME — or by `.svg` extension when\n * the source offered no usable type (an empty `File.type` normalizes to\n * `application/octet-stream` at materialization).\n */\nexport function isSvgFileItem(item: IngestItem): boolean {\n if (item.kind !== 'file') return false;\n if (item.mime === SVG_MIME) return true;\n return item.mime === 'application/octet-stream' && /\\.svg$/i.test(item.file.name);\n}\n\n/**\n * Strict-prefix sniff: could this text be an SVG document? `<svg` (or an XML\n * declaration, then optional whitespace/comments/DOCTYPE, then `<svg`) must\n * open the document — no mid-document substring scans, same discipline as\n * `sniffWeaselClipboardText`. Exists because Safari drops both custom MIMEs\n * and `image/svg+xml` from async clipboard writes, leaving `text/plain` as\n * the only surviving flavor of an SVG copy.\n */\nexport function sniffSvgText(text: string): boolean {\n let t = text.trimStart();\n if (t.startsWith('<?xml')) {\n const end = t.indexOf('?>');\n if (end < 0) return false;\n t = t.slice(end + 2);\n }\n for (;;) {\n t = t.trimStart();\n if (t.startsWith('<!--')) {\n const end = t.indexOf('-->');\n if (end < 0) return false;\n t = t.slice(end + 3);\n continue;\n }\n // Illustrator-style preamble: <!DOCTYPE svg PUBLIC \"...\" \"...\">. Skipping\n // ANY doctype is safe — a non-SVG doctype's root element fails the final\n // `<svg` check anyway. (No internal-subset handling; clipboard SVG\n // preambles don't carry `[...]` blocks.)\n if (/^<!doctype/i.test(t)) {\n const end = t.indexOf('>');\n if (end < 0) return false;\n t = t.slice(end + 1);\n continue;\n }\n break;\n }\n return /^<svg[\\s>/]/i.test(t);\n}\n\nconst defaultMeasure: Measure = async (file) => {\n const url = URL.createObjectURL(file);\n try {\n const img = new Image();\n img.src = url;\n await img.decode();\n return {\n width: img.naturalWidth || FALLBACK_WIDTH,\n height: img.naturalHeight || FALLBACK_HEIGHT,\n };\n } finally {\n URL.revokeObjectURL(url);\n }\n};\n\nlet measure: Measure = defaultMeasure;\n\nexport const kitSvgHandler: ContentHandlerEntry = {\n id: 'kit:svg',\n // Files by MIME/extension, plus the text/plain fallback flavor: SVG markup\n // pasted as plain text (the only flavor Safari lets an SVG copy keep).\n match: (item) =>\n isSvgFileItem(item)\n || (item.kind === 'string' && item.mime === 'text/plain' && sniffSvgText(item.text)),\n priority: -90,\n handle(items, ctx: IngestCtx) {\n const files = items.flatMap((it) => (it.kind === 'file' ? [it.file] : []));\n // String items (the text/plain SVG fallback flavor) enter the same file\n // path — wrap the markup in a File so unpack/embed stays one code path.\n // BUT skip them when the weasel-JSON handler already pasted this event's\n // copy: draw writes weasel-JSON + SVG together, so ingesting both would\n // double-paste. (ctx is shared per event; the weasel handler runs first.)\n // WARNING: this read must stay before any `await` in this handle — the\n // sync-ordering of handler microtasks is what makes the flag visible.\n if (!ctx.consumedWeaselPayload) {\n for (const it of items) {\n if (it.kind === 'string') files.push(new File([it.text], 'pasted.svg', { type: SVG_MIME }));\n }\n }\n if (files.length === 0) return;\n if (ctx.svg?.unpack) return ctx.svg.unpack(files, ctx);\n // Thunk (not the variable) so the test seam is read at call time.\n return embedFilesAsImageNodes(files, ctx, {\n measure: (f) => measure(f),\n mimeOverride: SVG_MIME,\n });\n },\n};\n\n/** @internal test seam — override the Image-element measurer (jsdom can't\n * decode SVG). Not part of the public barrel. */\nexport function __setSvgMeasureForTests(fn: Measure): void {\n measure = fn;\n}\n\n/** @internal test seam — restore the default measurer. */\nexport function _resetSvgHandlerSeamsForTests(): void {\n measure = defaultMeasure;\n}\n"],"mappings":";;AAyBA,IAAaA,IAAW,iBAIlBC,IAAiB,KACjBC,IAAkB;AAOxB,SAAgBC,EAAc,GAA2B;CAGvD,OAFIC,EAAK,SAAS,SACdA,EAAK,SAASJ,KACXI,EAAK,SAAS,8BAA8B,UAAU,KAAKA,EAAK,KAAK,IAAI,IAF/C;AAGnC;AAUA,SAAgBC,EAAa,GAAuB;CAClD,IAAI,IAAIC,EAAK,UAAU;CACvB,IAAI,EAAE,WAAW,OAAO,GAAG;EACzB,IAAMC,IAAM,EAAE,QAAQ,IAAI;EAC1B,IAAIA,IAAM,GAAG,OAAO;EACpB,IAAI,EAAE,MAAMA,IAAM,CAAC;CACrB;CACA,SAAS;EAEP,IADA,IAAI,EAAE,UAAU,GACZ,EAAE,WAAW,MAAM,GAAG;GACxB,IAAMA,IAAM,EAAE,QAAQ,KAAK;GAC3B,IAAIA,IAAM,GAAG,OAAO;GACpB,IAAI,EAAE,MAAMA,IAAM,CAAC;GACnB;EACF;EAKA,IAAI,cAAc,KAAK,CAAC,GAAG;GACzB,IAAMA,IAAM,EAAE,QAAQ,GAAG;GACzB,IAAIA,IAAM,GAAG,OAAO;GACpB,IAAI,EAAE,MAAMA,IAAM,CAAC;GACnB;EACF;EACA;CACF;CACA,OAAO,eAAe,KAAK,CAAC;AAC9B;AAiBA,IAAIC,IAAmB,OAfgB,MAAS;CAC9C,IAAMC,IAAM,IAAI,gBAAgBC,CAAI;CACpC,IAAI;EACF,IAAMC,IAAM,IAAI,MAAM;EAGtB,OAFA,EAAI,MAAMF,GACV,MAAME,EAAI,OAAO,GACV;GACL,OAAOA,EAAI,gBAAgBV;GAC3B,QAAQU,EAAI,iBAAiBT;EAC/B;CACF,UAAU;EACR,IAAI,gBAAgBO,CAAG;CACzB;AACF,GAIaG,IAAqC;CAChD,IAAI;CAGJ,QAAQ,MACNT,EAAcC,CAAI,KACdA,EAAK,SAAS,YAAYA,EAAK,SAAS,gBAAgBC,EAAaD,EAAK,IAAI;CACpF,UAAU;CACV,OAAO,GAAO,GAAgB;EAC5B,IAAMS,IAAQC,EAAM,SAAS,MAAQC,EAAG,SAAS,SAAS,CAACA,EAAG,IAAI,IAAI,CAAC,CAAE;EAQzE,IAAI,CAACC,EAAI,uBACF,KAAA,IAAMD,KAAMD,GACf,AAAIC,EAAG,SAAS,YAAUF,EAAM,KAAK,IAAI,KAAK,CAACE,EAAG,IAAI,GAAG,cAAc,EAAE,MAAMf,EAAS,CAAC,CAAC;EAG9F,IAAIa,EAAM,WAAW,GAGrB,OAFIG,EAAI,KAAK,SAAeA,EAAI,IAAI,OAAOH,GAAOG,CAAG,IAE9CC,EAAuBJ,GAAOG,GAAK;GACxC,UAAU,MAAMR,EAAQU,CAAC;GACzB,cAAclB;EAChB,CAAC;CACH;AACF"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { dwarn as e } from "../../debug/flag.js";
|
|
2
|
+
import { sniffSvgText as t } from "./svgHandler.js";
|
|
3
|
+
import { materializePaste as n } from "../../interactions/actions/clipboard/materializePaste.js";
|
|
4
|
+
import { WEASEL_CLIPBOARD_MIME as r, WEASEL_CLIPBOARD_MIME_WEB as i, extractWeaselClipboardFromSvg as a, parseWeaselClipboardText as o, sniffWeaselClipboardText as s } from "../../interactions/actions/clipboard/wireFormat.js";
|
|
5
|
+
//#region src/features/ingestion/weaselJsonHandler.ts
|
|
6
|
+
var c = (e) => e.includes("\"weaselClipboard\"") && t(e) && a(e) !== null, l = {
|
|
7
|
+
id: "kit:weasel-json",
|
|
8
|
+
priority: -50,
|
|
9
|
+
match: (e) => e.kind === "string" && (e.mime === r || e.mime === i || e.mime === "text/plain" && (s(e.text) || c(e.text))),
|
|
10
|
+
handle(r, i) {
|
|
11
|
+
let s = i.clipboard;
|
|
12
|
+
if (!s) {
|
|
13
|
+
e("clipboard", "weasel payload arrived but ctx.clipboard is not wired (ingestion.clipboard disabled or absent) — declining");
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
if (!s.adapter.commitPaste) {
|
|
17
|
+
e("clipboard", "weasel payload arrived but the clipboard adapter lacks commitPaste — declining");
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
let c = r.find((e) => e.kind === "string");
|
|
21
|
+
if (!c || c.kind !== "string") return;
|
|
22
|
+
let l = t(c.text) ? a(c.text) : c.text;
|
|
23
|
+
if (l === null) {
|
|
24
|
+
e("clipboard", "weasel payload vanished from the SVG metadata between match and handle — declining");
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
let u = o(l, s.reviver);
|
|
28
|
+
if (u === null) {
|
|
29
|
+
e("clipboard", "weasel payload unusable — declining (see prior warning if the parse threw)");
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
let d = { items: u }, f = n(s.adapter, d, { currentSelection: i.selection.get() });
|
|
33
|
+
f && (i.applyOps(f.ops, "Paste"), i.selection.set(f.newIds), i.consumedWeaselPayload = !0);
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
//#endregion
|
|
37
|
+
export { l as kitWeaselJsonHandler };
|
|
38
|
+
|
|
39
|
+
//# sourceMappingURL=weaselJsonHandler.js.map
|