tldraw 5.3.0 → 5.4.0-canary.0714aa9af9a0
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/DOCS.md +6 -2
- package/RELEASE_NOTES.md +53 -7
- package/dist-cjs/index.d.ts +264 -275
- package/dist-cjs/index.js +1 -1
- package/dist-cjs/lib/defaultExternalContentHandlers.js +2 -2
- package/dist-cjs/lib/defaultExternalContentHandlers.js.map +2 -2
- package/dist-cjs/lib/shapes/draw/toolStates/Drawing.js +2 -2
- package/dist-cjs/lib/shapes/draw/toolStates/Drawing.js.map +2 -2
- package/dist-cjs/lib/shapes/frame/frameHelpers.js +3 -0
- package/dist-cjs/lib/shapes/frame/frameHelpers.js.map +2 -2
- package/dist-cjs/lib/shapes/video/VideoShapeUtil.js +3 -2
- package/dist-cjs/lib/shapes/video/VideoShapeUtil.js.map +2 -2
- package/dist-cjs/lib/ui/TldrawUi.js +2 -3
- package/dist-cjs/lib/ui/TldrawUi.js.map +2 -2
- package/dist-cjs/lib/ui/components/ActionsMenu/DefaultActionsMenu.js +0 -3
- package/dist-cjs/lib/ui/components/ActionsMenu/DefaultActionsMenu.js.map +2 -2
- package/dist-cjs/lib/ui/components/ContextMenu/DefaultContextMenuContent.js +1 -1
- package/dist-cjs/lib/ui/components/ContextMenu/DefaultContextMenuContent.js.map +2 -2
- package/dist-cjs/lib/ui/components/Dialogs.js +8 -0
- package/dist-cjs/lib/ui/components/Dialogs.js.map +2 -2
- package/dist-cjs/lib/ui/components/SharePanel/DefaultPeopleMenuItem.js +1 -2
- package/dist-cjs/lib/ui/components/SharePanel/DefaultPeopleMenuItem.js.map +2 -2
- package/dist-cjs/lib/ui/context/actions.js +0 -1
- package/dist-cjs/lib/ui/context/actions.js.map +2 -2
- package/dist-cjs/lib/ui/hooks/useClipboardEvents.js +2 -0
- package/dist-cjs/lib/ui/hooks/useClipboardEvents.js.map +2 -2
- package/dist-cjs/lib/ui/hooks/useFlatten.js +42 -23
- package/dist-cjs/lib/ui/hooks/useFlatten.js.map +2 -2
- package/dist-cjs/lib/ui/hooks/useKeyboardShortcuts.js +5 -17
- package/dist-cjs/lib/ui/hooks/useKeyboardShortcuts.js.map +2 -2
- package/dist-cjs/lib/ui/kbd-utils.js +22 -3
- package/dist-cjs/lib/ui/kbd-utils.js.map +2 -2
- package/dist-cjs/lib/ui/version.js +3 -3
- package/dist-cjs/lib/ui/version.js.map +1 -1
- package/dist-esm/index.d.mts +264 -275
- package/dist-esm/index.mjs +1 -1
- package/dist-esm/lib/defaultExternalContentHandlers.mjs +2 -2
- package/dist-esm/lib/defaultExternalContentHandlers.mjs.map +2 -2
- package/dist-esm/lib/shapes/draw/toolStates/Drawing.mjs +2 -2
- package/dist-esm/lib/shapes/draw/toolStates/Drawing.mjs.map +2 -2
- package/dist-esm/lib/shapes/frame/frameHelpers.mjs +3 -0
- package/dist-esm/lib/shapes/frame/frameHelpers.mjs.map +2 -2
- package/dist-esm/lib/shapes/video/VideoShapeUtil.mjs +3 -2
- package/dist-esm/lib/shapes/video/VideoShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/ui/TldrawUi.mjs +2 -3
- package/dist-esm/lib/ui/TldrawUi.mjs.map +2 -2
- package/dist-esm/lib/ui/components/ActionsMenu/DefaultActionsMenu.mjs +2 -5
- package/dist-esm/lib/ui/components/ActionsMenu/DefaultActionsMenu.mjs.map +2 -2
- package/dist-esm/lib/ui/components/ContextMenu/DefaultContextMenuContent.mjs +1 -1
- package/dist-esm/lib/ui/components/ContextMenu/DefaultContextMenuContent.mjs.map +2 -2
- package/dist-esm/lib/ui/components/Dialogs.mjs +9 -1
- package/dist-esm/lib/ui/components/Dialogs.mjs.map +2 -2
- package/dist-esm/lib/ui/components/SharePanel/DefaultPeopleMenuItem.mjs +1 -2
- package/dist-esm/lib/ui/components/SharePanel/DefaultPeopleMenuItem.mjs.map +2 -2
- package/dist-esm/lib/ui/context/actions.mjs +0 -1
- package/dist-esm/lib/ui/context/actions.mjs.map +2 -2
- package/dist-esm/lib/ui/hooks/useClipboardEvents.mjs +2 -0
- package/dist-esm/lib/ui/hooks/useClipboardEvents.mjs.map +2 -2
- package/dist-esm/lib/ui/hooks/useFlatten.mjs +42 -23
- package/dist-esm/lib/ui/hooks/useFlatten.mjs.map +2 -2
- package/dist-esm/lib/ui/hooks/useKeyboardShortcuts.mjs +5 -17
- package/dist-esm/lib/ui/hooks/useKeyboardShortcuts.mjs.map +2 -2
- package/dist-esm/lib/ui/kbd-utils.mjs +22 -3
- package/dist-esm/lib/ui/kbd-utils.mjs.map +2 -2
- package/dist-esm/lib/ui/version.mjs +3 -3
- package/dist-esm/lib/ui/version.mjs.map +1 -1
- package/package.json +6 -6
- package/src/lib/defaultExternalContentHandlers.ts +2 -2
- package/src/lib/shapes/draw/DrawShapeTool.test.ts +19 -0
- package/src/lib/shapes/draw/toolStates/Drawing.ts +2 -2
- package/src/lib/shapes/frame/frameHelpers.ts +10 -1
- package/src/lib/shapes/video/VideoShapeUtil.tsx +4 -2
- package/src/lib/ui/TldrawUi.tsx +1 -2
- package/src/lib/ui/components/ActionsMenu/DefaultActionsMenu.tsx +2 -6
- package/src/lib/ui/components/ContextMenu/DefaultContextMenuContent.tsx +5 -1
- package/src/lib/ui/components/Dialogs.tsx +17 -1
- package/src/lib/ui/components/SharePanel/DefaultPeopleMenuItem.tsx +2 -3
- package/src/lib/ui/context/actions.tsx +0 -1
- package/src/lib/ui/hooks/useClipboardEvents.ts +2 -0
- package/src/lib/ui/hooks/useFlatten.ts +56 -23
- package/src/lib/ui/hooks/useKeyboardShortcuts.ts +5 -23
- package/src/lib/ui/kbd-utils.test.ts +11 -0
- package/src/lib/ui/kbd-utils.ts +27 -4
- package/src/lib/ui/version.ts +3 -3
- package/src/lib/ui.css +7 -16
- package/src/test/VideoShapeUtil.test.tsx +126 -0
- package/src/test/bookmark-shapes.test.ts +110 -0
- package/src/test/commands/alignShapes.test.tsx +19 -10
- package/src/test/commands/clipboard.test.ts +36 -1
- package/src/test/flatten.test.ts +135 -0
- package/src/test/modifiers.test.ts +104 -0
- package/tldraw.css +7 -16
package/DOCS.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# tldraw Documentation
|
|
2
2
|
|
|
3
|
-
Version: `5.
|
|
3
|
+
Version: `5.4.0-canary.0714aa9af9a0`
|
|
4
4
|
|
|
5
5
|
This file is generated during package publishing from the tldraw docs content for this exact package version.
|
|
6
6
|
|
|
@@ -383,6 +383,7 @@ We ship an experimental `tldraw-migrate` agent skill that helps a coding agent u
|
|
|
383
383
|
|
|
384
384
|
#### v5.x
|
|
385
385
|
|
|
386
|
+
- [v5.3](https://tldraw.dev/releases/v5.3.0) - Commenting with anchored threads on the canvas, new collaboration packages, geo shape flipping, crop snapping, and faster viewport culling
|
|
386
387
|
- [v5.2](https://tldraw.dev/releases/v5.2.0) - Faster freehand ink, a frame selection action, SDK-wide performance improvements, and breaking changes to the collaborator user-id types and Node support
|
|
387
388
|
- [v5.1](https://tldraw.dev/releases/v5.1.0) - Page menu redesign, copy-styles shortcut, selectable locked shapes, public translation APIs, and performance improvements
|
|
388
389
|
- [v5.0](https://tldraw.dev/releases/v5.0.0) - Custom themes, overlays, performance, extensiblity, and attribution
|
|
@@ -16960,11 +16961,14 @@ Ungrouping reverses this process by moving the group's children back to the grou
|
|
|
16960
16961
|
|
|
16961
16962
|
##### Alignment
|
|
16962
16963
|
|
|
16963
|
-
Alignment moves shapes so they share a common edge or center line. The
|
|
16964
|
+
Alignment moves shapes so they share a common edge or center line. The six single-axis operations are `left`, `right`, `top`, `bottom`, `center-horizontal`, and `center-vertical`. Use `center` to align shapes by both their horizontal and vertical centers in one call.
|
|
16965
|
+
|
|
16966
|
+
When aligning shapes, the editor first calculates the common bounding box of all selected shapes. It then moves each shape to the appropriate edge or center of that common box.
|
|
16964
16967
|
|
|
16965
16968
|
```typescript
|
|
16966
16969
|
editor.alignShapes(editor.getSelectedShapeIds(), 'left')
|
|
16967
16970
|
editor.alignShapes([box1, box2], 'center-vertical')
|
|
16971
|
+
editor.alignShapes([box1, box2], 'center')
|
|
16968
16972
|
```
|
|
16969
16973
|
|
|
16970
16974
|
Selected shapes connected by arrow bindings move together as a cluster during alignment. If shapes A and B are connected by an arrow and you align them with shape C, A and B move together as a single unit.
|
package/RELEASE_NOTES.md
CHANGED
|
@@ -1,27 +1,70 @@
|
|
|
1
1
|
# Releases
|
|
2
2
|
|
|
3
|
-
Version: `5.
|
|
3
|
+
Version: `5.4.0-canary.0714aa9af9a0`
|
|
4
4
|
|
|
5
5
|
This file is generated during package publishing from the tldraw release notes content for this exact package version.
|
|
6
6
|
|
|
7
7
|
## v5.3.0
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
[View on GitHub](https://github.com/tldraw/tldraw/releases/tag/v5.3.0)
|
|
10
|
+
|
|
11
|
+
This release adds commenting: a set of new packages for anchored comment threads on the canvas, backed by comment records in the schema and sync support for non-document data. Commenting is the first piece of our new collaboration package, a separately licensed section of the SDK for premium collaboration features. The release also adds flipping for geo shapes, snapping and symmetric resizing while cropping images, an `assets` prop for `TldrawImage`, and a reactive `Editor.getIsMounted()` with a new `unmount` event. Viewport culling is faster on large pages, and there's a batch of fixes for crashes and interaction bugs across arrows, groups, and text.
|
|
10
12
|
|
|
11
13
|
### What's new
|
|
12
14
|
|
|
13
|
-
####
|
|
15
|
+
#### Commenting ([#9471](https://github.com/tldraw/tldraw/pull/9471), [#9782](https://github.com/tldraw/tldraw/pull/9782), [#9850](https://github.com/tldraw/tldraw/pull/9850))
|
|
16
|
+
|
|
17
|
+
Comments are now a first-class primitive in the SDK. `@tldraw/commenting` ships a batteries-included canvas comments layer: threads anchor to a point, a shape (precisely or imprecisely), a text range, a region, or the page. You can reply, edit, react, resolve, and delete comments. The pins drag to re-anchor, and `?comment=<id>` deep links open a thread and bring the camera to its pin. Comment pins cluster together as you zoom out and separate back out as you zoom in.
|
|
18
|
+
|
|
19
|
+
Comment records live in `@tldraw/tlschema` as `TLCommentThread`, `TLComment`, and `TLCommentReaction`, and sync over a new generic object store in `@tldraw/sync-core`, so they ride alongside the document rather than inside it. On the server, `@tldraw/sync-collaboration` enforces write authorization, with a `canModifyComment` rule that lets a host widen the default owner-only permission. That way a workspace admin can moderate comments they don't own without granting anything beyond edit, delete, and resolve.
|
|
20
|
+
|
|
21
|
+
One rollout note: the comment record types ship with guard migrations, so once your server registers them, clients on an older SDK are rejected as too old and prompted to refresh. Roll out the upgraded client before or alongside the server change.
|
|
22
|
+
|
|
23
|
+
The layer is built to be taken apart. `ThreadRow` and `ThreadActions` are component slots, `CommentListItem` and `sortSidebarRows` are exported so a hand-built list can match the built-in one, and a host that supplies `getThreadHref` gets copy-link in the thread menu. On phones, the composer and the open thread stay above the software keyboard.
|
|
24
|
+
|
|
25
|
+
<details>
|
|
26
|
+
<summary>New packages</summary>
|
|
27
|
+
|
|
28
|
+
| Package | What it provides |
|
|
29
|
+
| ---------------------------- | ------------------------------------------------------------------------ |
|
|
30
|
+
| `@tldraw/commenting` | Canvas comments layer, comment UI components, and the comment tool |
|
|
31
|
+
| `@tldraw/mentions` | @-mention picker and TipTap node, shared by comments and shape rich text |
|
|
32
|
+
| `@tldraw/collaboration` | Umbrella package for the collaboration pieces |
|
|
33
|
+
| `@tldraw/sync-collaboration` | Server-side write authorization for collaboration features |
|
|
34
|
+
|
|
35
|
+
</details>
|
|
14
36
|
|
|
15
|
-
|
|
37
|
+
See the [commenting docs](https://tldraw.dev/docs/commenting) for setup.
|
|
16
38
|
|
|
17
39
|
### API changes
|
|
18
40
|
|
|
41
|
+
- 💥 Remove `usePassThroughMouseOverEvents` from `@tldraw/editor`. It re-dispatched `mouseover` at `.tl-canvas` so shapes under a floating panel stayed hovered, but the canvas only wires `onPointerEnter`, so the re-dispatched event arrived at an element with no listener for it. ([#9782](https://github.com/tldraw/tldraw/pull/9782))
|
|
42
|
+
- Add `TLCommentThread`, `TLComment`, and `TLCommentReaction` records to `@tldraw/tlschema`, with `createCommentThread` and `createComment` helpers, id helpers, validators, and `commentSchemaRecords` for registering them. ([#9471](https://github.com/tldraw/tldraw/pull/9471), [#9782](https://github.com/tldraw/tldraw/pull/9782))
|
|
43
|
+
- Add a generic object store to `@tldraw/sync-core` for syncing non-document records: `objectTypes` on the room and storage constructors, per-session `TLObjectStoreAccess`, `getObjectsSnapshot()`, `onCommittedChanges`, and an optional `TLSyncStorage.getObjectsByIds(ids)` for callers that need a few object-lane records rather than the whole lane. ([#9471](https://github.com/tldraw/tldraw/pull/9471), [#9782](https://github.com/tldraw/tldraw/pull/9782))
|
|
44
|
+
- Add `objectAccess` to the `synced-remote` member of `RemoteTLStoreWithStatus`, so a store from `useSync` reports whether the session can write object-lane records such as comments. If you construct that type yourself, in test mocks for example, you now need to supply `objectAccess`. ([#9471](https://github.com/tldraw/tldraw/pull/9471))
|
|
45
|
+
- Add `EditorPortal`, `EditorPortalProps`, and `useEditorPortalHost` to `@tldraw/editor`, for portalling canvas-anchored content into a host the editor renders last so its DOM order doesn't depend on mount timing. ([#9782](https://github.com/tldraw/tldraw/pull/9782))
|
|
46
|
+
- Add `renderHtmlFromRichTextWithExtensions(richText, extensions)` for rendering rich text outside a shape's editor config. `renderHtmlFromRichText` now fills _every_ empty paragraph with a `<br />` and keeps the paragraph's attributes, so an empty paragraph renders as `<p dir="auto"><br /></p>` — worth knowing if you snapshot that output. ([#9782](https://github.com/tldraw/tldraw/pull/9782))
|
|
47
|
+
- Add `flipX` and `flipY` to `TLGeoShapeProps`, with an `AddFlipProps` migration defaulting both to `false`, and add `PathBuilder.transform(mat)` for producing a transformed copy of a path. ([#9530](https://github.com/tldraw/tldraw/pull/9530))
|
|
48
|
+
- Add an optional `sizeToContentAspectRatio` to `EmbedDefinition` and a public `EmbedShapeUtil.resolveAspectRatio(shape)`. When set, an embed corrects its size after creation to its content's real aspect ratio, resolved from the URL's OpenGraph metadata via the editor's url asset handler. Existing custom embed definitions are unaffected. ([#9613](https://github.com/tldraw/tldraw/pull/9613))
|
|
49
|
+
- Add `ExportAsMenuGroup`, mirroring `CopyAsMenuGroup`, for the "Export as" submenu. ([#9589](https://github.com/tldraw/tldraw/pull/9589))
|
|
50
|
+
- Add `EditorManager`, a public abstract base class for editor managers that own a subscription or resource, so they share one teardown contract. `InputsManager`, `TickManager`, `FocusManager`, and `TextManager` now extend it. ([#9204](https://github.com/tldraw/tldraw/pull/9204))
|
|
51
|
+
- Populate `TLBaseExternalContent.sources` for file pastes, where it was previously always undefined, so custom `files` handlers and `onBeforePasteFromClipboard` can inspect the text, HTML, and url content that came alongside the files. ([#9763](https://github.com/tldraw/tldraw/pull/9763))
|
|
52
|
+
- Add an `assets` prop to `TldrawImage`, so a snapshot's images render from a custom asset store the same way they do in `Tldraw`. Previously `TldrawImage` always used the inline base64 asset store, so images kept anywhere else were missing. ([#9697](https://github.com/tldraw/tldraw/pull/9697)) (based on an implementation by [@jon-dez](https://github.com/jon-dez))
|
|
53
|
+
|
|
54
|
+
```tsx
|
|
55
|
+
<TldrawImage snapshot={snapshot} assets={assetStore} />
|
|
56
|
+
```
|
|
57
|
+
|
|
19
58
|
- Add an `unmount` event to `TLEventMap` and make `Editor.getIsMounted()` a reactive value that tracks whether the editor's component is currently mounted. ([#9472](https://github.com/tldraw/tldraw/pull/9472), [#9483](https://github.com/tldraw/tldraw/pull/9483))
|
|
20
59
|
- Make the shape hit-test margin pointer-aware and add a `coarseHitTestMargin` option: fine pointers (mouse and trackpad) use a tighter 3px default, coarse pointers (touch and pen) use 4px. ([#9492](https://github.com/tldraw/tldraw/pull/9492))
|
|
21
|
-
- Add a `ShapeUtil.onDuplicate(source, duplicate)` callback, invoked by `Editor.duplicateShapes` and `Editor.putContentOntoCurrentPage`,
|
|
60
|
+
- Add a `ShapeUtil.onDuplicate(source, duplicate)` callback, invoked by `Editor.duplicateShapes` and `Editor.putContentOntoCurrentPage`, so a shape can adjust its props when it is copied. Sticky notes now use it to attribute duplicated or pasted text to the current user instead of carrying over the original author. ([#9566](https://github.com/tldraw/tldraw/pull/9566))
|
|
22
61
|
|
|
23
62
|
### Improvements
|
|
24
63
|
|
|
64
|
+
- Geo shapes now flip. Previously flipping a selection left directional shapes such as the rhombus, trapezoid, and arrow geo shapes looking exactly the same on the other side of the mirror. `TLGeoShape` gains `flipX` and `flipY` props, matching the image shape, and a flip mirrors the shape's generated path. Geometry, hit-testing, the selection indicator, the canvas render, and SVG export all read from that path, so they stay in agreement. ([#9530](https://github.com/tldraw/tldraw/pull/9530))
|
|
65
|
+
- When cropping an image, crop edges now snap to other shapes and the grid, with the usual snapping guidelines. Holding Alt resizes the crop region symmetrically from its center. ([#9424](https://github.com/tldraw/tldraw/pull/9424))
|
|
66
|
+
- Size embeds from providers that report their content's dimensions (currently Vimeo) to that content's real aspect ratio, so a video is no longer letterboxed inside a 16:9 box. The corrected embed keeps the area of the original box, so a portrait video doesn't balloon over whatever sits above and below it. ([#9613](https://github.com/tldraw/tldraw/pull/9613), [#9756](https://github.com/tldraw/tldraw/pull/9756))
|
|
67
|
+
- Hide the "Copy as", "Export as", and "Export file" submenus, and the main menu's export group, when a consumer has removed all of their actions through `overrides`, instead of leaving an empty submenu trigger behind. ([#9589](https://github.com/tldraw/tldraw/pull/9589))
|
|
25
68
|
- Improve viewport culling performance on large pages: the spatial index now rechecks only the shapes affected by a change instead of every shape on the page. Custom shapes whose geometry depends on unrelated shapes (outside parent/child and binding relationships) are no longer automatically rechecked for culling when those shapes change; built-in shapes and standard patterns are unaffected. ([#9093](https://github.com/tldraw/tldraw/pull/9093))
|
|
26
69
|
- Improve performance when deleting many shapes at once by batching page state cleanup. ([#9456](https://github.com/tldraw/tldraw/pull/9456))
|
|
27
70
|
- Make long toast and dialog content wrap instead of overflowing, so long strings like URLs stay within the toast or dialog. ([#9546](https://github.com/tldraw/tldraw/pull/9546))
|
|
@@ -30,8 +73,11 @@ When cropping an image, crop edges now snap to other shapes and the grid, with t
|
|
|
30
73
|
|
|
31
74
|
### Bug fixes
|
|
32
75
|
|
|
76
|
+
- Fix zooming and panning not working while the cursor is over a non-scrollable UI overlay. The wheel pass-through guard treated any element whose content overflowed as scrollable, and a hover transform on a small overlay was enough to trigger that. Overlays now count as scrollable only when their computed `overflow` says so. ([#9698](https://github.com/tldraw/tldraw/pull/9698))
|
|
77
|
+
- Fix a crash when dragging content from another browser tab whose URL isn't a valid link, which happens when an ad blocker rewrites the dragged URL to something like `about:blank#blocked`. Dropping one now shows an error toast instead of failing validation on the bookmark shape. ([#9598](https://github.com/tldraw/tldraw/pull/9598))
|
|
78
|
+
- Fix the "URL" label wrapping onto two lines in the edit link and embed dialogs. ([#9663](https://github.com/tldraw/tldraw/pull/9663))
|
|
33
79
|
- Fix rich text headings (H1–H6) rendering with their line-height too tight, causing overlapping lines. ([#9543](https://github.com/tldraw/tldraw/pull/9543))
|
|
34
|
-
- Fix the style panel not highlighting the active fill correctly when the current fill lives in the overflow dropdown. ([#9509](https://github.com/tldraw/tldraw/pull/9509))
|
|
80
|
+
- Fix the style panel not highlighting the active fill correctly when the current fill lives in the overflow dropdown. ([#9509](https://github.com/tldraw/tldraw/pull/9509))
|
|
35
81
|
- Fix the style panel Shape, Line, and spline dropdown popovers so they open with the same gap as the other dropdowns. ([#9491](https://github.com/tldraw/tldraw/pull/9491))
|
|
36
82
|
- Fix double-clicking a shape inside an unfocused group immediately editing it; a double-click now drills one level into the group. ([#9488](https://github.com/tldraw/tldraw/pull/9488))
|
|
37
83
|
- Fix selected clipped arrows so they can be dragged when their geometry extends outside a clipping parent. ([#9479](https://github.com/tldraw/tldraw/pull/9479))
|
|
@@ -1299,7 +1345,7 @@ Draw and highlight shape point data is now stored using a compact delta-encoded
|
|
|
1299
1345
|
<details>
|
|
1300
1346
|
<summary>Breaking change details</summary>
|
|
1301
1347
|
|
|
1302
|
-
If you were reading or writing draw shape data
|
|
1348
|
+
If you were reading or writing draw shape data programmatically you might need to update your code to use the new format.
|
|
1303
1349
|
|
|
1304
1350
|
- `TLDrawShapeSegment.points` renamed to `.path` and changed from `VecModel[]` to `string` (base64-encoded)
|
|
1305
1351
|
- Added `scaleX` and `scaleY` properties to draw and highlight shapes
|