@neta-art/cohub 11.3.3 → 11.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/README.md +25 -0
  2. package/dist/board/editor/clipboard.js +1 -1
  3. package/dist/board/editor/creation.js +1 -1
  4. package/dist/board/editor/editor.js +2 -2
  5. package/dist/board/editor/selection.js +1 -1
  6. package/dist/board/export/index.js +1 -1
  7. package/dist/board/export/node/scripts.js +1 -1
  8. package/dist/board/export/scene.js +1 -1
  9. package/dist/board/model/index.js +15 -15
  10. package/dist/board/model/items/create.js +1 -1
  11. package/dist/board/model/sampling.js +1 -1
  12. package/dist/board/render/media-interaction.js +1 -1
  13. package/dist/board/render/renderers/arrow-card-renderer.js +1 -1
  14. package/dist/board/render/renderers/audio-card-renderer.js +1 -1
  15. package/dist/board/render/renderers/draw-card-renderer.js +1 -1
  16. package/dist/board/render/renderers/file-card-renderer.js +2 -2
  17. package/dist/board/render/renderers/model-card-renderer.js +3 -3
  18. package/dist/board/render/renderers/text-card-renderer.js +1 -1
  19. package/dist/board/render/renderers/video-card-renderer.js +1 -1
  20. package/dist/board/render/script-export.js +1 -1
  21. package/dist/board/render/script-host.js +1 -1
  22. package/dist/board/stage/assets.js +1 -1
  23. package/dist/board/stage/index.d.ts +2 -1
  24. package/dist/board/stage/index.js +2 -1
  25. package/dist/board/stage/pointer-gestures.d.ts +12 -0
  26. package/dist/board/stage/pointer-gestures.js +63 -0
  27. package/dist/board/stage/stage.js +23 -17
  28. package/dist/chunks/environment.d.ts +3959 -3882
  29. package/dist/chunks/http.d.ts +58 -3
  30. package/dist/chunks/http.js +84 -14
  31. package/dist/chunks/websocket.d.ts +1 -1
  32. package/dist/http.d.ts +3 -3
  33. package/dist/index.d.ts +83 -83
  34. package/dist/protocol/dist/board-patch.js +1 -1
  35. package/package.json +1 -1
