@excalidraw/excalidraw 0.18.0-c65b684e9 → 0.18.0-c6f8ef9

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.
@@ -2,7 +2,7 @@ import {
2
2
  decodePngMetadata,
3
3
  encodePngMetadata,
4
4
  getTEXtChunk
5
- } from "../chunk-65CT75SH.js";
5
+ } from "../chunk-CRKRRBMD.js";
6
6
  import "../chunk-CP5DND7P.js";
7
7
  import "../chunk-XDFCUUT6.js";
8
8
  export {
@@ -10,4 +10,4 @@ export {
10
10
  encodePngMetadata,
11
11
  getTEXtChunk
12
12
  };
13
- //# sourceMappingURL=image-G3ZXYWE6.js.map
13
+ //# sourceMappingURL=image-IWGLHPIX.js.map
package/dist/dev/index.js CHANGED
@@ -60,6 +60,7 @@ import {
60
60
  resizeImageFile,
61
61
  restore,
62
62
  restoreAppState,
63
+ restoreElement,
63
64
  restoreElements,
64
65
  restoreLibraryItems,
65
66
  saveAsJSON,
@@ -68,7 +69,7 @@ import {
68
69
  serializeLibraryAsJSON,
69
70
  strokeEllipseWithRotation,
70
71
  strokeRectWithRotation
71
- } from "./chunk-65CT75SH.js";
72
+ } from "./chunk-CRKRRBMD.js";
72
73
  import {
73
74
  define_import_meta_env_default
74
75
  } from "./chunk-CP5DND7P.js";
@@ -203,7 +204,7 @@ import {
203
204
  updateBoundElements as updateBoundElements3,
204
205
  getSuggestedBindingsForArrows,
205
206
  LinearElementEditor as LinearElementEditor12,
206
- newElementWith as newElementWith10,
207
+ newElementWith as newElementWith11,
207
208
  newFrameElement as newFrameElement3,
208
209
  newFreeDrawElement,
209
210
  newEmbeddableElement,
@@ -318,7 +319,8 @@ import {
318
319
  CaptureUpdateAction as CaptureUpdateAction37,
319
320
  hitElementBoundingBox as hitElementBoundingBox2,
320
321
  isLineElement as isLineElement7,
321
- isSimpleArrow
322
+ isSimpleArrow,
323
+ StoreDelta as StoreDelta2
322
324
  } from "@excalidraw/element";
323
325
 
324
326
  // actions/actionDeleteSelected.tsx
@@ -7804,7 +7806,11 @@ import {
7804
7806
  bindOrUnbindLinearElement,
7805
7807
  isBindingEnabled
7806
7808
  } from "@excalidraw/element/binding";
7807
- import { isValidPolygon, LinearElementEditor as LinearElementEditor5 } from "@excalidraw/element";
7809
+ import {
7810
+ isValidPolygon,
7811
+ LinearElementEditor as LinearElementEditor5,
7812
+ newElementWith as newElementWith4
7813
+ } from "@excalidraw/element";
7808
7814
  import {
7809
7815
  isBindingElement,
7810
7816
  isFreeDrawElement,
@@ -7849,7 +7855,14 @@ var actionFinalize = register({
7849
7855
  if (linearElementEditor !== appState.selectedLinearElement) {
7850
7856
  let newElements2 = elements;
7851
7857
  if (element2 && isInvisiblySmallElement(element2)) {
7852
- newElements2 = newElements2.filter((el) => el.id !== element2.id);
7858
+ newElements2 = newElements2.map((el) => {
7859
+ if (el.id === element2.id) {
7860
+ return newElementWith4(el, {
7861
+ isDeleted: true
7862
+ });
7863
+ }
7864
+ return el;
7865
+ });
7853
7866
  }
7854
7867
  return {
7855
7868
  elements: newElements2,
@@ -7882,7 +7895,12 @@ var actionFinalize = register({
7882
7895
  });
7883
7896
  }
7884
7897
  return {
7885
- elements: element2.points.length < 2 || isInvisiblySmallElement(element2) ? elements.filter((el) => el.id !== element2.id) : void 0,
7898
+ elements: element2.points.length < 2 || isInvisiblySmallElement(element2) ? elements.map((el) => {
7899
+ if (el.id === element2.id) {
7900
+ return newElementWith4(el, { isDeleted: true });
7901
+ }
7902
+ return el;
7903
+ }) : void 0,
7886
7904
  appState: {
7887
7905
  ...appState,
7888
7906
  cursorButton: "up",
@@ -7924,7 +7942,12 @@ var actionFinalize = register({
7924
7942
  }
7925
7943
  }
7926
7944
  if (element && isInvisiblySmallElement(element)) {
7927
- newElements = newElements.filter((el) => el.id !== element.id);
7945
+ newElements = newElements.map((el) => {
7946
+ if (el.id === element?.id) {
7947
+ return newElementWith4(el, { isDeleted: true });
7948
+ }
7949
+ return el;
7950
+ });
7928
7951
  }
7929
7952
  if (isLinearElement3(element) || isFreeDrawElement(element)) {
7930
7953
  const isLoop = isPathALoop(element.points, appState.zoom.value);
@@ -8936,7 +8959,7 @@ var exportCanvas = async (type, elements, appState, files, {
8936
8959
  let blob = canvasToBlob(tempCanvas);
8937
8960
  if (appState.exportEmbedScene) {
8938
8961
  blob = blob.then(
8939
- (blob2) => import("./data/image-G3ZXYWE6.js").then(
8962
+ (blob2) => import("./data/image-IWGLHPIX.js").then(
8940
8963
  ({ encodePngMetadata: encodePngMetadata2 }) => encodePngMetadata2({
8941
8964
  blob: blob2,
8942
8965
  metadata: serializeAsJSON(elements, appState, files, "local")
@@ -9277,7 +9300,7 @@ import {
9277
9300
  KEYS as KEYS16,
9278
9301
  getLineHeight as getLineHeight2
9279
9302
  } from "@excalidraw/common";
9280
- import { newElementWith as newElementWith4 } from "@excalidraw/element";
9303
+ import { newElementWith as newElementWith5 } from "@excalidraw/element";
9281
9304
  import {
9282
9305
  hasBoundTextElement,
9283
9306
  canApplyRoundnessTypeToElement,
@@ -9348,7 +9371,7 @@ var actionPasteStyles = register({
9348
9371
  if (!elementStylesToCopyFrom) {
9349
9372
  return element;
9350
9373
  }
9351
- let newElement6 = newElementWith4(element, {
9374
+ let newElement6 = newElementWith5(element, {
9352
9375
  backgroundColor: elementStylesToCopyFrom?.backgroundColor,
9353
9376
  strokeWidth: elementStylesToCopyFrom?.strokeWidth,
9354
9377
  strokeColor: elementStylesToCopyFrom?.strokeColor,
@@ -9364,7 +9387,7 @@ var actionPasteStyles = register({
9364
9387
  if (isTextElement3(newElement6)) {
9365
9388
  const fontSize = elementStylesToCopyFrom.fontSize || DEFAULT_FONT_SIZE3;
9366
9389
  const fontFamily = elementStylesToCopyFrom.fontFamily || DEFAULT_FONT_FAMILY3;
9367
- newElement6 = newElementWith4(newElement6, {
9390
+ newElement6 = newElementWith5(newElement6, {
9368
9391
  fontSize,
9369
9392
  fontFamily,
9370
9393
  textAlign: elementStylesToCopyFrom.textAlign || DEFAULT_TEXT_ALIGN,
@@ -9379,13 +9402,13 @@ var actionPasteStyles = register({
9379
9402
  redrawTextBoundingBox2(newElement6, container, app.scene);
9380
9403
  }
9381
9404
  if (newElement6.type === "arrow" && isArrowElement2(elementStylesToCopyFrom)) {
9382
- newElement6 = newElementWith4(newElement6, {
9405
+ newElement6 = newElementWith5(newElement6, {
9383
9406
  startArrowhead: elementStylesToCopyFrom.startArrowhead,
9384
9407
  endArrowhead: elementStylesToCopyFrom.endArrowhead
9385
9408
  });
9386
9409
  }
9387
9410
  if (isFrameLikeElement4(element)) {
9388
- newElement6 = newElementWith4(newElement6, {
9411
+ newElement6 = newElementWith5(newElement6, {
9389
9412
  roundness: null,
9390
9413
  backgroundColor: "transparent"
9391
9414
  });
@@ -9479,7 +9502,7 @@ var actionShortcuts = register({
9479
9502
 
9480
9503
  // actions/actionGroup.tsx
9481
9504
  import { getNonDeletedElements as getNonDeletedElements9 } from "@excalidraw/element";
9482
- import { newElementWith as newElementWith5 } from "@excalidraw/element";
9505
+ import { newElementWith as newElementWith6 } from "@excalidraw/element";
9483
9506
  import { isBoundToContainer as isBoundToContainer3 } from "@excalidraw/element";
9484
9507
  import {
9485
9508
  frameAndChildrenSelectedTogether,
@@ -9583,7 +9606,7 @@ var actionGroup = register({
9583
9606
  if (!selectElementIds.get(element.id)) {
9584
9607
  return element;
9585
9608
  }
9586
- return newElementWith5(element, {
9609
+ return newElementWith6(element, {
9587
9610
  groupIds: addToGroup(
9588
9611
  element.groupIds,
9589
9612
  newGroupId,
@@ -9660,7 +9683,7 @@ var actionUngroup = register({
9660
9683
  if (nextGroupIds.length === element.groupIds.length) {
9661
9684
  return element;
9662
9685
  }
9663
- return newElementWith5(element, {
9686
+ return newElementWith6(element, {
9664
9687
  groupIds: nextGroupIds
9665
9688
  });
9666
9689
  });
@@ -10459,7 +10482,7 @@ import {
10459
10482
  isBindingEnabled as isBindingEnabled2
10460
10483
  } from "@excalidraw/element";
10461
10484
  import { getCommonBoundingBox } from "@excalidraw/element";
10462
- import { newElementWith as newElementWith6 } from "@excalidraw/element";
10485
+ import { newElementWith as newElementWith7 } from "@excalidraw/element";
10463
10486
  import { deepCopyElement as deepCopyElement3 } from "@excalidraw/element";
10464
10487
  import { resizeMultipleElements } from "@excalidraw/element";
10465
10488
  import {
@@ -10545,7 +10568,7 @@ var flipElements = (selectedElements, elementsMap, appState, flipDirection, app)
10545
10568
  )) {
10546
10569
  return selectedElements.map((element) => {
10547
10570
  const _element = element;
10548
- return newElementWith6(_element, {
10571
+ return newElementWith7(_element, {
10549
10572
  startArrowhead: _element.endArrowhead,
10550
10573
  endArrowhead: _element.startArrowhead
10551
10574
  });
@@ -11616,7 +11639,7 @@ var actionLink = register({
11616
11639
  import { KEYS as KEYS29, arrayToMap as arrayToMap11, randomId as randomId4 } from "@excalidraw/common";
11617
11640
  import {
11618
11641
  elementsAreInSameGroup,
11619
- newElementWith as newElementWith7,
11642
+ newElementWith as newElementWith8,
11620
11643
  selectGroupsFromGivenElements
11621
11644
  } from "@excalidraw/element";
11622
11645
  import { CaptureUpdateAction as CaptureUpdateAction25 } from "@excalidraw/element";
@@ -11677,7 +11700,7 @@ var actionToggleElementLock = register({
11677
11700
  (groupId) => !appState.lockedMultiSelections[groupId]
11678
11701
  );
11679
11702
  }
11680
- return newElementWith7(element, {
11703
+ return newElementWith8(element, {
11681
11704
  locked: nextLockState,
11682
11705
  // do not recreate the array unncessarily
11683
11706
  groupIds: nextGroupIds.length !== element.groupIds.length ? nextGroupIds : element.groupIds
@@ -11726,7 +11749,7 @@ var actionUnlockAllElements = register({
11726
11749
  const nextGroupIds = element.groupIds.filter(
11727
11750
  (gid) => !appState.lockedMultiSelections[gid]
11728
11751
  );
11729
- return newElementWith7(element, {
11752
+ return newElementWith8(element, {
11730
11753
  locked: false,
11731
11754
  groupIds: (
11732
11755
  // do not recreate the array unncessarily
@@ -12842,7 +12865,8 @@ var exportToCanvas2 = ({
12842
12865
  const { elements: restoredElements, appState: restoredAppState } = restore(
12843
12866
  { elements, appState },
12844
12867
  null,
12845
- null
12868
+ null,
12869
+ { deleteInvisibleElements: true }
12846
12870
  );
12847
12871
  const { exportBackground, viewBackgroundColor } = restoredAppState;
12848
12872
  return exportToCanvas(
@@ -12936,7 +12960,8 @@ var exportToSvg2 = async ({
12936
12960
  const { elements: restoredElements, appState: restoredAppState } = restore(
12937
12961
  { elements, appState },
12938
12962
  null,
12939
- null
12963
+ null,
12964
+ { deleteInvisibleElements: true }
12940
12965
  );
12941
12966
  const exportAppState = {
12942
12967
  ...restoredAppState,
@@ -18225,7 +18250,7 @@ var generateElbowArrowShape = (points, radius) => {
18225
18250
  };
18226
18251
 
18227
18252
  // ../element/src/mutateElement.ts
18228
- var newElementWith8 = (element, updates, force = false) => {
18253
+ var newElementWith9 = (element, updates, force = false) => {
18229
18254
  let didChange = false;
18230
18255
  for (const key in updates) {
18231
18256
  const value = updates[key];
@@ -18354,7 +18379,7 @@ var actionTogglePolygon = register({
18354
18379
  if (!targetElementsMap.has(element.id) || !isLineElement4(element)) {
18355
18380
  return element;
18356
18381
  }
18357
- return newElementWith8(element, {
18382
+ return newElementWith9(element, {
18358
18383
  backgroundColor: nextPolygonState ? element.backgroundColor : "transparent",
18359
18384
  ...toggleLinePolygonState3(element, nextPolygonState)
18360
18385
  });
@@ -18946,7 +18971,7 @@ var createRedoAction = (history) => ({
18946
18971
 
18947
18972
  // actions/actionTextAutoResize.ts
18948
18973
  import { getFontString as getFontString6 } from "@excalidraw/common";
18949
- import { newElementWith as newElementWith9 } from "@excalidraw/element";
18974
+ import { newElementWith as newElementWith10 } from "@excalidraw/element";
18950
18975
  import { measureText as measureText4 } from "@excalidraw/element";
18951
18976
  import { isTextElement as isTextElement9 } from "@excalidraw/element";
18952
18977
  import { CaptureUpdateAction as CaptureUpdateAction34 } from "@excalidraw/element";
@@ -18970,7 +18995,7 @@ var actionTextAutoResize = register({
18970
18995
  getFontString6(element),
18971
18996
  element.lineHeight
18972
18997
  );
18973
- return newElementWith9(element, {
18998
+ return newElementWith10(element, {
18974
18999
  autoResize: true,
18975
19000
  width: metrics.width,
18976
19001
  height: metrics.height,
@@ -31600,7 +31625,7 @@ var App = class _App extends React43.Component {
31600
31625
  this.updateScene({
31601
31626
  elements: this.scene.getElementsIncludingDeleted().map((el) => {
31602
31627
  if (this.state.selectedElementIds[el.id]) {
31603
- return newElementWith10(el, {
31628
+ return newElementWith11(el, {
31604
31629
  [shouldUpdateStrokeColor ? "strokeColor" : "backgroundColor"]: color
31605
31630
  });
31606
31631
  }
@@ -31764,7 +31789,10 @@ var App = class _App extends React43.Component {
31764
31789
  }
31765
31790
  };
31766
31791
  }
31767
- const scene = restore(initialData, null, null, { repairBindings: true });
31792
+ const scene = restore(initialData, null, null, {
31793
+ repairBindings: true,
31794
+ deleteInvisibleElements: true
31795
+ });
31768
31796
  scene.appState = {
31769
31797
  ...scene.appState,
31770
31798
  theme: this.props.theme || scene.appState.theme,
@@ -32084,7 +32112,9 @@ var App = class _App extends React43.Component {
32084
32112
  }
32085
32113
  ));
32086
32114
  __publicField(this, "addElementsFromPasteOrLibrary", (opts) => {
32087
- const elements = restoreElements(opts.elements, null, void 0);
32115
+ const elements = restoreElements(opts.elements, null, {
32116
+ deleteInvisibleElements: true
32117
+ });
32088
32118
  const [minX, minY, maxX, maxY] = getCommonBounds12(elements);
32089
32119
  const elementsCenterX = distance2(minX, maxX) / 2;
32090
32120
  const elementsCenterY = distance2(minY, maxY) / 2;
@@ -32100,7 +32130,7 @@ var App = class _App extends React43.Component {
32100
32130
  const { duplicatedElements } = duplicateElements3({
32101
32131
  type: "everything",
32102
32132
  elements: elements.map((element) => {
32103
- return newElementWith10(element, {
32133
+ return newElementWith11(element, {
32104
32134
  x: element.x + gridX - minX,
32105
32135
  y: element.y + gridY - minY
32106
32136
  });
@@ -32447,6 +32477,19 @@ var App = class _App extends React43.Component {
32447
32477
  }
32448
32478
  }
32449
32479
  ));
32480
+ __publicField(this, "applyDeltas", (deltas, options) => {
32481
+ const aggregatedDelta = StoreDelta2.squash(...deltas);
32482
+ const nextAppState = { ...this.state };
32483
+ const nextElements = new Map(
32484
+ this.scene.getElementsMapIncludingDeleted()
32485
+ );
32486
+ return StoreDelta2.applyTo(
32487
+ aggregatedDelta,
32488
+ nextElements,
32489
+ nextAppState,
32490
+ options
32491
+ );
32492
+ });
32450
32493
  __publicField(this, "mutateElement", (element, updates, informMutation = true) => {
32451
32494
  return this.scene.mutateElement(element, updates, {
32452
32495
  informMutation,
@@ -33468,7 +33511,7 @@ var App = class _App extends React43.Component {
33468
33511
  __publicField(this, "getTopLayerFrameAtSceneCoords", (sceneCoords) => {
33469
33512
  const elementsMap = this.scene.getNonDeletedElementsMap();
33470
33513
  const frames = this.scene.getNonDeletedFramesLikes().filter(
33471
- (frame) => isCursorInFrame(sceneCoords, frame, elementsMap)
33514
+ (frame) => !frame.locked && isCursorInFrame(sceneCoords, frame, elementsMap)
33472
33515
  );
33473
33516
  return frames.length ? frames[frames.length - 1] : null;
33474
33517
  });
@@ -34867,7 +34910,7 @@ var App = class _App extends React43.Component {
34867
34910
  const elements = this.scene.getElementsIncludingDeleted().map((ele) => {
34868
34911
  if (this.elementsPendingErasure.has(ele.id) || ele.frameId && this.elementsPendingErasure.has(ele.frameId) || isBoundToContainer8(ele) && this.elementsPendingErasure.has(ele.containerId)) {
34869
34912
  didChange = true;
34870
- return newElementWith10(ele, { isDeleted: true });
34913
+ return newElementWith11(ele, { isDeleted: true });
34871
34914
  }
34872
34915
  return ele;
34873
34916
  });
@@ -34976,7 +35019,7 @@ var App = class _App extends React43.Component {
34976
35019
  */
34977
35020
  __publicField(this, "getLatestInitializedImageElement", (imagePlaceholder, fileId) => {
34978
35021
  const latestImageElement = this.scene.getElement(imagePlaceholder.id) ?? imagePlaceholder;
34979
- return newElementWith10(
35022
+ return newElementWith11(
34980
35023
  latestImageElement,
34981
35024
  {
34982
35025
  fileId
@@ -35095,9 +35138,9 @@ var App = class _App extends React43.Component {
35095
35138
  if (erroredFiles.size) {
35096
35139
  this.store.scheduleAction(CaptureUpdateAction37.NEVER);
35097
35140
  this.scene.replaceAllElements(
35098
- elements.map((element) => {
35141
+ this.scene.getElementsIncludingDeleted().map((element) => {
35099
35142
  if (isInitializedImageElement3(element) && erroredFiles.has(element.fileId)) {
35100
- return newElementWith10(element, {
35143
+ return newElementWith11(element, {
35101
35144
  status: "error"
35102
35145
  });
35103
35146
  }
@@ -35841,6 +35884,7 @@ var App = class _App extends React43.Component {
35841
35884
  if (excalidrawAPI) {
35842
35885
  const api = {
35843
35886
  updateScene: this.updateScene,
35887
+ applyDeltas: this.applyDeltas,
35844
35888
  mutateElement: this.mutateElement,
35845
35889
  updateLibrary: this.library.updateLibrary,
35846
35890
  addFiles: this.addFiles,
@@ -37134,7 +37178,7 @@ var App = class _App extends React43.Component {
37134
37178
  // Not sure why we include deleted elements as well hence using deleted elements map
37135
37179
  ...this.scene.getElementsIncludingDeleted().map((_element) => {
37136
37180
  if (_element.id === element.id && isTextElement19(_element)) {
37137
- return newElementWith10(_element, {
37181
+ return newElementWith11(_element, {
37138
37182
  originalText: nextOriginalText,
37139
37183
  isDeleted: isDeleted ?? _element.isDeleted,
37140
37184
  // returns (wrapped) text and new dimensions
@@ -37174,13 +37218,7 @@ var App = class _App extends React43.Component {
37174
37218
  }),
37175
37219
  onSubmit: withBatchedUpdates(({ viaKeyboard, nextOriginalText }) => {
37176
37220
  const isDeleted = !nextOriginalText.trim();
37177
- if (isDeleted && !isExistingElement) {
37178
- this.scene.replaceAllElements(
37179
- this.scene.getElementsIncludingDeleted().filter((x) => x.id !== element.id)
37180
- );
37181
- } else {
37182
- updateElement(nextOriginalText, isDeleted);
37183
- }
37221
+ updateElement(nextOriginalText, isDeleted);
37184
37222
  if (!isDeleted && viaKeyboard) {
37185
37223
  const elementIdToSelect = element.containerId ? element.containerId : element.id;
37186
37224
  flushSync3(() => {
@@ -37200,7 +37238,9 @@ var App = class _App extends React43.Component {
37200
37238
  element
37201
37239
  ]);
37202
37240
  }
37203
- this.store.scheduleCapture();
37241
+ if (!isDeleted || isExistingElement) {
37242
+ this.store.scheduleCapture();
37243
+ }
37204
37244
  flushSync3(() => {
37205
37245
  this.setState({
37206
37246
  newElement: null,
@@ -37950,7 +37990,7 @@ var App = class _App extends React43.Component {
37950
37990
  if (idsOfElementsToDuplicate.has(el.id)) {
37951
37991
  const origEl = pointerDownState.originalElements.get(el.id);
37952
37992
  if (origEl) {
37953
- return newElementWith10(el, {
37993
+ return newElementWith11(el, {
37954
37994
  x: origEl.x,
37955
37995
  y: origEl.y
37956
37996
  });
@@ -39326,8 +39366,7 @@ import {
39326
39366
  } from "@excalidraw/element";
39327
39367
  var shouldDiscardRemoteElement = (localAppState, local, remote) => {
39328
39368
  if (local && // local element is being edited
39329
- (local.id === localAppState.editingTextElement?.id || local.id === localAppState.resizingElement?.id || local.id === localAppState.newElement?.id || // TODO: Is this still valid? As newElement is selection element, which is never part of the elements array
39330
- // local element is newer
39369
+ (local.id === localAppState.editingTextElement?.id || local.id === localAppState.resizingElement?.id || local.id === localAppState.newElement?.id || // local element is newer
39331
39370
  local.version > remote.version || // resolve conflicting edits deterministically by taking the one with
39332
39371
  // the lowest versionNonce
39333
39372
  local.version === remote.version && local.versionNonce < remote.versionNonce)) {
@@ -39402,7 +39441,7 @@ import {
39402
39441
  } from "@excalidraw/common";
39403
39442
  import {
39404
39443
  mutateElement as mutateElement2,
39405
- newElementWith as newElementWith11,
39444
+ newElementWith as newElementWith12,
39406
39445
  bumpVersion
39407
39446
  } from "@excalidraw/element";
39408
39447
  import { CaptureUpdateAction as CaptureUpdateAction38 } from "@excalidraw/element";
@@ -39653,12 +39692,13 @@ export {
39653
39692
  loadSceneOrLibraryFromBlob,
39654
39693
  mergeLibraryItems,
39655
39694
  mutateElement2 as mutateElement,
39656
- newElementWith11 as newElementWith,
39695
+ newElementWith12 as newElementWith,
39657
39696
  normalizeLink4 as normalizeLink,
39658
39697
  parseLibraryTokensFromUrl,
39659
39698
  reconcileElements,
39660
39699
  restore,
39661
39700
  restoreAppState,
39701
+ restoreElement,
39662
39702
  restoreElements,
39663
39703
  restoreLibraryItems,
39664
39704
  sceneCoordsToViewportCoords2 as sceneCoordsToViewportCoords,