package/README.md CHANGED
@@ -218,6 +218,12 @@ editor.addItem("acme.order", { at: editor.viewCenter(), props: { orderId: "o-1",
218
218
  // React: const selection = useSyncExternalStore((fn) => editor.subscribe("selection", fn), () => editor.selection);
219
219
  ```
220
220
 
221
+ For draggable DOM item views, use `createBoardPointerGestures(element, { move, end })`
222
+ from `board/stage`: call `start(event)` for accepted pointer downs and `cancel()`
223
+ on unmount. It follows active pointers outside the element, preserves mouse gestures
224
+ when capture is lost, and cancels on window blur or page hide. Forward events through
225
+ `context.toPointerEvent` to the editor; keep hover handling separate from active gestures.
226
+
221
227
  Items of a type the client does not know still render as a placeholder, move
222
228
  and keep every field, so documents written by newer clients are never
223
229
  rewritten by older ones. For a canvas look instead of DOM, pass renderers to
@@ -257,6 +263,25 @@ const stop = session.subscribe({
257
263
  stop();
258
264
  ```
259
265
 
266
+ ## Space wallets
267
+
268
+ ```ts
269
+ const wallet = client.space(spaceId).wallet;
270
+ const balance = await wallet.get();
271
+ const catalog = await wallet.catalog();
272
+ const activity = await wallet.activities(1);
273
+ const { checkout, orderId } = await wallet.createOrder({
274
+ id: crypto.randomUUID(), // Persist and reuse this ID when retrying.
275
+ productKey,
276
+ });
277
+ const confirmation = await wallet.confirmOrder(orderId);
278
+ ```
279
+
280
+ Open `checkout.checkoutUrl` to pay. Confirmation requires the contributor's
281
+ session; a payment redirect is not proof of settlement. Space funds pay whole
282
+ usage charges when sufficient, otherwise the original user's balance is used.
283
+ Personal balance transfers and withdrawals are not supported.
284
+
260
285
  ## Apps and the App runtime
261
286
 
262
287
  An **App** (previously *Work*) is a published, shareable web page hosted by
@@ -1,6 +1,6 @@
1
1
  import { parseBoardItem } from "../../protocol/dist/board-model.js";
2
- import { arrowBindings, isArrowBinding } from "../../protocol/dist/board-layout.js";
3
2
  import { BOARD_CLIPBOARD_KIND, BOARD_CLIPBOARD_MIME } from "../../protocol/dist/board.js";
3
+ import { arrowBindings, isArrowBinding } from "../../protocol/dist/board-layout.js";
4
4
  import { createBoardItemId } from "../model/items/id.js";
5
5
  //#region src/board/editor/clipboard.ts
6
6
  /** How far a duplicate or repeated paste lands from its source. */
@@ -1,6 +1,6 @@
1
1
  import { IDENTITY_MATRIX, applyMatrix, invertMatrix } from "../../protocol/dist/board-layout.js";
2
- import { rectCenter } from "../model/geometry.js";
3
2
  import { buildBoardScene } from "../model/scene.js";
3
+ import { rectCenter } from "../model/geometry.js";
4
4
  import { isShapeKind } from "../model/shape-types.js";
5
5
  import { createBoardItemId } from "../model/items/id.js";
6
6
  import { createAppBoardItem, createArrowBoardItem, createDrawBoardItem, createFileNodeForPath, createFrameBoardItem, createMediaBoardItem, createShapeBoardItem, createTaskBoardItem, createTextBoardItem } from "../model/items/create.js";
@@ -1,8 +1,8 @@
1
1
  import { clampBoardStrokeSize } from "../../protocol/dist/board-constants.js";
2
- import { hasBoardScripts } from "../model/script-index.js";
3
- import { normalizeViewport } from "../model/geometry.js";
4
2
  import { buildBoardScene } from "../model/scene.js";
3
+ import { normalizeViewport } from "../model/geometry.js";
5
4
  import { isBoardColorId } from "../model/palette.js";
5
+ import { hasBoardScripts } from "../model/script-index.js";
6
6
  import { isShapeKind } from "../model/shape-types.js";
7
7
  import { createBoardToolStyles } from "../model/tool-styles.js";
8
8
  import { titleForBoardItem } from "../model/items/create.js";
@@ -1,5 +1,5 @@
1
- import { selectionBounds } from "../model/geometry.js";
2
1
  import { sceneItemToItem } from "../model/scene.js";
2
+ import { selectionBounds } from "../model/geometry.js";
3
3
  import { alignFrames, distributeFrames } from "./align.js";
4
4
  import { resolveSelectionTransform } from "./selection-transform.js";
5
5
  import { memo } from "./state.js";
@@ -1,9 +1,9 @@
1
1
  import { buildBoardScene } from "../model/scene.js";
2
2
  import { resolveBoardAnimationCamera } from "../model/sampling.js";
3
- import { normalizeBoardDocument, planBoardExport } from "../model/export-plan.js";
4
3
  import { parseBoardCssColor } from "../render/css-color.js";
5
4
  import { defaultBoardPalette } from "../render/palette.js";
6
5
  import { createBoardRenderSampler } from "../render/sampling.js";
6
+ import { normalizeBoardDocument, planBoardExport } from "../model/export-plan.js";
7
7
  import { ensureBoardTextMeasurement } from "../render/text-measurement.js";
8
8
  import { createBoardExportScene } from "./scene.js";
9
9
  import { Rectangle, RendererType } from "pixi.js";
@@ -1,5 +1,5 @@
1
- import { boardScriptScope, composeBoardScriptItems } from "../../model/script-scene.js";
2
1
  import { buildBoardScene } from "../../model/scene.js";
2
+ import { boardScriptScope, composeBoardScriptItems } from "../../model/script-scene.js";
3
3
  import { createBoardScriptModuleReader, loadBoardScriptSources } from "../../../protocol/dist/board-script-modules.js";
4
4
  import { createScriptRuntime } from "../../render/script-runtime.js";
5
5
  import { initializeBoardFonts } from "./fonts.js";
@@ -1,9 +1,9 @@
1
1
  import { buildFallbackShapeColors } from "../model/palette.js";
2
- import { imageAssetKey } from "../model/image-key.js";
3
2
  import { defaultBoardPalette } from "../render/palette.js";
4
3
  import { clippingAncestor, isClippingFrame, syncClipGroup } from "../render/clip.js";
5
4
  import { DEFAULT_BOARD_RENDER_LABELS, getBoardCardRenderer } from "../render/renderers/board-renderer-registry.js";
6
5
  import { resolveBoardRenderStyle } from "../render/style.js";
6
+ import { imageAssetKey } from "../model/image-key.js";
7
7
  import { Container, Graphics, Sprite, TilingSprite } from "pixi.js";
8
8
  //#region src/board/export/scene.ts
9
9
  function buildContext(input) {
@@ -1,36 +1,36 @@
1
1
  import { BOARD_STROKE_MAX_SIZE, BOARD_STROKE_MIN_SIZE, clampBoardStrokeSize } from "../../protocol/dist/board-constants.js";
2
2
  import { isPublicBoardRemoteAddress, normalizeBoardRemoteUrl } from "../../protocol/dist/board-url.js";
3
3
  import { BOARD_ANCHOR_SIDES, BOARD_ARROW_ROUTES, BOARD_CAMERA_TARGET, BOARD_COLOR_TOKENS, BOARD_DASHES, BOARD_DERIVED_SIZE_TYPES, BOARD_EFFECT_KINDS, BOARD_EFFECT_KIND_INFO, BOARD_ENTER_PRESETS, BOARD_EXTENSION_TYPE_PATTERN, BOARD_GRID_DEFAULT_SIZE, BOARD_GRID_MAX_SIZE, BOARD_GRID_MIN_SIZE, BOARD_ID_MAX_LENGTH, BOARD_ITEM_SCHEMAS, BOARD_ITEM_TYPES, BOARD_PLAY_MODES, BOARD_SHAPE_GEOMETRIES, BOARD_TASK_ARTIFACT_LIMIT, BOARD_TEXT_ALIGNS, BoardAnimationHeaderSchema, BoardAnimationSchema, BoardArrowAnchorSchema, BoardArrowBindingSchema, BoardArrowEndSchema, BoardArrowItemSchema, BoardAudioItemSchema, BoardBackgroundSchema, BoardColorSchema, BoardCropSchema, BoardCustomItemSchema, BoardDrawItemSchema, BoardDrawPointSchema, BoardEaseSchema, BoardEffectItemSchema, BoardExtensionItemSchema, BoardFileItemSchema, BoardFrameItemSchema, BoardIdSchema, BoardImageItemSchema, BoardKeySchema, BoardKeyframeSchema, BoardMarkerSchema, BoardMediaOriginSchema, BoardMediaSnapshotSchema, BoardMediaSourceSchema, BoardPatchSchema, BoardScriptSchema, BoardSettingsSchema, BoardShapeItemSchema, BoardSizeSchema, BoardStyleSchema, BoardTaskArtifactSchema, BoardTaskItemSchema, BoardTaskSnapshotSchema, BoardTextItemSchema, BoardTrackSchema, BoardVec2Schema, BoardVideoItemSchema, boardItemSchema, emptyBoardDocument, hasAuthoredSize, isBoardColorString, isBoardEase, isBuiltinItem, isBuiltinItemType, isEmptyBoardDelta, isFileBackedItem, isMediaItem, isSafeBoardSourcePath, parseBoardItem, parseBoardMediaSource } from "../../protocol/dist/board-model.js";
4
+ import { isBoardPath, parseBoardManifest, serializeBoardManifest } from "../../protocol/dist/board.js";
4
5
  import { IDENTITY_MATRIX, anchorPoint, applyMatrix, arrowBindings, autoAnchorSide, bendControl, clampBoardFontSize, createBoardLayout, createDocumentLayout, drawPointsBounds, drawSampleRadius, estimateTextWidth, framePoint, invertMatrix, isArrowBinding, layoutBoardText, multiplyMatrix, pointsRect, rotateAround, scaleVector, setBoardTextMeasurer, sideAnchor } from "../../protocol/dist/board-layout.js";
5
6
  import { applyBoardDelta, applyBoardPatch, applyBoardPatchToDocument, boardPatchTouches, createDocumentState, diffBoardDocuments, diffMergePatch, isEmptyBoardPatch, listBoardProperties, mergePatch, parseBoardDocument, pruneBoardTrack, resolveBoardProperty, trackReferences } from "../../protocol/dist/board-patch.js";
6
- import { isBoardPath, parseBoardManifest, serializeBoardManifest } from "../../protocol/dist/board.js";
7
7
  import { BOARD_SCHEMA_TARGETS, boardJsonSchema, boardSchemaOverview } from "../../protocol/dist/board-schema.js";
8
8
  import { BOARD_TASK_SOURCE_PREFIX, boardTaskSource, featuredTaskArtifact, rankedTaskArtifacts, taskArtifactPreviewUrl, taskArtifacts, taskRunArtifacts, taskRunToBoardTaskSnapshot, withObservedArtifactFacts } from "../../protocol/dist/board-task.js";
9
- import { placeBoardOverlay } from "./overlay-placement.js";
10
- import { boardScriptItems, hasBoardScripts } from "./script-index.js";
9
+ import { applyBoardEvaluation, boardAnimationTime, boardDocumentAt, boardEase, compileBoardAnimations, evaluateBoardAnimations, parseHexColor, sampleBoardTrack } from "./animation.js";
10
+ import { buildBoardScene, orderBoardItems, placeItem, refreshBoardScene, sceneItemToItem, sceneItemsToRecord, toSceneItem } from "./scene.js";
11
11
  import { CORNER_RESIZE_HANDLES, CORNER_ROTATION_ZONE_WIDTH, EDGE_RESIZE_HANDLES, FIT_PADDING, HANDLE_DIRECTION, HANDLE_HIT_RADIUS, MAX_BOARD_ZOOM, MIN_BOARD_ZOOM, MIN_ITEM_SIZE, RESIZE_HANDLES, ROTATION_HANDLE_OFFSET, VIEWPORT_MARGIN_RATIO, angleFromCenter, cameraForFocus, cameraForRect, cameraForState, clamp, clampZoom, degToRad, expandRect, fitToContent, frameContainsPoint, frameCornerRotationHandleAt, frameCorners, frameEdgeHandleAt, frameHandlePosition, frameRayIntersection, frameRect, handlePosition, itemBounds, normalizeRotation, normalizeViewport, normalizedPoint, panBy, pointToWorld, pointsBounds, radToDeg, rectCenter, rectContainsPoint, rectForCameraFocus, rectsIntersect, resizeFrame, resizeFrameToSize, rotateFrames, rotatePointAround, rotationHandleAnchor, rotationHandlePosition, scaleFrames, screenOffset, screenPoint, screenToWorld, selectionBounds, stableCullRect, unionRects, visibleWorldRect, worldOffset, worldPoint, worldRect, worldToScreen, zoomAround } from "./geometry.js";
12
+ import { createBoardAnimationSampler, resolveBoardAnimationCamera } from "./sampling.js";
13
+ import { BOARD_COLORS, DEFAULT_BOARD_COLOR, boardColorCssVar, buildFallbackShapeColors, isBoardColorId, pickBoardColor, resolveBoardColor, resolveItemColor } from "./palette.js";
14
+ import { ARROW_BINDING_GAP, arrowHitRadius, arrowPathBounds, distanceToArrow, pathMidpoint, pathPointAt, resolveAnchor, resolveArrow, resolveSceneArrow } from "./arrow-geometry.js";
15
+ import { BOARD_EXPORT_DEFAULT_PADDING, BOARD_EXPORT_DEFAULT_SCALE, BOARD_EXPORT_ITEM_WARN_THRESHOLD, BOARD_EXPORT_MAX_EDGE, BOARD_EXPORT_MAX_PIXELS, exportItemBounds, normalizeBoardDocument, planBoardExport } from "./export-plan.js";
16
+ import { TEXT_FONT_FAMILY, TEXT_FONT_SIZE, TEXT_LINE_HEIGHT, TEXT_MAX_FONT_SIZE, TEXT_MIN_FONT_SIZE, boardFontFamily } from "./text-metrics.js";
17
+ import { boardModelFormat, getMediaExtension, getMediaResourceTitle, inferBoardMediaKind, isBoardModelItem } from "./media.js";
18
+ import { FILE_EXCERPT_MAX_BYTES, FILE_EXCERPT_MAX_CHARS, buildCodeExcerpt, buildFileExcerpt, buildFileSnapshot, fileBaseName, fileCategory, fileStem, readCoverFromFrontmatter, readFrontmatterScalars, readTitleFromFrontmatter, resolveCoverRef, resolveFileTitle, resolveSpacePath, shouldFetchFileExcerpt, splitFrontmatter } from "./file-snapshot.js";
19
+ import { availabilityFromError, fileCategoryAccent, fileMetaLine, filePreviewKind, filePreviewMemoKey, filePreviewScope, fileTypeLabel, formatFileSize, isFileSnapshotFresh, mergeFileSnapshot } from "./file-preview.js";
20
+ import { buildStrokeOutline, buildStrokeRibbonGeometry, computeDrawBounds, createStrokeRibbonBuilder, distanceToStroke, isStrokeCorner, sampleRadius, simplifyDrawIndices, trimDrawPoints } from "./draw-geometry.js";
21
+ import { boardScriptItems, hasBoardScripts } from "./script-index.js";
12
22
  import { boardScriptScope, composeBoardScriptItems, prepareBoardScriptOutput, scriptTemporaryPrefix, validateBoardScriptCommit, validateBoardScriptOutput } from "./script-scene.js";
13
23
  import { boardScriptHitVisible, boardScriptTarget, resolveBoardScriptHit } from "./script-hit.js";
24
+ import { boardImageKeySource, imageAssetKey } from "./image-key.js";
25
+ import { placeBoardOverlay } from "./overlay-placement.js";
14
26
  import { BOARD_SCRIPT_API } from "./script-api.js";
15
27
  import { BOARD_SCRIPT_DRAWING_EXAMPLE } from "./script-example.js";
16
- import { applyBoardEvaluation, boardAnimationTime, boardDocumentAt, boardEase, compileBoardAnimations, evaluateBoardAnimations, parseHexColor, sampleBoardTrack } from "./animation.js";
17
- import { buildBoardScene, orderBoardItems, placeItem, refreshBoardScene, sceneItemToItem, sceneItemsToRecord, toSceneItem } from "./scene.js";
18
- import { createBoardAnimationSampler, resolveBoardAnimationCamera } from "./sampling.js";
19
28
  import { boardPathTrack, boardSequence, boardSequencePatch } from "./authoring.js";
20
29
  import { BOARD_PRESET_NAMES, boardNestedAnimation, boardNestedAnimationTrack, boardPresetTracks, isBoardPresetName, listBoardPresets } from "./presets.js";
21
- import { ARROW_BINDING_GAP, arrowHitRadius, arrowPathBounds, distanceToArrow, pathMidpoint, pathPointAt, resolveAnchor, resolveArrow, resolveSceneArrow } from "./arrow-geometry.js";
22
- import { buildStrokeOutline, buildStrokeRibbonGeometry, computeDrawBounds, createStrokeRibbonBuilder, distanceToStroke, isStrokeCorner, sampleRadius, simplifyDrawIndices, trimDrawPoints } from "./draw-geometry.js";
23
30
  import { appendBoardDrawSamples, quantizeDrawCoordinate } from "./draw-input.js";
24
31
  import { BOARD_EXPORT_MAX_TEXTURES, selectBoardExportAssets } from "./export-assets.js";
25
- import { BOARD_EXPORT_DEFAULT_PADDING, BOARD_EXPORT_DEFAULT_SCALE, BOARD_EXPORT_ITEM_WARN_THRESHOLD, BOARD_EXPORT_MAX_EDGE, BOARD_EXPORT_MAX_PIXELS, exportItemBounds, normalizeBoardDocument, planBoardExport } from "./export-plan.js";
26
- import { boardModelFormat, getMediaExtension, getMediaResourceTitle, inferBoardMediaKind, isBoardModelItem } from "./media.js";
27
- import { FILE_EXCERPT_MAX_BYTES, FILE_EXCERPT_MAX_CHARS, buildCodeExcerpt, buildFileExcerpt, buildFileSnapshot, fileBaseName, fileCategory, fileStem, readCoverFromFrontmatter, readFrontmatterScalars, readTitleFromFrontmatter, resolveCoverRef, resolveFileTitle, resolveSpacePath, shouldFetchFileExcerpt, splitFrontmatter } from "./file-snapshot.js";
28
- import { availabilityFromError, fileCategoryAccent, fileMetaLine, filePreviewKind, filePreviewMemoKey, filePreviewScope, fileTypeLabel, formatFileSize, isFileSnapshotFresh, mergeFileSnapshot } from "./file-preview.js";
29
- import { BOARD_COLORS, DEFAULT_BOARD_COLOR, boardColorCssVar, buildFallbackShapeColors, isBoardColorId, pickBoardColor, resolveBoardColor, resolveItemColor } from "./palette.js";
30
32
  import { SHAPE_KINDS, isShapeKind } from "./shape-types.js";
31
- import { TEXT_FONT_FAMILY, TEXT_FONT_SIZE, TEXT_LINE_HEIGHT, TEXT_MAX_FONT_SIZE, TEXT_MIN_FONT_SIZE, boardFontFamily } from "./text-metrics.js";
32
33
  import { DEFAULT_BOARD_TOOL_STYLES, createBoardToolStyles } from "./tool-styles.js";
33
- import { boardImageKeySource, imageAssetKey } from "./image-key.js";
34
34
  import { FULL_CAPABILITIES, defineBoardItem } from "./items/definition.js";
35
35
  import { builtinBoardItems } from "./items/builtin.js";
36
36
  import { createBoardEntityId, createBoardItemId } from "./items/id.js";
@@ -1,10 +1,10 @@
1
1
  import { BoardMediaOriginSchema, parseBoardItem } from "../../../protocol/dist/board-model.js";
2
2
  import { pointsRect } from "../../../protocol/dist/board-layout.js";
3
3
  import { featuredTaskArtifact } from "../../../protocol/dist/board-task.js";
4
- import { quantizeDrawCoordinate } from "../draw-input.js";
5
4
  import { boardModelFormat, getMediaResourceTitle, inferBoardMediaKind } from "../media.js";
6
5
  import { fileStem } from "../file-snapshot.js";
7
6
  import { filePreviewKind } from "../file-preview.js";
7
+ import { quantizeDrawCoordinate } from "../draw-input.js";
8
8
  import { DEFAULT_BOARD_TOOL_STYLES } from "../tool-styles.js";
9
9
  import { createBoardItemId } from "./id.js";
10
10
  //#region src/board/model/items/create.ts
@@ -1,7 +1,7 @@
1
1
  import { arrowBindings } from "../../protocol/dist/board-layout.js";
2
- import { cameraForFocus, cameraForState } from "./geometry.js";
3
2
  import { applyBoardEvaluation, boardAnimationTime, compileBoardAnimations, evaluateBoardAnimations } from "./animation.js";
4
3
  import { buildBoardScene } from "./scene.js";
4
+ import { cameraForFocus, cameraForState } from "./geometry.js";
5
5
  //#region src/board/model/sampling.ts
6
6
  function createBoardAnimationSampler(document, animation, options = {}) {
7
7
  const selected = animation ? document.animations[animation] : void 0;
@@ -1,7 +1,7 @@
1
1
  import { featuredTaskArtifact } from "../../protocol/dist/board-task.js";
2
2
  import { degToRad, rotatePointAround, worldPoint } from "../model/geometry.js";
3
- import { isBoardModelItem } from "../model/media.js";
4
3
  import { boardCardDetailed } from "./text-resolution.js";
4
+ import { isBoardModelItem } from "../model/media.js";
5
5
  import { audioKeyCenter } from "./renderers/audio-card-renderer.js";
6
6
  import { modelKeyCenter } from "./renderers/model-card-renderer.js";
7
7
  //#region src/board/render/media-interaction.ts
@@ -1,6 +1,6 @@
1
1
  import { BOARD_FONT_STACK } from "../../../protocol/dist/board-constants.js";
2
- import { pathPointAt, resolveSceneArrow } from "../../model/arrow-geometry.js";
3
2
  import { itemAlpha, itemColor } from "../palette.js";
3
+ import { pathPointAt, resolveSceneArrow } from "../../model/arrow-geometry.js";
4
4
  import { syncTextResolution, textResolutionForZoom } from "../text-resolution.js";
5
5
  import { dashPattern, endAngle, traceArrowhead, tracePolyline, trimPolyline } from "../stroke.js";
6
6
  import { drawCardSurface } from "../surface.js";
@@ -1,7 +1,7 @@
1
- import { getMediaResourceTitle } from "../../model/media.js";
2
1
  import { fitTextToWidth } from "../text-fit.js";
3
2
  import { boardCardDetailed, syncTextResolution, textResolutionForZoom } from "../text-resolution.js";
4
3
  import { formatBoardDuration } from "../card-tag.js";
4
+ import { getMediaResourceTitle } from "../../model/media.js";
5
5
  import { drawAudioWaveform } from "../audio-waveform.js";
6
6
  import { cardElevation, drawCardSurface } from "../surface.js";
7
7
  import { positionShell } from "./base-card-renderer.js";
@@ -1,8 +1,8 @@
1
1
  import { applyMatrix } from "../../../protocol/dist/board-layout.js";
2
- import { computeDrawBounds, createStrokeRibbonBuilder, trimDrawPoints } from "../../model/draw-geometry.js";
3
2
  import { itemAlpha, itemColor } from "../palette.js";
4
3
  import { positionShell } from "./base-card-renderer.js";
5
4
  import { drawFarStroke, farStrokeSamples } from "./far-plate.js";
5
+ import { computeDrawBounds, createStrokeRibbonBuilder, trimDrawPoints } from "../../model/draw-geometry.js";
6
6
  import { Container, Graphics, Mesh, MeshGeometry, Texture } from "pixi.js";
7
7
  //#region src/board/render/renderers/draw-card-renderer.ts
8
8
  const partsByContainer = /* @__PURE__ */ new WeakMap();
@@ -1,12 +1,12 @@
1
1
  import { BOARD_FONT_STACK, BOARD_MONO_FONT_STACK } from "../../../protocol/dist/board-constants.js";
2
- import { fileCategory, fileStem } from "../../model/file-snapshot.js";
3
- import { fileCategoryAccent, fileMetaLine, filePreviewKind, fileTypeLabel } from "../../model/file-preview.js";
4
2
  import { fitTextToLines } from "../text-fit.js";
5
3
  import { boardCardDetailed, syncTextResolution } from "../text-resolution.js";
6
4
  import { createCardTag, syncCardTag, zoomCardTag } from "../card-tag.js";
7
5
  import { cardElevation, containRect, drawCardSurface, traceCardOutline } from "../surface.js";
8
6
  import { positionShell } from "./base-card-renderer.js";
9
7
  import { drawFarPlate } from "./far-plate.js";
8
+ import { fileCategory, fileStem } from "../../model/file-snapshot.js";
9
+ import { fileCategoryAccent, fileMetaLine, filePreviewKind, fileTypeLabel } from "../../model/file-preview.js";
10
10
  import { Container, Graphics, Sprite, Text, Texture } from "pixi.js";
11
11
  //#region src/board/render/renderers/file-card-renderer.ts
12
12
  const PADDING = 10;
@@ -1,12 +1,12 @@
1
- import { isBoardModelItem } from "../../model/media.js";
2
- import { fileStem } from "../../model/file-snapshot.js";
3
- import { fileMetaLine } from "../../model/file-preview.js";
4
1
  import { boardCardDetailed } from "../text-resolution.js";
5
2
  import { createCardTag, syncCardTag, traceCube, zoomCardTag } from "../card-tag.js";
3
+ import { isBoardModelItem } from "../../model/media.js";
6
4
  import { cardElevation, containRect, drawCardSurface } from "../surface.js";
7
5
  import { positionShell } from "./base-card-renderer.js";
8
6
  import { drawFarPlate } from "./far-plate.js";
9
7
  import { drawModelKey } from "./media-key.js";
8
+ import { fileStem } from "../../model/file-snapshot.js";
9
+ import { fileMetaLine } from "../../model/file-preview.js";
10
10
  import { Container, Graphics, Sprite, Texture } from "pixi.js";
11
11
  //#region src/board/render/renderers/model-card-renderer.ts
12
12
  const partsByContainer = /* @__PURE__ */ new WeakMap();
@@ -1,6 +1,6 @@
1
1
  import { layoutBoardText } from "../../../protocol/dist/board-layout.js";
2
- import { boardFontFamily } from "../../model/text-metrics.js";
3
2
  import { itemAlpha, itemColor } from "../palette.js";
3
+ import { boardFontFamily } from "../../model/text-metrics.js";
4
4
  import { BOARD_FONT_STACKS } from "../text-measurement.js";
5
5
  import { syncTextResolution, textResolutionForZoom } from "../text-resolution.js";
6
6
  import { positionShell } from "./base-card-renderer.js";
@@ -1,6 +1,6 @@
1
- import { getMediaResourceTitle } from "../../model/media.js";
2
1
  import { boardCardDetailed } from "../text-resolution.js";
3
2
  import { createCardTag, formatBoardDuration, syncCardTag, zoomCardTag } from "../card-tag.js";
3
+ import { getMediaResourceTitle } from "../../model/media.js";
4
4
  import { cardElevation, containRect, drawCardSurface, traceCardOutline } from "../surface.js";
5
5
  import { positionShell } from "./base-card-renderer.js";
6
6
  import { drawFarPlate } from "./far-plate.js";
@@ -1,5 +1,5 @@
1
- import { composeBoardScriptItems } from "../model/script-scene.js";
2
1
  import { buildBoardScene } from "../model/scene.js";
2
+ import { composeBoardScriptItems } from "../model/script-scene.js";
3
3
  import { createBoardScriptHost } from "./script-host.js";
4
4
  //#region src/board/render/script-export.ts
5
5
  async function prepareBrowserBoardScripts(document, time, readModule, snapshots) {
@@ -1,7 +1,7 @@
1
+ import { BoardScriptTexture } from "./script-texture.js";
1
2
  import { boardScriptItems } from "../model/script-index.js";
2
3
  import { boardScriptScope } from "../model/script-scene.js";
3
4
  import { boardScriptHitVisible, resolveBoardScriptHit } from "../model/script-hit.js";
4
- import { BoardScriptTexture } from "./script-texture.js";
5
5
  import { createBoardScriptModuleReader, loadBoardScriptSources } from "../../protocol/dist/board-script-modules.js";
6
6
  import { boardScriptFrameSource } from "./script-sandbox.js";
7
7
  //#region src/board/render/script-host.ts
@@ -2,8 +2,8 @@ import { mediaPreviewCandidates } from "../../media.js";
2
2
  import { parseBoardMediaSource } from "../../protocol/dist/board-model.js";
3
3
  import { featuredTaskArtifact } from "../../protocol/dist/board-task.js";
4
4
  import { boardModelFormat, isBoardModelItem } from "../model/media.js";
5
- import { boardImageKeySource, imageAssetKey } from "../model/image-key.js";
6
5
  import { loadVideoThumbnailTexture, videoTextureNaturalSize } from "../render/video-thumbnail.js";
6
+ import { boardImageKeySource, imageAssetKey } from "../model/image-key.js";
7
7
  import { DEFAULT_LRU_BUDGET, selectLruEvictions } from "./lru.js";
8
8
  import { boardImageTexturePool, loadBoardImageTexture, unloadBoardImageTexture } from "./texture-pool.js";
9
9
  import { Texture } from "pixi.js";
@@ -2,8 +2,9 @@ import { DEFAULT_LRU_BUDGET, LruBudget, LruEntry, selectLruEvictions } from "./l
2
2
  import { BoardImageTexturePool, boardImageTexturePool, createBoardImageTexturePool, loadBoardImageTexture, unloadBoardImageTexture } from "./texture-pool.js";
3
3
  import { BoardAssetManager, BoardAssetManagerOptions, BoardModelPreviewRequest, BoardModelPreviews, boardAssetKey, createBoardAssetManager } from "./assets.js";
4
4
  import { toBoardPointerEvent } from "./pointer.js";
5
+ import { createBoardPointerGestures } from "./pointer-gestures.js";
5
6
  import { BoardLiveStroke, BoardScene, BoardSceneNode, SceneSyncInput, createBoardScene } from "./scene.js";
6
7
  import { BoardItemView, BoardItemViewContext, BoardItemViewInstance, BoardItemViewLayer, createBoardItemViewLayer } from "./views.js";
7
8
  import { BoardStage, BoardStageOptions, BoardStagePointerPhase, BoardStageTheme, mountBoardStage } from "./stage.js";
8
9
  import { BoardOverlayInput, drawBoardOverlay, expandFrame } from "./overlay.js";
9
- export { BoardAssetManager, BoardAssetManagerOptions, BoardImageTexturePool, BoardItemView, BoardItemViewContext, BoardItemViewInstance, BoardItemViewLayer, BoardLiveStroke, BoardModelPreviewRequest, BoardModelPreviews, BoardOverlayInput, BoardScene, BoardSceneNode, BoardStage, BoardStageOptions, BoardStagePointerPhase, BoardStageTheme, DEFAULT_LRU_BUDGET, LruBudget, LruEntry, SceneSyncInput, boardAssetKey, boardImageTexturePool, createBoardAssetManager, createBoardImageTexturePool, createBoardItemViewLayer, createBoardScene, drawBoardOverlay, expandFrame, loadBoardImageTexture, mountBoardStage, selectLruEvictions, toBoardPointerEvent, unloadBoardImageTexture };
10
+ export { BoardAssetManager, BoardAssetManagerOptions, BoardImageTexturePool, BoardItemView, BoardItemViewContext, BoardItemViewInstance, BoardItemViewLayer, BoardLiveStroke, BoardModelPreviewRequest, BoardModelPreviews, BoardOverlayInput, BoardScene, BoardSceneNode, BoardStage, BoardStageOptions, BoardStagePointerPhase, BoardStageTheme, DEFAULT_LRU_BUDGET, LruBudget, LruEntry, SceneSyncInput, boardAssetKey, boardImageTexturePool, createBoardAssetManager, createBoardImageTexturePool, createBoardItemViewLayer, createBoardPointerGestures, createBoardScene, drawBoardOverlay, expandFrame, loadBoardImageTexture, mountBoardStage, selectLruEvictions, toBoardPointerEvent, unloadBoardImageTexture };
@@ -2,8 +2,9 @@ import { DEFAULT_LRU_BUDGET, selectLruEvictions } from "./lru.js";
2
2
  import { boardImageTexturePool, createBoardImageTexturePool, loadBoardImageTexture, unloadBoardImageTexture } from "./texture-pool.js";
3
3
  import { boardAssetKey, createBoardAssetManager } from "./assets.js";
4
4
  import { toBoardPointerEvent } from "./pointer.js";
5
+ import { createBoardPointerGestures } from "./pointer-gestures.js";
5
6
  import { createBoardScene } from "./scene.js";
6
7
  import { drawBoardOverlay, expandFrame } from "./overlay.js";
7
8
  import { createBoardItemViewLayer } from "./views.js";
8
9
  import { mountBoardStage } from "./stage.js";
9
- export { DEFAULT_LRU_BUDGET, boardAssetKey, boardImageTexturePool, createBoardAssetManager, createBoardImageTexturePool, createBoardItemViewLayer, createBoardScene, drawBoardOverlay, expandFrame, loadBoardImageTexture, mountBoardStage, selectLruEvictions, toBoardPointerEvent, unloadBoardImageTexture };
10
+ export { DEFAULT_LRU_BUDGET, boardAssetKey, boardImageTexturePool, createBoardAssetManager, createBoardImageTexturePool, createBoardItemViewLayer, createBoardPointerGestures, createBoardScene, drawBoardOverlay, expandFrame, loadBoardImageTexture, mountBoardStage, selectLruEvictions, toBoardPointerEvent, unloadBoardImageTexture };
@@ -0,0 +1,12 @@
1
+ //#region src/board/stage/pointer-gestures.d.ts
2
+ type BoardPointerGestureHandlers = {
3
+ move(event: PointerEvent): void;
4
+ end(event: PointerEvent): void;
5
+ };
6
+ declare function createBoardPointerGestures(host: HTMLElement, handlers: BoardPointerGestureHandlers): {
7
+ has: (pointerId: number) => boolean;
8
+ start(event: PointerEvent): void;
9
+ cancel: () => void;
10
+ };
11
+ //#endregion
12
+ export { createBoardPointerGestures };
@@ -0,0 +1,63 @@
1
+ //#region src/board/stage/pointer-gestures.ts
2
+ function createBoardPointerGestures(host, handlers) {
3
+ const document = host.ownerDocument;
4
+ const window = document.defaultView;
5
+ const pointers = /* @__PURE__ */ new Map();
6
+ function listen(active) {
7
+ const method = active ? "addEventListener" : "removeEventListener";
8
+ document[method]("pointermove", move, true);
9
+ document[method]("pointerup", end, true);
10
+ document[method]("pointercancel", end, true);
11
+ host[method]("lostpointercapture", lost);
12
+ window?.[method]("blur", cancel);
13
+ document[method]("visibilitychange", visibility);
14
+ }
15
+ function move(event) {
16
+ const previous = pointers.get(event.pointerId);
17
+ if (!previous) return;
18
+ if (event.pointerType === "mouse" && event.buttons === 0 && window) {
19
+ end(new window.PointerEvent("pointerup", {
20
+ pointerId: event.pointerId,
21
+ pointerType: event.pointerType,
22
+ clientX: previous.clientX,
23
+ clientY: previous.clientY,
24
+ button: 0,
25
+ buttons: 0,
26
+ shiftKey: event.shiftKey,
27
+ altKey: event.altKey,
28
+ ctrlKey: event.ctrlKey,
29
+ metaKey: event.metaKey
30
+ }));
31
+ return;
32
+ }
33
+ pointers.set(event.pointerId, event);
34
+ handlers.move(event);
35
+ }
36
+ function end(event) {
37
+ if (!pointers.delete(event.pointerId)) return;
38
+ if (pointers.size === 0) listen(false);
39
+ if (host.hasPointerCapture(event.pointerId)) host.releasePointerCapture(event.pointerId);
40
+ handlers.end(event);
41
+ }
42
+ function lost(event) {
43
+ if (event.target === host && event.pointerType !== "mouse") end(event);
44
+ }
45
+ function cancel() {
46
+ if (!window) return;
47
+ for (const event of [...pointers.values()]) end(new window.PointerEvent("pointercancel", event));
48
+ }
49
+ function visibility() {
50
+ if (document.hidden) cancel();
51
+ }
52
+ return {
53
+ has: (pointerId) => pointers.has(pointerId),
54
+ start(event) {
55
+ host.setPointerCapture(event.pointerId);
56
+ if (pointers.size === 0) listen(true);
57
+ pointers.set(event.pointerId, event);
58
+ },
59
+ cancel
60
+ };
61
+ }
62
+ //#endregion
63
+ export { createBoardPointerGestures };
@@ -1,23 +1,24 @@
1
1
  import { applyMatrix, invertMatrix } from "../../protocol/dist/board-layout.js";
2
2
  import { featuredTaskArtifact } from "../../protocol/dist/board-task.js";
3
3
  import { screenPoint, screenToWorld, stableCullRect, visibleWorldRect, worldPoint } from "../model/geometry.js";
4
- import { boardScriptScope, composeBoardScriptItems, prepareBoardScriptOutput, validateBoardScriptCommit } from "../model/script-scene.js";
5
- import { boardScriptTarget } from "../model/script-hit.js";
6
4
  import { createBoardAnimationSampler, resolveBoardAnimationCamera } from "../model/sampling.js";
7
- import { resolveSceneArrow } from "../model/arrow-geometry.js";
8
5
  import { buildFallbackShapeColors, pickBoardColor, resolveItemColor } from "../model/palette.js";
9
- import { isCreationBoardTool } from "../editor/tool.js";
10
- import { resizeCursorForHandle } from "../editor/selection-transform.js";
11
6
  import { parseBoardCssColor } from "../render/css-color.js";
12
7
  import { defaultBoardPalette, itemAlpha } from "../render/palette.js";
8
+ import { resolveSceneArrow } from "../model/arrow-geometry.js";
13
9
  import { createBoardBackground, updateBoardBackground } from "../render/board-background.js";
14
10
  import { getBoardResolution, textZoomBucket } from "../render/text-resolution.js";
15
11
  import { DEFAULT_BOARD_RENDER_LABELS, getBoardCardRenderer } from "../render/renderers/board-renderer-registry.js";
12
+ import { boardScriptScope, composeBoardScriptItems, prepareBoardScriptOutput, validateBoardScriptCommit } from "../model/script-scene.js";
13
+ import { boardScriptTarget } from "../model/script-hit.js";
16
14
  import { createBoardScriptHost } from "../render/script-host.js";
17
15
  import { defaultBoardRenderStyle } from "../render/style.js";
16
+ import { isCreationBoardTool } from "../editor/tool.js";
17
+ import { resizeCursorForHandle } from "../editor/selection-transform.js";
18
18
  import { createBoardPlayer } from "../player/index.js";
19
19
  import { createBoardScriptObservers } from "../model/script-observers.js";
20
20
  import { toBoardPointerEvent } from "./pointer.js";
21
+ import { createBoardPointerGestures } from "./pointer-gestures.js";
21
22
  import { createBoardScene } from "./scene.js";
22
23
  import { scheduleBoardMaintenance } from "./maintenance.js";
23
24
  import { createBoardScriptPointerRouter } from "./script-pointer.js";
@@ -679,10 +680,7 @@ function mountBoardStage(host, options) {
679
680
  x: event.clientX,
680
681
  y: event.clientY
681
682
  }, event.type !== "pointerup");
682
- if (type === "down" && recipient) {
683
- host.setPointerCapture(event.pointerId);
684
- host.focus({ preventScroll: true });
685
- }
683
+ if (type === "down" && recipient) host.focus({ preventScroll: true });
686
684
  if (recipient && type !== "leave") sendScriptEvent(recipient, input.cancelled ? "pointercancel" : `pointer${type}`, event, input);
687
685
  if (click) sendScriptEvent(click, "click", event, input);
688
686
  return consumed || recipient !== null;
@@ -701,24 +699,33 @@ function mountBoardStage(host, options) {
701
699
  scripts?.event(scriptHover.owner, input);
702
700
  event.stopPropagation();
703
701
  }
702
+ const pointers = createBoardPointerGestures(host, {
703
+ move: routePointerMove,
704
+ end: handlePointerUp
705
+ });
704
706
  function handlePointerDown(event) {
705
- if (inViews(event)) return;
707
+ if (!active || inViews(event)) return;
706
708
  editor.takeCameraControl();
707
709
  const input = toInput(event);
708
- if (scriptPointer("down", event, input)) return;
710
+ if (scriptPointer("down", event, input)) {
711
+ pointers.start(event);
712
+ return;
713
+ }
709
714
  if (options.onPointer?.("down", event, input) === false) return;
710
- host.setPointerCapture(event.pointerId);
715
+ pointers.start(event);
711
716
  editor.pointerDown(input);
712
717
  }
713
718
  function handlePointerMove(event) {
714
- if (inViews(event)) return;
719
+ if (!active || pointers.has(event.pointerId) || inViews(event)) return;
720
+ routePointerMove(event);
721
+ }
722
+ function routePointerMove(event) {
715
723
  const input = toInput(event);
716
724
  if (scriptPointer("move", event, input)) return;
717
725
  if (options.onPointer?.("move", event, input) === false) return;
718
726
  editor.pointerMove(input);
719
727
  }
720
728
  function handlePointerUp(event) {
721
- if (inViews(event)) return;
722
729
  const input = toInput(event);
723
730
  if (scriptPointer("up", event, input)) return;
724
731
  if (options.onPointer?.("up", event, input) === false) return;
@@ -758,9 +765,6 @@ function mountBoardStage(host, options) {
758
765
  ["keyup", handleScriptKey],
759
766
  ["pointerdown", handlePointerDown],
760
767
  ["pointermove", handlePointerMove],
761
- ["pointerup", handlePointerUp],
762
- ["pointercancel", handlePointerUp],
763
- ["lostpointercapture", handlePointerUp],
764
768
  ["pointerleave", handlePointerLeave],
765
769
  [
766
770
  "wheel",
@@ -874,6 +878,7 @@ function mountBoardStage(host, options) {
874
878
  if (active === next) return;
875
879
  active = next;
876
880
  if (!active) {
881
+ pointers.cancel();
877
882
  stopMarch();
878
883
  cancelScriptPointers();
879
884
  cancelAnimationFrame(renderFrame);
@@ -902,6 +907,7 @@ function mountBoardStage(host, options) {
902
907
  toWorld: (clientX, clientY) => screenToWorld(clientX, clientY, rectOf(), renderCamera()),
903
908
  destroy() {
904
909
  disposed = true;
910
+ pointers.cancel();
905
911
  stopMarch();
906
912
  scriptPointers.clear();
907
913
  stopTransforms?.();