@myoc/excalidraw 0.19.532 → 0.19.534

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 (66) hide show
  1. package/CHANGELOG.md +160 -0
  2. package/dist/dev/{chunk-ITMOGRAW.js → chunk-LMB2JFA3.js} +23 -8
  3. package/dist/dev/chunk-LMB2JFA3.js.map +7 -0
  4. package/dist/dev/{chunk-ASAPRLCW.js → chunk-LXITAORX.js} +2 -2
  5. package/dist/dev/data/{image-S7APFFV6.js → image-42C5IMES.js} +3 -3
  6. package/dist/dev/index.css +248 -0
  7. package/dist/dev/index.css.map +3 -3
  8. package/dist/dev/index.js +1374 -591
  9. package/dist/dev/index.js.map +4 -4
  10. package/dist/dev/subset-shared.chunk.js +1 -1
  11. package/dist/dev/subset-worker.chunk.js +1 -1
  12. package/dist/prod/chunk-GTKIAGSI.js +4 -0
  13. package/dist/prod/{chunk-GSRXJLOQ.js → chunk-J5EM63O7.js} +1 -1
  14. package/dist/prod/data/image-SPSR2YYO.js +1 -0
  15. package/dist/prod/index.css +1 -1
  16. package/dist/prod/index.js +19 -19
  17. package/dist/prod/subset-shared.chunk.js +1 -1
  18. package/dist/prod/subset-worker.chunk.js +1 -1
  19. package/dist/types/common/src/constants.d.ts +1 -0
  20. package/dist/types/element/src/gif.d.ts +29 -0
  21. package/dist/types/element/src/image.d.ts +6 -1
  22. package/dist/types/element/src/index.d.ts +2 -0
  23. package/dist/types/element/src/newElement.d.ts +1 -0
  24. package/dist/types/element/src/renderGif.d.ts +5 -0
  25. package/dist/types/element/src/types.d.ts +12 -0
  26. package/dist/types/excalidraw/actions/actionBoundText.d.ts +2 -2
  27. package/dist/types/excalidraw/actions/actionCanvas.d.ts +6 -6
  28. package/dist/types/excalidraw/actions/actionClipboard.d.ts +2 -2
  29. package/dist/types/excalidraw/actions/actionCropEditor.d.ts +1 -1
  30. package/dist/types/excalidraw/actions/actionDeleteSelected.d.ts +3 -3
  31. package/dist/types/excalidraw/actions/actionDeselect.d.ts +1 -1
  32. package/dist/types/excalidraw/actions/actionElementLink.d.ts +1 -1
  33. package/dist/types/excalidraw/actions/actionElementLock.d.ts +2 -2
  34. package/dist/types/excalidraw/actions/actionExport.d.ts +2 -2
  35. package/dist/types/excalidraw/actions/actionFrame.d.ts +4 -3
  36. package/dist/types/excalidraw/actions/actionGroup.d.ts +2 -2
  37. package/dist/types/excalidraw/actions/actionLinearEditor.d.ts +2 -1
  38. package/dist/types/excalidraw/actions/actionLink.d.ts +1 -1
  39. package/dist/types/excalidraw/actions/actionProperties.d.ts +2 -2
  40. package/dist/types/excalidraw/actions/actionSelectAll.d.ts +1 -1
  41. package/dist/types/excalidraw/actions/actionStyles.d.ts +1 -1
  42. package/dist/types/excalidraw/actions/actionToggleArrowBinding.d.ts +1 -1
  43. package/dist/types/excalidraw/actions/actionToggleGridMode.d.ts +1 -1
  44. package/dist/types/excalidraw/actions/actionToggleMidpointSnapping.d.ts +1 -1
  45. package/dist/types/excalidraw/actions/actionToggleObjectsSnapMode.d.ts +1 -1
  46. package/dist/types/excalidraw/actions/actionToggleSearchMenu.d.ts +1 -1
  47. package/dist/types/excalidraw/actions/actionToggleStats.d.ts +1 -1
  48. package/dist/types/excalidraw/actions/actionToggleViewMode.d.ts +1 -1
  49. package/dist/types/excalidraw/components/App.d.ts +8 -1
  50. package/dist/types/excalidraw/components/App.gif.d.ts +18 -0
  51. package/dist/types/excalidraw/components/GifPlaybackControls.d.ts +10 -0
  52. package/dist/types/excalidraw/components/icons.d.ts +4 -0
  53. package/dist/types/excalidraw/data/blob.d.ts +2 -2
  54. package/dist/types/excalidraw/data/json.d.ts +1 -1
  55. package/dist/types/excalidraw/data/restoreGif.d.ts +4 -0
  56. package/dist/types/excalidraw/index.d.ts +1 -1
  57. package/dist/types/excalidraw/scene/Renderer.d.ts +1 -0
  58. package/dist/types/excalidraw/scene/types.d.ts +2 -1
  59. package/dist/types/excalidraw/types.d.ts +12 -2
  60. package/dist/types/excalidraw/viewport.d.ts +1 -1
  61. package/package.json +5 -5
  62. package/dist/dev/chunk-ITMOGRAW.js.map +0 -7
  63. package/dist/prod/chunk-U3WBDUKM.js +0 -4
  64. package/dist/prod/data/image-MWFLMJV7.js +0 -1
  65. /package/dist/dev/{chunk-ASAPRLCW.js.map → chunk-LXITAORX.js.map} +0 -0
  66. /package/dist/dev/data/{image-S7APFFV6.js.map → image-42C5IMES.js.map} +0 -0
package/dist/dev/index.js CHANGED
@@ -63,10 +63,10 @@ import {
63
63
  serializeAsJSON,
64
64
  strokeRectWithRotation_simple,
65
65
  zoomToFitBounds
66
- } from "./chunk-ITMOGRAW.js";
66
+ } from "./chunk-LMB2JFA3.js";
67
67
  import {
68
68
  define_import_meta_env_default
69
- } from "./chunk-ASAPRLCW.js";
69
+ } from "./chunk-LXITAORX.js";
70
70
  import {
71
71
  en_default
72
72
  } from "./chunk-SKCAT7JG.js";
@@ -80,7 +80,7 @@ import {
80
80
  } from "./chunk-XDFCUUT6.js";
81
81
 
82
82
  // index.tsx
83
- import React42, {
83
+ import React43, {
84
84
  useCallback as useCallback13,
85
85
  useContext as useContext5,
86
86
  useEffect as useEffect40,
@@ -96,9 +96,9 @@ import {
96
96
  } from "@excalidraw/common";
97
97
 
98
98
  // components/App.tsx
99
- import clsx60 from "clsx";
99
+ import clsx61 from "clsx";
100
100
  import throttle3 from "lodash.throttle";
101
- import React40, { useContext as useContext4 } from "react";
101
+ import React41, { useContext as useContext4 } from "react";
102
102
  import { flushSync as flushSync2 } from "react-dom";
103
103
  import rough3 from "roughjs/bin/rough";
104
104
  import { nanoid } from "nanoid";
@@ -134,7 +134,7 @@ import {
134
134
  IMAGE_MIME_TYPES as IMAGE_MIME_TYPES2,
135
135
  IMAGE_RENDER_TIMEOUT,
136
136
  LINE_CONFIRM_THRESHOLD as LINE_CONFIRM_THRESHOLD2,
137
- MIME_TYPES as MIME_TYPES9,
137
+ MIME_TYPES as MIME_TYPES11,
138
138
  MQ_RIGHT_SIDEBAR_MIN_WIDTH,
139
139
  POINTER_BUTTON as POINTER_BUTTON2,
140
140
  ROUNDNESS as ROUNDNESS8,
@@ -166,7 +166,7 @@ import {
166
166
  isInputLike,
167
167
  isToolIcon,
168
168
  isWritableElement as isWritableElement4,
169
- sceneCoordsToViewportCoords as sceneCoordsToViewportCoords6,
169
+ sceneCoordsToViewportCoords as sceneCoordsToViewportCoords7,
170
170
  tupleToCoors,
171
171
  viewportCoordsToSceneCoords as viewportCoordsToSceneCoords3,
172
172
  wrapEvent as wrapEvent2,
@@ -206,7 +206,7 @@ import {
206
206
  } from "@excalidraw/common";
207
207
  import {
208
208
  getObservedAppState as getObservedAppState2,
209
- getCommonBounds as getCommonBounds13,
209
+ getCommonBounds as getCommonBounds14,
210
210
  getElementAbsoluteCoords as getElementAbsoluteCoords8,
211
211
  bindOrUnbindBindingElements as bindOrUnbindBindingElements2,
212
212
  fixBindingsAfterDeletion as fixBindingsAfterDeletion2,
@@ -214,7 +214,7 @@ import {
214
214
  isBindingEnabled as isBindingEnabled3,
215
215
  updateBoundElements as updateBoundElements6,
216
216
  LinearElementEditor as LinearElementEditor12,
217
- newElementWith as newElementWith10,
217
+ newElementWith as newElementWith11,
218
218
  newFrameElement as newFrameElement3,
219
219
  newFreeDrawElement,
220
220
  newEmbeddableElement,
@@ -236,7 +236,7 @@ import {
236
236
  isFrameLikeElement as isFrameLikeElement17,
237
237
  isImageElement as isImageElement9,
238
238
  isEmbeddableElement as isEmbeddableElement4,
239
- isInitializedImageElement as isInitializedImageElement3,
239
+ isInitializedImageElement as isInitializedImageElement5,
240
240
  isLinearElement as isLinearElement11,
241
241
  isLinearElementType as isLinearElementType2,
242
242
  isUsingAdaptiveRadius as isUsingAdaptiveRadius5,
@@ -294,7 +294,7 @@ import {
294
294
  getApproxMinLineWidth as getApproxMinLineWidth3,
295
295
  getApproxMinLineHeight as getApproxMinLineHeight2,
296
296
  getMinTextElementWidth as getMinTextElementWidth2,
297
- ShapeCache as ShapeCache5,
297
+ ShapeCache as ShapeCache7,
298
298
  getRenderOpacity,
299
299
  editGroupForSelectedElement,
300
300
  getElementsInGroup as getElementsInGroup12,
@@ -638,6 +638,10 @@ var PlusIcon = createIcon(
638
638
  ] }),
639
639
  tablerIconProps
640
640
  );
641
+ var CirclePauseIcon = createIcon(
642
+ "M320 112C434.9 112 528 205.1 528 320C528 434.9 434.9 528 320 528C205.1 528 112 434.9 112 320C112 205.1 205.1 112 320 112zM320 576C461.4 576 576 461.4 576 320C576 178.6 461.4 64 320 64C178.6 64 64 178.6 64 320C64 461.4 178.6 576 320 576zM288 248C288 234.7 277.3 224 264 224C250.7 224 240 234.7 240 248L240 392C240 405.3 250.7 416 264 416C277.3 416 288 405.3 288 392L288 248zM400 248C400 234.7 389.3 224 376 224C362.7 224 352 234.7 352 248L352 392C352 405.3 362.7 416 376 416C389.3 416 400 405.3 400 392L400 248z",
643
+ 640
644
+ );
641
645
  var DotsIcon = createIcon(
642
646
  /* @__PURE__ */ jsxs("g", { strokeWidth: "1.5", children: [
643
647
  /* @__PURE__ */ jsx("path", { stroke: "none", d: "M0 0h24v24H0z", fill: "none" }),
@@ -2482,6 +2486,33 @@ var playerStopFilledIcon = createIcon(
2482
2486
  ] }),
2483
2487
  tablerIconProps
2484
2488
  );
2489
+ var prevFrame = createIcon(
2490
+ /* @__PURE__ */ jsxs(Fragment, { children: [
2491
+ /* @__PURE__ */ jsx("path", { d: "M7 5v14" }),
2492
+ /* @__PURE__ */ jsx("path", { d: "M19 6l-9 6l9 6z" })
2493
+ ] }),
2494
+ tablerIconProps
2495
+ );
2496
+ var nextFrame = createIcon(
2497
+ /* @__PURE__ */ jsxs(Fragment, { children: [
2498
+ /* @__PURE__ */ jsx("path", { d: "M17 5v14" }),
2499
+ /* @__PURE__ */ jsx("path", { d: "M5 6l9 6l-9 6z" })
2500
+ ] }),
2501
+ tablerIconProps
2502
+ );
2503
+ var frames = createIcon(
2504
+ /* @__PURE__ */ jsxs("g", { strokeWidth: 1.25, children: [
2505
+ /* @__PURE__ */ jsx("path", { stroke: "none", d: "M0 0h24v24H0z", fill: "none" }),
2506
+ /* @__PURE__ */ jsx("path", { d: "M4 6h16a1 1 0 0 1 1 1v10a1 1 0 0 1 -1 1h-16a1 1 0 0 1 -1 -1v-10a1 1 0 0 1 1 -1z" }),
2507
+ /* @__PURE__ */ jsx("path", { d: "M7 6v12" }),
2508
+ /* @__PURE__ */ jsx("path", { d: "M17 6v12" }),
2509
+ /* @__PURE__ */ jsx("path", { d: "M3 10h4" }),
2510
+ /* @__PURE__ */ jsx("path", { d: "M3 14h4" }),
2511
+ /* @__PURE__ */ jsx("path", { d: "M17 10h4" }),
2512
+ /* @__PURE__ */ jsx("path", { d: "M17 14h4" })
2513
+ ] }),
2514
+ tablerIconProps
2515
+ );
2485
2516
  var tablerCheckIcon = createIcon(
2486
2517
  /* @__PURE__ */ jsxs(Fragment, { children: [
2487
2518
  /* @__PURE__ */ jsx("path", { stroke: "none", d: "M0 0h24v24H0z", fill: "none" }),
@@ -10937,7 +10968,7 @@ var exportCanvas = async (type, elements, appState, files, {
10937
10968
  let blob = canvasToBlob(tempCanvas);
10938
10969
  if (appState.exportEmbedScene) {
10939
10970
  blob = blob.then(
10940
- (blob2) => import("./data/image-S7APFFV6.js").then(
10971
+ (blob2) => import("./data/image-42C5IMES.js").then(
10941
10972
  ({ encodePngMetadata: encodePngMetadata2 }) => encodePngMetadata2({
10942
10973
  blob: blob2,
10943
10974
  metadata: serializeAsJSON(elements, appState, files, "local")
@@ -15033,8 +15064,15 @@ import { invariant as invariant9 } from "@excalidraw/common";
15033
15064
  import { arrayToMap as arrayToMap23, findIndex, findLastIndex as findLastIndex2 } from "@excalidraw/common";
15034
15065
  import { isFiniteNumber } from "@excalidraw/math";
15035
15066
 
15067
+ // ../element/src/gif.ts
15068
+ import { decode, decodeFrames } from "modern-gif";
15069
+
15036
15070
  // ../element/src/image.ts
15037
- import { MIME_TYPES as MIME_TYPES4, SVG_NS } from "@excalidraw/common";
15071
+ import {
15072
+ DEFAULT_GIF_AUTO_DECODE_MAX_FILE_SIZE_BYTES,
15073
+ MIME_TYPES as MIME_TYPES4,
15074
+ SVG_NS
15075
+ } from "@excalidraw/common";
15038
15076
  import { rgbaToThumbHash, thumbHashToRGBA } from "thumbhash";
15039
15077
 
15040
15078
  // ../element/src/resizeElements.ts
@@ -24432,6 +24470,125 @@ var AppFlowchart = class _AppFlowchart {
24432
24470
  }
24433
24471
  };
24434
24472
 
24473
+ // components/App.gif.ts
24474
+ import {
24475
+ createGifPlaybackMetadata,
24476
+ hasPlayableGif,
24477
+ isInitializedImageElement as isInitializedImageElement3,
24478
+ newElementWith as newElementWith10,
24479
+ ShapeCache as ShapeCache4
24480
+ } from "@excalidraw/element";
24481
+ import { MIME_TYPES as MIME_TYPES8 } from "@excalidraw/common";
24482
+ var AppGifPlayback = class {
24483
+ constructor(app) {
24484
+ this.app = app;
24485
+ __publicField(this, "playbackRaf", null);
24486
+ __publicField(this, "runtimeState", /* @__PURE__ */ new Map());
24487
+ __publicField(this, "stop", () => {
24488
+ if (this.playbackRaf !== null) {
24489
+ cancelAnimationFrame(this.playbackRaf);
24490
+ this.playbackRaf = null;
24491
+ }
24492
+ this.runtimeState.clear();
24493
+ });
24494
+ __publicField(this, "getFrameIndex", (element) => element.gifPlayback?.playing ? this.runtimeState.get(element.id)?.frameIndex ?? element.gifPlayback.frameIndex : element.gifPlayback?.frameIndex);
24495
+ __publicField(this, "setFrameIndex", (element, frameIndex) => {
24496
+ this.runtimeState.set(element.id, {
24497
+ frameIndex,
24498
+ lastFrameTime: performance.now()
24499
+ });
24500
+ });
24501
+ __publicField(this, "ensureLoop", () => {
24502
+ if (this.playbackRaf !== null || this.app.unmounted) {
24503
+ return;
24504
+ }
24505
+ if (!hasPlayableGif(
24506
+ this.app.scene.getNonDeletedElements(),
24507
+ this.app.imageCache
24508
+ )) {
24509
+ return;
24510
+ }
24511
+ this.playbackRaf = requestAnimationFrame(this.tick);
24512
+ });
24513
+ __publicField(this, "createPlaceholderDecodeState", (placeholderImageElement, imageFile) => {
24514
+ if (imageFile.type !== MIME_TYPES8.gif) {
24515
+ return null;
24516
+ }
24517
+ const placeholderGifFileId = placeholderImageElement.id;
24518
+ this.app.imageCache.set(placeholderGifFileId, {
24519
+ image: new Promise(() => {
24520
+ }),
24521
+ mimeType: MIME_TYPES8.gif,
24522
+ gifDecodeStatus: "pending"
24523
+ });
24524
+ const gifPlaceholder = newElementWith10(placeholderImageElement, {
24525
+ fileId: placeholderGifFileId,
24526
+ gifPlayback: createGifPlaybackMetadata({ playing: true })
24527
+ });
24528
+ this.app.scene.replaceAllElements(
24529
+ this.app.scene.getElementsIncludingDeleted().map(
24530
+ (element) => element.id === gifPlaceholder.id ? gifPlaceholder : element
24531
+ )
24532
+ );
24533
+ this.app.imagePlaceholderUpdateEmitter.trigger();
24534
+ return placeholderGifFileId;
24535
+ });
24536
+ __publicField(this, "ensureElementPlaybackMetadata", (element, opts = {}) => {
24537
+ const shouldUseExisting = element.gifPlayback && (opts.playing === void 0 || element.gifPlayback.playing === opts.playing);
24538
+ return shouldUseExisting ? element : newElementWith10(element, {
24539
+ gifPlayback: element.gifPlayback ? {
24540
+ ...element.gifPlayback,
24541
+ playing: opts.playing ?? element.gifPlayback.playing
24542
+ } : createGifPlaybackMetadata(opts)
24543
+ });
24544
+ });
24545
+ __publicField(this, "removePlaceholderDecodeState", (placeholderGifFileId) => {
24546
+ if (placeholderGifFileId) {
24547
+ this.app.imageCache.delete(placeholderGifFileId);
24548
+ }
24549
+ });
24550
+ __publicField(this, "tick", () => {
24551
+ this.playbackRaf = null;
24552
+ if (this.app.unmounted) {
24553
+ return;
24554
+ }
24555
+ const now = performance.now();
24556
+ let didAdvanceFrame = false;
24557
+ let shouldContinue = false;
24558
+ for (const element of this.app.scene.getNonDeletedElements()) {
24559
+ if (!isInitializedImageElement3(element) || !element.gifPlayback?.playing) {
24560
+ continue;
24561
+ }
24562
+ const gif = this.app.imageCache.get(element.fileId)?.gif;
24563
+ if (!gif || gif.frames.length < 2) {
24564
+ continue;
24565
+ }
24566
+ shouldContinue = true;
24567
+ const speed = Math.max(element.gifPlayback.speed || 1, 0.1);
24568
+ const runtimeState = this.runtimeState.get(element.id) ?? {
24569
+ frameIndex: element.gifPlayback.frameIndex,
24570
+ lastFrameTime: now
24571
+ };
24572
+ this.runtimeState.set(element.id, runtimeState);
24573
+ const currentFrameIndex = runtimeState.frameIndex;
24574
+ const delay = gif.delays[currentFrameIndex] ?? 100;
24575
+ if (now - runtimeState.lastFrameTime >= delay / speed) {
24576
+ runtimeState.frameIndex = (currentFrameIndex + 1) % gif.frames.length;
24577
+ runtimeState.lastFrameTime = now;
24578
+ ShapeCache4.delete(element);
24579
+ didAdvanceFrame = true;
24580
+ }
24581
+ }
24582
+ if (didAdvanceFrame) {
24583
+ this.app.scene.triggerUpdate();
24584
+ }
24585
+ if (shouldContinue) {
24586
+ this.playbackRaf = requestAnimationFrame(this.tick);
24587
+ }
24588
+ });
24589
+ }
24590
+ };
24591
+
24435
24592
  // components/App.viewport.ts
24436
24593
  import {
24437
24594
  debounce as debounce2,
@@ -25411,17 +25568,16 @@ var ViewportStatusBadge = ({
25411
25568
  };
25412
25569
 
25413
25570
  // components/LayerUI.tsx
25414
- import clsx58 from "clsx";
25415
- import React37 from "react";
25571
+ import clsx59 from "clsx";
25572
+ import React38 from "react";
25416
25573
  import {
25417
25574
  CLASSES as CLASSES9,
25418
25575
  TOOL_TYPE as TOOL_TYPE2,
25419
25576
  arrayToMap as arrayToMap33,
25420
25577
  isShallowEqual as isShallowEqual6
25421
25578
  } from "@excalidraw/common";
25422
- import { mutateElement as mutateElement6 } from "@excalidraw/element";
25579
+ import { mutateElement as mutateElement6, ShapeCache as ShapeCache6 } from "@excalidraw/element";
25423
25580
  import { showSelectedShapeActions } from "@excalidraw/element";
25424
- import { ShapeCache as ShapeCache4 } from "@excalidraw/element";
25425
25581
 
25426
25582
  // context/tunnels.ts
25427
25583
  import { createIsolation as createIsolation2 } from "jotai-scope";
@@ -29733,7 +29889,7 @@ import { getBoundTextElement as getBoundTextElement14, handleBindTextResize as h
29733
29889
  import { isTextElement as isTextElement13 } from "@excalidraw/element";
29734
29890
 
29735
29891
  // ../utils/src/export.ts
29736
- import { MIME_TYPES as MIME_TYPES8 } from "@excalidraw/common";
29892
+ import { MIME_TYPES as MIME_TYPES9 } from "@excalidraw/common";
29737
29893
  import { getNonDeletedElements as getNonDeletedElements17 } from "@excalidraw/element";
29738
29894
  var exportToCanvas2 = ({
29739
29895
  elements,
@@ -29784,16 +29940,16 @@ var exportToCanvas2 = ({
29784
29940
  );
29785
29941
  };
29786
29942
  var exportToBlob = async (opts) => {
29787
- let { mimeType = MIME_TYPES8.png, quality } = opts;
29788
- if (mimeType === MIME_TYPES8.png && typeof quality === "number") {
29789
- console.warn(`"quality" will be ignored for "${MIME_TYPES8.png}" mimeType`);
29943
+ let { mimeType = MIME_TYPES9.png, quality } = opts;
29944
+ if (mimeType === MIME_TYPES9.png && typeof quality === "number") {
29945
+ console.warn(`"quality" will be ignored for "${MIME_TYPES9.png}" mimeType`);
29790
29946
  }
29791
29947
  if (mimeType === "image/jpg") {
29792
- mimeType = MIME_TYPES8.jpg;
29948
+ mimeType = MIME_TYPES9.jpg;
29793
29949
  }
29794
- if (mimeType === MIME_TYPES8.jpg && !opts.appState?.exportBackground) {
29950
+ if (mimeType === MIME_TYPES9.jpg && !opts.appState?.exportBackground) {
29795
29951
  console.warn(
29796
- `Defaulting "exportBackground" to "true" for "${MIME_TYPES8.jpg}" mimeType`
29952
+ `Defaulting "exportBackground" to "true" for "${MIME_TYPES9.jpg}" mimeType`
29797
29953
  );
29798
29954
  opts = {
29799
29955
  ...opts,
@@ -29808,7 +29964,7 @@ var exportToBlob = async (opts) => {
29808
29964
  if (!blob) {
29809
29965
  return reject(new Error("couldn't export to blob"));
29810
29966
  }
29811
- if (blob && mimeType === MIME_TYPES8.png && opts.appState?.exportEmbedScene) {
29967
+ if (blob && mimeType === MIME_TYPES9.png && opts.appState?.exportEmbedScene) {
29812
29968
  blob = await encodePngMetadata({
29813
29969
  blob,
29814
29970
  metadata: serializeAsJSON(
@@ -31301,9 +31457,544 @@ var ErrorDialog = ({
31301
31457
  ) });
31302
31458
  };
31303
31459
 
31304
- // components/HelpDialog.tsx
31305
- import React32, { useMemo as useMemo10 } from "react";
31460
+ // components/GifPlaybackControls.tsx
31306
31461
  import clsx48 from "clsx";
31462
+ import React32 from "react";
31463
+ import { MIME_TYPES as MIME_TYPES10, sceneCoordsToViewportCoords as sceneCoordsToViewportCoords4 } from "@excalidraw/common";
31464
+ import {
31465
+ getCommonBounds as getCommonBounds11,
31466
+ isInitializedImageElement as isInitializedImageElement4,
31467
+ ShapeCache as ShapeCache5
31468
+ } from "@excalidraw/element";
31469
+ import { Fragment as Fragment18, jsx as jsx112, jsxs as jsxs58 } from "react/jsx-runtime";
31470
+ var gifPlayIcon = /* @__PURE__ */ jsx112("svg", { viewBox: "0 0 24 24", "aria-hidden": "true", focusable: "false", children: /* @__PURE__ */ jsx112("path", { d: "M8 5v14l11 -7z" }) });
31471
+ var gifPauseIcon = /* @__PURE__ */ jsxs58("svg", { viewBox: "0 0 24 24", "aria-hidden": "true", focusable: "false", children: [
31472
+ /* @__PURE__ */ jsx112("path", { d: "M8 5v14" }),
31473
+ /* @__PURE__ */ jsx112("path", { d: "M16 5v14" })
31474
+ ] });
31475
+ var GIF_FRAME_GALLERY_ITEM_WIDTH = 76;
31476
+ var GIF_FRAME_GALLERY_ITEM_GAP = 4;
31477
+ var GIF_FRAME_GALLERY_ITEM_PITCH = GIF_FRAME_GALLERY_ITEM_WIDTH + GIF_FRAME_GALLERY_ITEM_GAP;
31478
+ var GIF_FRAME_GALLERY_OVERSCAN = 8;
31479
+ var GIF_POPUP_GAP = 8;
31480
+ var getClampedCenteredPopupLeft = (anchorCenterX, popupWidth) => {
31481
+ const halfPopupWidth = popupWidth / 2;
31482
+ return Math.min(
31483
+ Math.max(anchorCenterX, halfPopupWidth + GIF_POPUP_GAP),
31484
+ window.innerWidth - halfPopupWidth - GIF_POPUP_GAP
31485
+ );
31486
+ };
31487
+ var getGifControlPosition = (element, appState) => {
31488
+ const [, , x2, y2] = getCommonBounds11([element]);
31489
+ const bottomRight = sceneCoordsToViewportCoords4(
31490
+ { sceneX: x2, sceneY: y2 },
31491
+ appState
31492
+ );
31493
+ return {
31494
+ left: Math.min(
31495
+ Math.max(bottomRight.x - appState.offsetLeft, 8),
31496
+ appState.width - 8
31497
+ ),
31498
+ top: Math.min(
31499
+ Math.max(bottomRight.y - appState.offsetTop, 8),
31500
+ appState.height - 8
31501
+ )
31502
+ };
31503
+ };
31504
+ var GifPlaybackControls = ({
31505
+ app,
31506
+ files,
31507
+ setAppState
31508
+ }) => {
31509
+ const liveAppState = useExcalidrawAppState();
31510
+ const [, rerenderGifControls] = React32.useReducer(
31511
+ (version) => version + 1,
31512
+ 0
31513
+ );
31514
+ const [gifGalleryScrollLeft, setGifGalleryScrollLeft] = React32.useState(0);
31515
+ const [isGifGalleryDragging, setIsGifGalleryDragging] = React32.useState(false);
31516
+ const speedButtonRef = React32.useRef(null);
31517
+ const framesButtonRef = React32.useRef(null);
31518
+ const speedPickerRef = React32.useRef(null);
31519
+ const frameGalleryRef = React32.useRef(null);
31520
+ const frameGalleryDragRef = React32.useRef(null);
31521
+ const suppressNextFrameClickRef = React32.useRef(false);
31522
+ const [gifPopupPosition, setGifPopupPosition] = React32.useState(null);
31523
+ React32.useLayoutEffect(() => {
31524
+ const popup = liveAppState.openPopup;
31525
+ if (popup !== "gifSpeedPicker" && popup !== "gifFrameGallery") {
31526
+ if (gifPopupPosition !== null) {
31527
+ setGifPopupPosition(null);
31528
+ }
31529
+ return;
31530
+ }
31531
+ const anchor = popup === "gifSpeedPicker" ? speedButtonRef.current : framesButtonRef.current;
31532
+ const popupElement = popup === "gifSpeedPicker" ? speedPickerRef.current : frameGalleryRef.current;
31533
+ if (!anchor || !popupElement) {
31534
+ return;
31535
+ }
31536
+ const anchorRect = anchor.getBoundingClientRect();
31537
+ const popupRect = popupElement.getBoundingClientRect();
31538
+ const left = getClampedCenteredPopupLeft(
31539
+ anchorRect.left + anchorRect.width / 2,
31540
+ popupRect.width
31541
+ );
31542
+ const top = popup === "gifSpeedPicker" ? Math.max(
31543
+ GIF_POPUP_GAP,
31544
+ anchorRect.top - popupRect.height - GIF_POPUP_GAP
31545
+ ) : Math.min(
31546
+ window.innerHeight - popupRect.height - GIF_POPUP_GAP,
31547
+ anchorRect.bottom + GIF_POPUP_GAP
31548
+ );
31549
+ const nextPosition = {
31550
+ left,
31551
+ top: Math.max(GIF_POPUP_GAP, top)
31552
+ };
31553
+ setGifPopupPosition(
31554
+ (currentPosition) => currentPosition?.left === nextPosition.left && currentPosition.top === nextPosition.top ? currentPosition : nextPosition
31555
+ );
31556
+ }, [
31557
+ gifGalleryScrollLeft,
31558
+ gifPopupPosition,
31559
+ liveAppState.openPopup,
31560
+ liveAppState.scrollX,
31561
+ liveAppState.scrollY,
31562
+ liveAppState.zoom.value
31563
+ ]);
31564
+ const updateGifPlayback = (element, gifPlayback) => {
31565
+ ShapeCache5.delete(element);
31566
+ app.scene.mutateElement(element, {
31567
+ gifPlayback
31568
+ });
31569
+ app.scheduleUpdate();
31570
+ setAppState({});
31571
+ rerenderGifControls();
31572
+ if (gifPlayback.playing) {
31573
+ app.ensureGifPlaybackLoop();
31574
+ }
31575
+ };
31576
+ const deferredGifBadges = app.scene.getNonDeletedElements().filter(
31577
+ (element) => isInitializedImageElement4(element) && !liveAppState.selectedElementIds[element.id] && files[element.fileId]?.mimeType === MIME_TYPES10.gif && app.imageCache.get(element.fileId)?.gifDecodeStatus === "deferred"
31578
+ ).map((element) => {
31579
+ const position = getGifControlPosition(element, liveAppState);
31580
+ return /* @__PURE__ */ jsx112(
31581
+ "span",
31582
+ {
31583
+ className: "gif-playback-controls gif-playback-controls__deferred-badge",
31584
+ role: "img",
31585
+ "aria-label": "GIF paused",
31586
+ style: position,
31587
+ children: CirclePauseIcon
31588
+ },
31589
+ element.id
31590
+ );
31591
+ });
31592
+ const selectedElements = app.scene.getSelectedElements(liveAppState);
31593
+ const selectedElementControls = () => {
31594
+ if (selectedElements.length !== 1) {
31595
+ return null;
31596
+ }
31597
+ const selectedElement = selectedElements[0];
31598
+ if (!isInitializedImageElement4(selectedElement) || files[selectedElement.fileId]?.mimeType !== MIME_TYPES10.gif) {
31599
+ return null;
31600
+ }
31601
+ const cacheEntry = app.imageCache.get(selectedElement.fileId);
31602
+ const gif = cacheEntry?.gif;
31603
+ const [x1, , x2, y2] = getCommonBounds11([selectedElement]);
31604
+ const leftTop = sceneCoordsToViewportCoords4(
31605
+ { sceneX: x1, sceneY: y2 },
31606
+ liveAppState
31607
+ );
31608
+ const rightTop = sceneCoordsToViewportCoords4(
31609
+ { sceneX: x2, sceneY: y2 },
31610
+ liveAppState
31611
+ );
31612
+ const width = rightTop.x - leftTop.x;
31613
+ const left = leftTop.x - liveAppState.offsetLeft + width / 2;
31614
+ const top = Math.max(
31615
+ 12,
31616
+ Math.min(
31617
+ liveAppState.height - 86,
31618
+ leftTop.y - liveAppState.offsetTop + 16
31619
+ )
31620
+ );
31621
+ if (cacheEntry?.gifDecodeStatus === "deferred") {
31622
+ const position = getGifControlPosition(selectedElement, liveAppState);
31623
+ return /* @__PURE__ */ jsx112(
31624
+ "div",
31625
+ {
31626
+ className: "gif-playback-controls gif-playback-controls--deferred",
31627
+ style: position,
31628
+ onPointerDown: (event) => event.stopPropagation(),
31629
+ children: /* @__PURE__ */ jsx112(
31630
+ "button",
31631
+ {
31632
+ type: "button",
31633
+ className: "gif-playback-controls__load-large",
31634
+ title: "Load Large GIF",
31635
+ onClick: () => {
31636
+ app.loadDeferredGif(selectedElement.fileId);
31637
+ },
31638
+ children: "Load Large GIF"
31639
+ }
31640
+ )
31641
+ }
31642
+ );
31643
+ }
31644
+ if (cacheEntry?.gifDecodeStatus === "pending") {
31645
+ return null;
31646
+ }
31647
+ const frameCount = gif?.frames.length ?? 0;
31648
+ if (!gif || frameCount < 2) {
31649
+ return null;
31650
+ }
31651
+ const playback = selectedElement.gifPlayback ?? {
31652
+ frameIndex: 0,
31653
+ speed: 1,
31654
+ playing: false
31655
+ };
31656
+ const viewportAppState = app.state;
31657
+ const runtimeFrameIndex = app.getGifPlaybackFrameIndex(selectedElement) ?? playback.frameIndex;
31658
+ const frameIndex = Math.min(Math.max(runtimeFrameIndex, 0), frameCount - 1);
31659
+ const galleryTop = Math.min(viewportAppState.height - 120, top + 48);
31660
+ const speedPickerTop = Math.max(12, top - 52);
31661
+ const commitFrame = (nextFrameIndex) => {
31662
+ const normalizedFrameIndex = (nextFrameIndex + frameCount) % frameCount;
31663
+ app.setGifPlaybackFrameIndex(selectedElement, normalizedFrameIndex);
31664
+ updateGifPlayback(selectedElement, {
31665
+ ...playback,
31666
+ frameIndex: normalizedFrameIndex,
31667
+ playing: false
31668
+ });
31669
+ };
31670
+ const wheelFrame = (event) => {
31671
+ event.stopPropagation();
31672
+ commitFrame(frameIndex + (event.deltaY < 0 ? 1 : -1));
31673
+ };
31674
+ const setPlaying = (playing) => {
31675
+ app.setGifPlaybackFrameIndex(selectedElement, frameIndex);
31676
+ updateGifPlayback(selectedElement, {
31677
+ ...playback,
31678
+ frameIndex,
31679
+ playing
31680
+ });
31681
+ };
31682
+ const speeds = [0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2, 4];
31683
+ const getSpeedIndex = (speed) => {
31684
+ const exactIndex = speeds.indexOf(speed);
31685
+ if (exactIndex !== -1) {
31686
+ return exactIndex;
31687
+ }
31688
+ return speeds.reduce(
31689
+ (nearestIndex, candidate, index) => Math.abs(candidate - speed) < Math.abs(speeds[nearestIndex] - speed) ? index : nearestIndex,
31690
+ 0
31691
+ );
31692
+ };
31693
+ const setSpeed = (speed) => {
31694
+ updateGifPlayback(selectedElement, {
31695
+ ...playback,
31696
+ speed
31697
+ });
31698
+ };
31699
+ const stepSpeed = (direction) => {
31700
+ const currentIndex = getSpeedIndex(playback.speed);
31701
+ setSpeed(
31702
+ speeds[Math.min(Math.max(currentIndex + direction, 0), speeds.length - 1)]
31703
+ );
31704
+ };
31705
+ const speedLabel = Number.isInteger(playback.speed) ? `${playback.speed}` : `${playback.speed}`;
31706
+ const galleryScrollWidth = frameCount * GIF_FRAME_GALLERY_ITEM_PITCH - GIF_FRAME_GALLERY_ITEM_GAP;
31707
+ const galleryViewportWidth = Math.min(
31708
+ Math.max(viewportAppState.width * 0.9, 1),
31709
+ galleryScrollWidth
31710
+ );
31711
+ const galleryMaxScrollLeft = Math.max(
31712
+ galleryScrollWidth - galleryViewportWidth,
31713
+ 0
31714
+ );
31715
+ const clampedGifGalleryScrollLeft = Math.min(
31716
+ gifGalleryScrollLeft,
31717
+ galleryMaxScrollLeft
31718
+ );
31719
+ const firstVisibleFrameIndex = Math.max(
31720
+ Math.floor(clampedGifGalleryScrollLeft / GIF_FRAME_GALLERY_ITEM_PITCH) - GIF_FRAME_GALLERY_OVERSCAN,
31721
+ 0
31722
+ );
31723
+ const visibleFrameCount = Math.ceil(galleryViewportWidth / GIF_FRAME_GALLERY_ITEM_PITCH) + GIF_FRAME_GALLERY_OVERSCAN * 2;
31724
+ const lastVisibleFrameIndex = Math.min(
31725
+ firstVisibleFrameIndex + visibleFrameCount,
31726
+ frameCount
31727
+ );
31728
+ const visibleFrames = gif.frames.slice(
31729
+ firstVisibleFrameIndex,
31730
+ lastVisibleFrameIndex
31731
+ );
31732
+ const beginGalleryDrag = (event) => {
31733
+ if (event.pointerType !== "mouse" || event.button !== 0) {
31734
+ return;
31735
+ }
31736
+ frameGalleryDragRef.current = {
31737
+ pointerId: event.pointerId,
31738
+ startClientX: event.clientX,
31739
+ startScrollLeft: event.currentTarget.scrollLeft,
31740
+ didDrag: false
31741
+ };
31742
+ event.stopPropagation();
31743
+ };
31744
+ const updateGalleryDrag = (event) => {
31745
+ const dragState = frameGalleryDragRef.current;
31746
+ if (!dragState || dragState.pointerId !== event.pointerId) {
31747
+ return;
31748
+ }
31749
+ const deltaX = event.clientX - dragState.startClientX;
31750
+ if (!dragState.didDrag && Math.abs(deltaX) <= 3) {
31751
+ return;
31752
+ }
31753
+ if (!dragState.didDrag) {
31754
+ dragState.didDrag = true;
31755
+ event.currentTarget.setPointerCapture?.(event.pointerId);
31756
+ setIsGifGalleryDragging(true);
31757
+ }
31758
+ event.currentTarget.scrollLeft = dragState.startScrollLeft - deltaX;
31759
+ setGifGalleryScrollLeft(event.currentTarget.scrollLeft);
31760
+ event.preventDefault();
31761
+ event.stopPropagation();
31762
+ };
31763
+ const endGalleryDrag = (event) => {
31764
+ const dragState = frameGalleryDragRef.current;
31765
+ if (!dragState || dragState.pointerId !== event.pointerId) {
31766
+ return;
31767
+ }
31768
+ suppressNextFrameClickRef.current = dragState.didDrag;
31769
+ frameGalleryDragRef.current = null;
31770
+ if (event.currentTarget.hasPointerCapture?.(event.pointerId)) {
31771
+ event.currentTarget.releasePointerCapture(event.pointerId);
31772
+ }
31773
+ setIsGifGalleryDragging(false);
31774
+ event.stopPropagation();
31775
+ };
31776
+ const cancelGalleryDrag = (event) => {
31777
+ const dragState = frameGalleryDragRef.current;
31778
+ if (!dragState || dragState.pointerId !== event.pointerId) {
31779
+ return;
31780
+ }
31781
+ frameGalleryDragRef.current = null;
31782
+ setIsGifGalleryDragging(false);
31783
+ event.stopPropagation();
31784
+ };
31785
+ const stopGalleryTouchPropagation = (event) => {
31786
+ if (event.pointerType !== "mouse") {
31787
+ event.stopPropagation();
31788
+ }
31789
+ };
31790
+ return /* @__PURE__ */ jsxs58(
31791
+ "div",
31792
+ {
31793
+ className: "gif-playback-controls",
31794
+ style: { left, top },
31795
+ onPointerDown: (event) => event.stopPropagation(),
31796
+ children: [
31797
+ liveAppState.openPopup === "gifSpeedPicker" && /* @__PURE__ */ jsx112(
31798
+ "div",
31799
+ {
31800
+ className: "gif-speed-picker",
31801
+ ref: speedPickerRef,
31802
+ style: gifPopupPosition ?? { left, top: speedPickerTop },
31803
+ children: speeds.map((speed) => {
31804
+ const label = Number.isInteger(speed) ? `${speed}` : `${speed}`;
31805
+ return /* @__PURE__ */ jsxs58(
31806
+ "button",
31807
+ {
31808
+ type: "button",
31809
+ className: clsx48("gif-speed-picker__speed", {
31810
+ "gif-speed-picker__speed--selected": speed === playback.speed
31811
+ }),
31812
+ onClick: () => setSpeed(speed),
31813
+ title: `${label}x`,
31814
+ children: [
31815
+ "x",
31816
+ label
31817
+ ]
31818
+ },
31819
+ speed
31820
+ );
31821
+ })
31822
+ }
31823
+ ),
31824
+ /* @__PURE__ */ jsxs58("div", { className: "gif-playback-controls__bar", children: [
31825
+ /* @__PURE__ */ jsxs58(
31826
+ "button",
31827
+ {
31828
+ type: "button",
31829
+ className: "gif-playback-controls__button gif-playback-controls__button--speed",
31830
+ ref: speedButtonRef,
31831
+ onClick: () => setAppState({
31832
+ openPopup: liveAppState.openPopup === "gifSpeedPicker" ? null : "gifSpeedPicker"
31833
+ }),
31834
+ onWheel: (event) => {
31835
+ event.stopPropagation();
31836
+ stepSpeed(event.deltaY < 0 ? 1 : -1);
31837
+ },
31838
+ title: "Speed",
31839
+ children: [
31840
+ "x",
31841
+ speedLabel
31842
+ ]
31843
+ }
31844
+ ),
31845
+ /* @__PURE__ */ jsx112(
31846
+ "button",
31847
+ {
31848
+ type: "button",
31849
+ className: "gif-playback-controls__button",
31850
+ onClick: () => commitFrame(frameIndex - 1),
31851
+ onWheel: wheelFrame,
31852
+ title: "Previous frame",
31853
+ children: prevFrame
31854
+ }
31855
+ ),
31856
+ /* @__PURE__ */ jsx112(
31857
+ "button",
31858
+ {
31859
+ type: "button",
31860
+ className: "gif-playback-controls__button",
31861
+ onClick: () => setPlaying(!playback.playing),
31862
+ onWheel: wheelFrame,
31863
+ title: playback.playing ? "Pause" : "Play",
31864
+ children: playback.playing ? gifPauseIcon : gifPlayIcon
31865
+ }
31866
+ ),
31867
+ /* @__PURE__ */ jsx112(
31868
+ "button",
31869
+ {
31870
+ type: "button",
31871
+ className: "gif-playback-controls__button",
31872
+ onClick: () => commitFrame(frameIndex + 1),
31873
+ onWheel: wheelFrame,
31874
+ title: "Next frame",
31875
+ children: nextFrame
31876
+ }
31877
+ ),
31878
+ /* @__PURE__ */ jsx112(
31879
+ "button",
31880
+ {
31881
+ type: "button",
31882
+ className: "gif-playback-controls__button gif-playback-controls__button--frames",
31883
+ ref: framesButtonRef,
31884
+ onClick: () => {
31885
+ if (liveAppState.openPopup !== "gifFrameGallery") {
31886
+ setGifGalleryScrollLeft(
31887
+ Math.max(
31888
+ frameIndex * GIF_FRAME_GALLERY_ITEM_PITCH - galleryViewportWidth / 2,
31889
+ 0
31890
+ )
31891
+ );
31892
+ }
31893
+ setAppState({
31894
+ openPopup: liveAppState.openPopup === "gifFrameGallery" ? null : "gifFrameGallery"
31895
+ });
31896
+ },
31897
+ onWheel: wheelFrame,
31898
+ title: "Frames",
31899
+ children: frames
31900
+ }
31901
+ )
31902
+ ] }),
31903
+ liveAppState.openPopup === "gifFrameGallery" && /* @__PURE__ */ jsx112(
31904
+ "div",
31905
+ {
31906
+ className: clsx48("gif-frame-gallery", {
31907
+ "gif-frame-gallery--dragging": isGifGalleryDragging
31908
+ }),
31909
+ style: {
31910
+ ...gifPopupPosition ?? { left, top: galleryTop },
31911
+ width: galleryViewportWidth
31912
+ },
31913
+ ref: (node) => {
31914
+ frameGalleryRef.current = node;
31915
+ if (node && node.scrollLeft !== clampedGifGalleryScrollLeft) {
31916
+ node.scrollLeft = clampedGifGalleryScrollLeft;
31917
+ }
31918
+ },
31919
+ onScroll: (event) => {
31920
+ setGifGalleryScrollLeft(event.currentTarget.scrollLeft);
31921
+ },
31922
+ onPointerDownCapture: stopGalleryTouchPropagation,
31923
+ onPointerMoveCapture: stopGalleryTouchPropagation,
31924
+ onPointerUpCapture: stopGalleryTouchPropagation,
31925
+ onPointerCancelCapture: stopGalleryTouchPropagation,
31926
+ onPointerDown: beginGalleryDrag,
31927
+ onPointerMove: updateGalleryDrag,
31928
+ onPointerUp: endGalleryDrag,
31929
+ onPointerCancel: cancelGalleryDrag,
31930
+ onLostPointerCapture: cancelGalleryDrag,
31931
+ onClickCapture: (event) => {
31932
+ if (suppressNextFrameClickRef.current) {
31933
+ suppressNextFrameClickRef.current = false;
31934
+ event.preventDefault();
31935
+ event.stopPropagation();
31936
+ return;
31937
+ }
31938
+ suppressNextFrameClickRef.current = false;
31939
+ },
31940
+ onWheelCapture: (event) => {
31941
+ event.stopPropagation();
31942
+ event.currentTarget.scrollLeft += event.deltaY;
31943
+ setGifGalleryScrollLeft(event.currentTarget.scrollLeft);
31944
+ },
31945
+ children: /* @__PURE__ */ jsx112(
31946
+ "div",
31947
+ {
31948
+ className: "gif-frame-gallery__spacer",
31949
+ style: { width: galleryScrollWidth },
31950
+ children: visibleFrames.map((frame, offset) => {
31951
+ const index = firstVisibleFrameIndex + offset;
31952
+ return /* @__PURE__ */ jsxs58(
31953
+ "button",
31954
+ {
31955
+ type: "button",
31956
+ className: clsx48("gif-frame-gallery__frame", {
31957
+ "gif-frame-gallery__frame--selected": index === frameIndex
31958
+ }),
31959
+ style: {
31960
+ left: index * GIF_FRAME_GALLERY_ITEM_PITCH
31961
+ },
31962
+ onClick: () => commitFrame(index),
31963
+ title: `Frame ${index + 1}`,
31964
+ children: [
31965
+ /* @__PURE__ */ jsx112(
31966
+ "canvas",
31967
+ {
31968
+ width: frame.width,
31969
+ height: frame.height,
31970
+ ref: (node) => {
31971
+ node?.getContext("2d")?.drawImage(frame, 0, 0);
31972
+ }
31973
+ }
31974
+ ),
31975
+ /* @__PURE__ */ jsx112("span", { children: index + 1 })
31976
+ ]
31977
+ },
31978
+ index
31979
+ );
31980
+ })
31981
+ }
31982
+ )
31983
+ }
31984
+ )
31985
+ ]
31986
+ }
31987
+ );
31988
+ };
31989
+ return /* @__PURE__ */ jsxs58(Fragment18, { children: [
31990
+ deferredGifBadges,
31991
+ selectedElementControls()
31992
+ ] });
31993
+ };
31994
+
31995
+ // components/HelpDialog.tsx
31996
+ import React33, { useMemo as useMemo10 } from "react";
31997
+ import clsx49 from "clsx";
31307
31998
  import { isDarwin as isDarwin4, isFirefox as isFirefox4, isWindows } from "@excalidraw/common";
31308
31999
  import { KEYS as KEYS48 } from "@excalidraw/common";
31309
32000
  import { SHAPES as SHAPES3 } from "@excalidraw/element/shapes";
@@ -31311,14 +32002,14 @@ import { SHAPES as SHAPES3 } from "@excalidraw/element/shapes";
31311
32002
  // components/HelpDialog/BasicHelpDialog.tsx
31312
32003
  import { isFirefox as isFirefox3, KEYS as KEYS47 } from "@excalidraw/common";
31313
32004
  import { SHAPES as SHAPES2 } from "@excalidraw/element/shapes";
31314
- import { Fragment as Fragment18, jsx as jsx112, jsxs as jsxs58 } from "react/jsx-runtime";
31315
- var Section2 = (props) => /* @__PURE__ */ jsxs58(Fragment18, { children: [
31316
- /* @__PURE__ */ jsx112("h3", { children: props.title }),
31317
- /* @__PURE__ */ jsx112("div", { className: "HelpDialog__islands-container", children: props.children })
32005
+ import { Fragment as Fragment19, jsx as jsx113, jsxs as jsxs59 } from "react/jsx-runtime";
32006
+ var Section2 = (props) => /* @__PURE__ */ jsxs59(Fragment19, { children: [
32007
+ /* @__PURE__ */ jsx113("h3", { children: props.title }),
32008
+ /* @__PURE__ */ jsx113("div", { className: "HelpDialog__islands-container", children: props.children })
31318
32009
  ] });
31319
- var ShortcutIsland = (props) => /* @__PURE__ */ jsxs58("div", { className: `HelpDialog__island ${props.className}`, children: [
31320
- /* @__PURE__ */ jsx112("h4", { className: "HelpDialog__island-title", children: props.caption }),
31321
- /* @__PURE__ */ jsx112("div", { className: "HelpDialog__island-content", children: props.children })
32010
+ var ShortcutIsland = (props) => /* @__PURE__ */ jsxs59("div", { className: `HelpDialog__island ${props.className}`, children: [
32011
+ /* @__PURE__ */ jsx113("h4", { className: "HelpDialog__island-title", children: props.caption }),
32012
+ /* @__PURE__ */ jsx113("div", { className: "HelpDialog__island-content", children: props.children })
31322
32013
  ] });
31323
32014
  function* intersperse(as, delim) {
31324
32015
  let first = true;
@@ -31340,25 +32031,25 @@ var Shortcut = ({
31340
32031
  }) => {
31341
32032
  const splitShortcutKeys = shortcuts.map((shortcut) => {
31342
32033
  const keys = shortcut.endsWith("++") ? [...shortcut.slice(0, -2).split("+"), "+"] : shortcut.split("+");
31343
- return keys.map((key) => /* @__PURE__ */ jsx112(ShortcutKey, { children: upperCaseSingleChars(key) }, key));
32034
+ return keys.map((key) => /* @__PURE__ */ jsx113(ShortcutKey, { children: upperCaseSingleChars(key) }, key));
31344
32035
  });
31345
- return /* @__PURE__ */ jsxs58("div", { className: "HelpDialog__shortcut", children: [
31346
- /* @__PURE__ */ jsx112("div", { children: label }),
31347
- /* @__PURE__ */ jsx112("div", { className: "HelpDialog__key-container", children: [...intersperse(splitShortcutKeys, isOr ? t("helpDialog.or") : null)] })
32036
+ return /* @__PURE__ */ jsxs59("div", { className: "HelpDialog__shortcut", children: [
32037
+ /* @__PURE__ */ jsx113("div", { children: label }),
32038
+ /* @__PURE__ */ jsx113("div", { className: "HelpDialog__key-container", children: [...intersperse(splitShortcutKeys, isOr ? t("helpDialog.or") : null)] })
31348
32039
  ] });
31349
32040
  };
31350
- var ShortcutKey = (props) => /* @__PURE__ */ jsx112("kbd", { className: "HelpDialog__key", ...props });
32041
+ var ShortcutKey = (props) => /* @__PURE__ */ jsx113("kbd", { className: "HelpDialog__key", ...props });
31351
32042
  function BasicHelpDialog() {
31352
- return /* @__PURE__ */ jsxs58(Section2, { title: t("helpDialog.shortcuts"), children: [
31353
- /* @__PURE__ */ jsxs58(
32043
+ return /* @__PURE__ */ jsxs59(Section2, { title: t("helpDialog.shortcuts"), children: [
32044
+ /* @__PURE__ */ jsxs59(
31354
32045
  ShortcutIsland,
31355
32046
  {
31356
32047
  className: "HelpDialog__island--tools",
31357
32048
  caption: t("helpDialog.tools"),
31358
32049
  children: [
31359
- /* @__PURE__ */ jsx112(Shortcut, { label: t("toolBar.hand"), shortcuts: [KEYS47.H] }),
32050
+ /* @__PURE__ */ jsx113(Shortcut, { label: t("toolBar.hand"), shortcuts: [KEYS47.H] }),
31360
32051
  SHAPES2.filter(({ myocSimplifiedMode }) => myocSimplifiedMode).map(
31361
- ({ value, key }) => /* @__PURE__ */ jsx112(
32052
+ ({ value, key }) => /* @__PURE__ */ jsx113(
31362
32053
  Shortcut,
31363
32054
  {
31364
32055
  label: t(`toolBar.${value}`),
@@ -31367,7 +32058,7 @@ function BasicHelpDialog() {
31367
32058
  value
31368
32059
  )
31369
32060
  ),
31370
- /* @__PURE__ */ jsx112(
32061
+ /* @__PURE__ */ jsx113(
31371
32062
  Shortcut,
31372
32063
  {
31373
32064
  label: t("helpDialog.cropStart"),
@@ -31375,7 +32066,7 @@ function BasicHelpDialog() {
31375
32066
  isOr: true
31376
32067
  }
31377
32068
  ),
31378
- /* @__PURE__ */ jsx112(
32069
+ /* @__PURE__ */ jsx113(
31379
32070
  Shortcut,
31380
32071
  {
31381
32072
  label: t("helpDialog.cropFinish"),
@@ -31386,21 +32077,21 @@ function BasicHelpDialog() {
31386
32077
  ]
31387
32078
  }
31388
32079
  ),
31389
- /* @__PURE__ */ jsxs58(
32080
+ /* @__PURE__ */ jsxs59(
31390
32081
  ShortcutIsland,
31391
32082
  {
31392
32083
  className: "HelpDialog__island--view",
31393
32084
  caption: t("helpDialog.view"),
31394
32085
  children: [
31395
- /* @__PURE__ */ jsx112(Shortcut, { label: t("helpDialog.smartZoom"), shortcuts: [KEYS47.F] }),
31396
- /* @__PURE__ */ jsx112(
32086
+ /* @__PURE__ */ jsx113(Shortcut, { label: t("helpDialog.smartZoom"), shortcuts: [KEYS47.F] }),
32087
+ /* @__PURE__ */ jsx113(
31397
32088
  Shortcut,
31398
32089
  {
31399
32090
  label: t("helpDialog.dragToZoom"),
31400
32091
  shortcuts: [`${KEYS47.Z}+${t("helpDialog.drag")}`]
31401
32092
  }
31402
32093
  ),
31403
- /* @__PURE__ */ jsx112(
32094
+ /* @__PURE__ */ jsx113(
31404
32095
  Shortcut,
31405
32096
  {
31406
32097
  label: t("buttons.objectsSnapMode"),
@@ -31410,76 +32101,76 @@ function BasicHelpDialog() {
31410
32101
  ]
31411
32102
  }
31412
32103
  ),
31413
- /* @__PURE__ */ jsxs58(
32104
+ /* @__PURE__ */ jsxs59(
31414
32105
  ShortcutIsland,
31415
32106
  {
31416
32107
  className: "HelpDialog__island--editor",
31417
32108
  caption: t("helpDialog.editor"),
31418
32109
  children: [
31419
- /* @__PURE__ */ jsx112(
32110
+ /* @__PURE__ */ jsx113(
31420
32111
  Shortcut,
31421
32112
  {
31422
32113
  label: t("labels.pasteAsPlaintext"),
31423
32114
  shortcuts: [getShortcutKey("CtrlOrCmd+Shift+V")]
31424
32115
  }
31425
32116
  ),
31426
- /* @__PURE__ */ jsx112(
32117
+ /* @__PURE__ */ jsx113(
31427
32118
  Shortcut,
31428
32119
  {
31429
32120
  label: t("labels.multiSelect"),
31430
32121
  shortcuts: [getShortcutKey(`Shift+${t("helpDialog.click")}`)]
31431
32122
  }
31432
32123
  ),
31433
- /* @__PURE__ */ jsx112(
32124
+ /* @__PURE__ */ jsx113(
31434
32125
  Shortcut,
31435
32126
  {
31436
32127
  label: t("helpDialog.deepSelect"),
31437
32128
  shortcuts: [getShortcutKey(`CtrlOrCmd+${t("helpDialog.click")}`)]
31438
32129
  }
31439
32130
  ),
31440
- /* @__PURE__ */ jsx112(
32131
+ /* @__PURE__ */ jsx113(
31441
32132
  Shortcut,
31442
32133
  {
31443
32134
  label: t("helpDialog.deepBoxSelect"),
31444
32135
  shortcuts: [getShortcutKey(`CtrlOrCmd+${t("helpDialog.drag")}`)]
31445
32136
  }
31446
32137
  ),
31447
- (probablySupportsClipboardBlob || isFirefox3) && /* @__PURE__ */ jsx112(
32138
+ (probablySupportsClipboardBlob || isFirefox3) && /* @__PURE__ */ jsx113(
31448
32139
  Shortcut,
31449
32140
  {
31450
32141
  label: t("labels.copyAsPng"),
31451
32142
  shortcuts: [getShortcutKey("Shift+Alt+C")]
31452
32143
  }
31453
32144
  ),
31454
- /* @__PURE__ */ jsx112(
32145
+ /* @__PURE__ */ jsx113(
31455
32146
  Shortcut,
31456
32147
  {
31457
32148
  label: t("helpDialog.toggleElementLock"),
31458
32149
  shortcuts: [getShortcutKey("CtrlOrCmd+Shift+L")]
31459
32150
  }
31460
32151
  ),
31461
- /* @__PURE__ */ jsx112(
32152
+ /* @__PURE__ */ jsx113(
31462
32153
  Shortcut,
31463
32154
  {
31464
32155
  label: t("labels.group"),
31465
32156
  shortcuts: [getShortcutKey("CtrlOrCmd+G")]
31466
32157
  }
31467
32158
  ),
31468
- /* @__PURE__ */ jsx112(
32159
+ /* @__PURE__ */ jsx113(
31469
32160
  Shortcut,
31470
32161
  {
31471
32162
  label: t("labels.ungroup"),
31472
32163
  shortcuts: [getShortcutKey("CtrlOrCmd+Shift+G")]
31473
32164
  }
31474
32165
  ),
31475
- /* @__PURE__ */ jsx112(
32166
+ /* @__PURE__ */ jsx113(
31476
32167
  Shortcut,
31477
32168
  {
31478
32169
  label: t("labels.flipHorizontal"),
31479
32170
  shortcuts: [getShortcutKey("Shift+H")]
31480
32171
  }
31481
32172
  ),
31482
- /* @__PURE__ */ jsx112(
32173
+ /* @__PURE__ */ jsx113(
31483
32174
  Shortcut,
31484
32175
  {
31485
32176
  label: t("labels.flipVertical"),
@@ -31493,14 +32184,14 @@ function BasicHelpDialog() {
31493
32184
  }
31494
32185
 
31495
32186
  // components/HelpDialog.tsx
31496
- import { Fragment as Fragment19, jsx as jsx113, jsxs as jsxs59 } from "react/jsx-runtime";
31497
- var Section3 = (props) => /* @__PURE__ */ jsxs59(Fragment19, { children: [
31498
- /* @__PURE__ */ jsx113("h3", { children: props.title }),
31499
- /* @__PURE__ */ jsx113("div", { className: "HelpDialog__islands-container", children: props.children })
32187
+ import { Fragment as Fragment20, jsx as jsx114, jsxs as jsxs60 } from "react/jsx-runtime";
32188
+ var Section3 = (props) => /* @__PURE__ */ jsxs60(Fragment20, { children: [
32189
+ /* @__PURE__ */ jsx114("h3", { children: props.title }),
32190
+ /* @__PURE__ */ jsx114("div", { className: "HelpDialog__islands-container", children: props.children })
31500
32191
  ] });
31501
- var ShortcutIsland2 = (props) => /* @__PURE__ */ jsxs59("div", { className: `HelpDialog__island ${props.className}`, children: [
31502
- /* @__PURE__ */ jsx113("h4", { className: "HelpDialog__island-title", children: props.caption }),
31503
- /* @__PURE__ */ jsx113("div", { className: "HelpDialog__island-content", children: props.children })
32192
+ var ShortcutIsland2 = (props) => /* @__PURE__ */ jsxs60("div", { className: `HelpDialog__island ${props.className}`, children: [
32193
+ /* @__PURE__ */ jsx114("h4", { className: "HelpDialog__island-title", children: props.caption }),
32194
+ /* @__PURE__ */ jsx114("div", { className: "HelpDialog__island-content", children: props.children })
31504
32195
  ] });
31505
32196
  function* intersperse2(as, delim) {
31506
32197
  let first = true;
@@ -31522,40 +32213,40 @@ var Shortcut2 = ({
31522
32213
  }) => {
31523
32214
  const splitShortcutKeys = shortcuts.map((shortcut) => {
31524
32215
  const keys = shortcut.endsWith("++") ? [...shortcut.slice(0, -2).split("+"), "+"] : shortcut.split("+");
31525
- return keys.map((key) => /* @__PURE__ */ jsx113(ShortcutKey2, { children: upperCaseSingleChars2(key) }, key));
32216
+ return keys.map((key) => /* @__PURE__ */ jsx114(ShortcutKey2, { children: upperCaseSingleChars2(key) }, key));
31526
32217
  });
31527
- return /* @__PURE__ */ jsxs59("div", { className: "HelpDialog__shortcut", children: [
31528
- /* @__PURE__ */ jsx113("div", { children: label }),
31529
- /* @__PURE__ */ jsx113("div", { className: "HelpDialog__key-container", children: [...intersperse2(splitShortcutKeys, isOr ? t("helpDialog.or") : null)] })
32218
+ return /* @__PURE__ */ jsxs60("div", { className: "HelpDialog__shortcut", children: [
32219
+ /* @__PURE__ */ jsx114("div", { children: label }),
32220
+ /* @__PURE__ */ jsx114("div", { className: "HelpDialog__key-container", children: [...intersperse2(splitShortcutKeys, isOr ? t("helpDialog.or") : null)] })
31530
32221
  ] });
31531
32222
  };
31532
- var ShortcutKey2 = (props) => /* @__PURE__ */ jsx113("kbd", { className: "HelpDialog__key", ...props });
32223
+ var ShortcutKey2 = (props) => /* @__PURE__ */ jsx114("kbd", { className: "HelpDialog__key", ...props });
31533
32224
  var HelpDialog = ({ onClose }) => {
31534
- const [isShowAll, setIsShowAll] = React32.useState(false);
31535
- const handleClose = React32.useCallback(() => {
32225
+ const [isShowAll, setIsShowAll] = React33.useState(false);
32226
+ const handleClose = React33.useCallback(() => {
31536
32227
  if (onClose) {
31537
32228
  onClose();
31538
32229
  }
31539
32230
  }, [onClose]);
31540
32231
  const showAllButton = useMemo10(
31541
- () => isShowAll ? /* @__PURE__ */ jsx113(
32232
+ () => isShowAll ? /* @__PURE__ */ jsx114(
31542
32233
  "button",
31543
32234
  {
31544
- className: clsx48("toggle-button", {}),
32235
+ className: clsx49("toggle-button", {}),
31545
32236
  onClick: () => setIsShowAll(false),
31546
32237
  children: t("helpDialog.myoc.showingAll")
31547
32238
  }
31548
- ) : /* @__PURE__ */ jsx113(
32239
+ ) : /* @__PURE__ */ jsx114(
31549
32240
  "button",
31550
32241
  {
31551
- className: clsx48("toggle-button", {}),
32242
+ className: clsx49("toggle-button", {}),
31552
32243
  onClick: () => setIsShowAll(true),
31553
32244
  children: t("helpDialog.myoc.showingBasic")
31554
32245
  }
31555
32246
  ),
31556
32247
  [isShowAll]
31557
32248
  );
31558
- return /* @__PURE__ */ jsx113(Fragment19, { children: /* @__PURE__ */ jsx113(
32249
+ return /* @__PURE__ */ jsx114(Fragment20, { children: /* @__PURE__ */ jsx114(
31559
32250
  Dialog,
31560
32251
  {
31561
32252
  onCloseRequest: handleClose,
@@ -31563,15 +32254,15 @@ var HelpDialog = ({ onClose }) => {
31563
32254
  className: "HelpDialog",
31564
32255
  titleButton: showAllButton,
31565
32256
  portalContainerClassName: "HelpDialog__modalContainer",
31566
- children: isShowAll ? /* @__PURE__ */ jsxs59(Section3, { title: t("helpDialog.shortcuts"), children: [
31567
- /* @__PURE__ */ jsxs59(
32257
+ children: isShowAll ? /* @__PURE__ */ jsxs60(Section3, { title: t("helpDialog.shortcuts"), children: [
32258
+ /* @__PURE__ */ jsxs60(
31568
32259
  ShortcutIsland2,
31569
32260
  {
31570
32261
  className: "HelpDialog__island--tools",
31571
32262
  caption: t("helpDialog.tools"),
31572
32263
  children: [
31573
- /* @__PURE__ */ jsx113(Shortcut2, { label: t("toolBar.hand"), shortcuts: [KEYS48.H] }),
31574
- SHAPES3.map(({ value, key }) => /* @__PURE__ */ jsx113(
32264
+ /* @__PURE__ */ jsx114(Shortcut2, { label: t("toolBar.hand"), shortcuts: [KEYS48.H] }),
32265
+ SHAPES3.map(({ value, key }) => /* @__PURE__ */ jsx114(
31575
32266
  Shortcut2,
31576
32267
  {
31577
32268
  label: t(`toolBar.${value}`),
@@ -31579,29 +32270,29 @@ var HelpDialog = ({ onClose }) => {
31579
32270
  },
31580
32271
  value
31581
32272
  )),
31582
- /* @__PURE__ */ jsx113(Shortcut2, { label: t("toolBar.frame"), shortcuts: [KEYS48.F] }),
31583
- /* @__PURE__ */ jsx113(
32273
+ /* @__PURE__ */ jsx114(Shortcut2, { label: t("toolBar.frame"), shortcuts: [KEYS48.F] }),
32274
+ /* @__PURE__ */ jsx114(
31584
32275
  Shortcut2,
31585
32276
  {
31586
32277
  label: t("labels.eyeDropper"),
31587
32278
  shortcuts: [KEYS48.I, "Shift+S", "Shift+I"]
31588
32279
  }
31589
32280
  ),
31590
- /* @__PURE__ */ jsx113(
32281
+ /* @__PURE__ */ jsx114(
31591
32282
  Shortcut2,
31592
32283
  {
31593
32284
  label: t("helpDialog.editLineArrowPoints"),
31594
32285
  shortcuts: [getShortcutKey("CtrlOrCmd+Enter")]
31595
32286
  }
31596
32287
  ),
31597
- /* @__PURE__ */ jsx113(
32288
+ /* @__PURE__ */ jsx114(
31598
32289
  Shortcut2,
31599
32290
  {
31600
32291
  label: t("helpDialog.editText"),
31601
32292
  shortcuts: [getShortcutKey("Enter")]
31602
32293
  }
31603
32294
  ),
31604
- /* @__PURE__ */ jsx113(
32295
+ /* @__PURE__ */ jsx114(
31605
32296
  Shortcut2,
31606
32297
  {
31607
32298
  label: t("helpDialog.textNewLine"),
@@ -31611,7 +32302,7 @@ var HelpDialog = ({ onClose }) => {
31611
32302
  ]
31612
32303
  }
31613
32304
  ),
31614
- /* @__PURE__ */ jsx113(
32305
+ /* @__PURE__ */ jsx114(
31615
32306
  Shortcut2,
31616
32307
  {
31617
32308
  label: t("helpDialog.textFinish"),
@@ -31621,7 +32312,7 @@ var HelpDialog = ({ onClose }) => {
31621
32312
  ]
31622
32313
  }
31623
32314
  ),
31624
- /* @__PURE__ */ jsx113(
32315
+ /* @__PURE__ */ jsx114(
31625
32316
  Shortcut2,
31626
32317
  {
31627
32318
  label: t("helpDialog.curvedArrow"),
@@ -31634,7 +32325,7 @@ var HelpDialog = ({ onClose }) => {
31634
32325
  isOr: false
31635
32326
  }
31636
32327
  ),
31637
- /* @__PURE__ */ jsx113(
32328
+ /* @__PURE__ */ jsx114(
31638
32329
  Shortcut2,
31639
32330
  {
31640
32331
  label: t("helpDialog.curvedLine"),
@@ -31647,7 +32338,7 @@ var HelpDialog = ({ onClose }) => {
31647
32338
  isOr: false
31648
32339
  }
31649
32340
  ),
31650
- /* @__PURE__ */ jsx113(
32341
+ /* @__PURE__ */ jsx114(
31651
32342
  Shortcut2,
31652
32343
  {
31653
32344
  label: t("helpDialog.cropStart"),
@@ -31658,7 +32349,7 @@ var HelpDialog = ({ onClose }) => {
31658
32349
  isOr: true
31659
32350
  }
31660
32351
  ),
31661
- /* @__PURE__ */ jsx113(
32352
+ /* @__PURE__ */ jsx114(
31662
32353
  Shortcut2,
31663
32354
  {
31664
32355
  label: t("helpDialog.cropFinish"),
@@ -31666,22 +32357,22 @@ var HelpDialog = ({ onClose }) => {
31666
32357
  isOr: true
31667
32358
  }
31668
32359
  ),
31669
- /* @__PURE__ */ jsx113(Shortcut2, { label: t("toolBar.lock"), shortcuts: [KEYS48.Q] }),
31670
- /* @__PURE__ */ jsx113(
32360
+ /* @__PURE__ */ jsx114(Shortcut2, { label: t("toolBar.lock"), shortcuts: [KEYS48.Q] }),
32361
+ /* @__PURE__ */ jsx114(
31671
32362
  Shortcut2,
31672
32363
  {
31673
32364
  label: t("helpDialog.preventBinding"),
31674
32365
  shortcuts: [getShortcutKey("CtrlOrCmd")]
31675
32366
  }
31676
32367
  ),
31677
- /* @__PURE__ */ jsx113(
32368
+ /* @__PURE__ */ jsx114(
31678
32369
  Shortcut2,
31679
32370
  {
31680
32371
  label: t("toolBar.link"),
31681
32372
  shortcuts: [getShortcutKey("CtrlOrCmd+K")]
31682
32373
  }
31683
32374
  ),
31684
- /* @__PURE__ */ jsx113(
32375
+ /* @__PURE__ */ jsx114(
31685
32376
  Shortcut2,
31686
32377
  {
31687
32378
  label: t("toolBar.convertElementType"),
@@ -31692,90 +32383,90 @@ var HelpDialog = ({ onClose }) => {
31692
32383
  ]
31693
32384
  }
31694
32385
  ),
31695
- /* @__PURE__ */ jsxs59(
32386
+ /* @__PURE__ */ jsxs60(
31696
32387
  ShortcutIsland2,
31697
32388
  {
31698
32389
  className: "HelpDialog__island--view",
31699
32390
  caption: t("helpDialog.view"),
31700
32391
  children: [
31701
- /* @__PURE__ */ jsx113(
32392
+ /* @__PURE__ */ jsx114(
31702
32393
  Shortcut2,
31703
32394
  {
31704
32395
  label: t("helpDialog.smartZoom"),
31705
32396
  shortcuts: [KEYS48.F]
31706
32397
  }
31707
32398
  ),
31708
- /* @__PURE__ */ jsx113(
32399
+ /* @__PURE__ */ jsx114(
31709
32400
  Shortcut2,
31710
32401
  {
31711
32402
  label: t("helpDialog.dragToZoom"),
31712
32403
  shortcuts: [`${KEYS48.Z}+${t("helpDialog.drag")}`]
31713
32404
  }
31714
32405
  ),
31715
- /* @__PURE__ */ jsx113(
32406
+ /* @__PURE__ */ jsx114(
31716
32407
  Shortcut2,
31717
32408
  {
31718
32409
  label: t("buttons.zoomIn"),
31719
32410
  shortcuts: [getShortcutKey("CtrlOrCmd++")]
31720
32411
  }
31721
32412
  ),
31722
- /* @__PURE__ */ jsx113(
32413
+ /* @__PURE__ */ jsx114(
31723
32414
  Shortcut2,
31724
32415
  {
31725
32416
  label: t("buttons.zoomOut"),
31726
32417
  shortcuts: [getShortcutKey("CtrlOrCmd+-")]
31727
32418
  }
31728
32419
  ),
31729
- /* @__PURE__ */ jsx113(
32420
+ /* @__PURE__ */ jsx114(
31730
32421
  Shortcut2,
31731
32422
  {
31732
32423
  label: t("buttons.resetZoom"),
31733
32424
  shortcuts: [getShortcutKey("CtrlOrCmd+0")]
31734
32425
  }
31735
32426
  ),
31736
- /* @__PURE__ */ jsx113(
32427
+ /* @__PURE__ */ jsx114(
31737
32428
  Shortcut2,
31738
32429
  {
31739
32430
  label: t("helpDialog.movePageUpDown"),
31740
32431
  shortcuts: ["PgUp/PgDn"]
31741
32432
  }
31742
32433
  ),
31743
- /* @__PURE__ */ jsx113(
32434
+ /* @__PURE__ */ jsx114(
31744
32435
  Shortcut2,
31745
32436
  {
31746
32437
  label: t("helpDialog.movePageLeftRight"),
31747
32438
  shortcuts: ["Shift+PgUp/PgDn"]
31748
32439
  }
31749
32440
  ),
31750
- /* @__PURE__ */ jsx113(
32441
+ /* @__PURE__ */ jsx114(
31751
32442
  Shortcut2,
31752
32443
  {
31753
32444
  label: t("buttons.objectsSnapMode"),
31754
32445
  shortcuts: [getShortcutKey("Alt+S")]
31755
32446
  }
31756
32447
  ),
31757
- /* @__PURE__ */ jsx113(
32448
+ /* @__PURE__ */ jsx114(
31758
32449
  Shortcut2,
31759
32450
  {
31760
32451
  label: t("labels.toggleGrid"),
31761
32452
  shortcuts: [getShortcutKey("CtrlOrCmd+'")]
31762
32453
  }
31763
32454
  ),
31764
- /* @__PURE__ */ jsx113(
32455
+ /* @__PURE__ */ jsx114(
31765
32456
  Shortcut2,
31766
32457
  {
31767
32458
  label: t("labels.viewMode"),
31768
32459
  shortcuts: [getShortcutKey("Alt+R")]
31769
32460
  }
31770
32461
  ),
31771
- /* @__PURE__ */ jsx113(
32462
+ /* @__PURE__ */ jsx114(
31772
32463
  Shortcut2,
31773
32464
  {
31774
32465
  label: t("stats.fullTitle"),
31775
32466
  shortcuts: [getShortcutKey("Alt+/")]
31776
32467
  }
31777
32468
  ),
31778
- /* @__PURE__ */ jsx113(
32469
+ /* @__PURE__ */ jsx114(
31779
32470
  Shortcut2,
31780
32471
  {
31781
32472
  label: t("search.title"),
@@ -31785,13 +32476,13 @@ var HelpDialog = ({ onClose }) => {
31785
32476
  ]
31786
32477
  }
31787
32478
  ),
31788
- /* @__PURE__ */ jsxs59(
32479
+ /* @__PURE__ */ jsxs60(
31789
32480
  ShortcutIsland2,
31790
32481
  {
31791
32482
  className: "HelpDialog__island--editor",
31792
32483
  caption: t("helpDialog.editor"),
31793
32484
  children: [
31794
- /* @__PURE__ */ jsx113(
32485
+ /* @__PURE__ */ jsx114(
31795
32486
  Shortcut2,
31796
32487
  {
31797
32488
  label: t("labels.moveCanvas"),
@@ -31802,56 +32493,56 @@ var HelpDialog = ({ onClose }) => {
31802
32493
  isOr: true
31803
32494
  }
31804
32495
  ),
31805
- /* @__PURE__ */ jsx113(
32496
+ /* @__PURE__ */ jsx114(
31806
32497
  Shortcut2,
31807
32498
  {
31808
32499
  label: t("labels.delete"),
31809
32500
  shortcuts: [getShortcutKey("Delete")]
31810
32501
  }
31811
32502
  ),
31812
- /* @__PURE__ */ jsx113(
32503
+ /* @__PURE__ */ jsx114(
31813
32504
  Shortcut2,
31814
32505
  {
31815
32506
  label: t("labels.cut"),
31816
32507
  shortcuts: [getShortcutKey("CtrlOrCmd+X")]
31817
32508
  }
31818
32509
  ),
31819
- /* @__PURE__ */ jsx113(
32510
+ /* @__PURE__ */ jsx114(
31820
32511
  Shortcut2,
31821
32512
  {
31822
32513
  label: t("labels.copy"),
31823
32514
  shortcuts: [getShortcutKey("CtrlOrCmd+C")]
31824
32515
  }
31825
32516
  ),
31826
- /* @__PURE__ */ jsx113(
32517
+ /* @__PURE__ */ jsx114(
31827
32518
  Shortcut2,
31828
32519
  {
31829
32520
  label: t("labels.paste"),
31830
32521
  shortcuts: [getShortcutKey("CtrlOrCmd+V")]
31831
32522
  }
31832
32523
  ),
31833
- /* @__PURE__ */ jsx113(
32524
+ /* @__PURE__ */ jsx114(
31834
32525
  Shortcut2,
31835
32526
  {
31836
32527
  label: t("labels.pasteAsPlaintext"),
31837
32528
  shortcuts: [getShortcutKey("CtrlOrCmd+Shift+V")]
31838
32529
  }
31839
32530
  ),
31840
- /* @__PURE__ */ jsx113(
32531
+ /* @__PURE__ */ jsx114(
31841
32532
  Shortcut2,
31842
32533
  {
31843
32534
  label: t("labels.selectAll"),
31844
32535
  shortcuts: [getShortcutKey("CtrlOrCmd+A")]
31845
32536
  }
31846
32537
  ),
31847
- /* @__PURE__ */ jsx113(
32538
+ /* @__PURE__ */ jsx114(
31848
32539
  Shortcut2,
31849
32540
  {
31850
32541
  label: t("labels.multiSelect"),
31851
32542
  shortcuts: [getShortcutKey(`Shift+${t("helpDialog.click")}`)]
31852
32543
  }
31853
32544
  ),
31854
- /* @__PURE__ */ jsx113(
32545
+ /* @__PURE__ */ jsx114(
31855
32546
  Shortcut2,
31856
32547
  {
31857
32548
  label: t("helpDialog.deepSelect"),
@@ -31860,7 +32551,7 @@ var HelpDialog = ({ onClose }) => {
31860
32551
  ]
31861
32552
  }
31862
32553
  ),
31863
- /* @__PURE__ */ jsx113(
32554
+ /* @__PURE__ */ jsx114(
31864
32555
  Shortcut2,
31865
32556
  {
31866
32557
  label: t("helpDialog.deepBoxSelect"),
@@ -31869,14 +32560,14 @@ var HelpDialog = ({ onClose }) => {
31869
32560
  ]
31870
32561
  }
31871
32562
  ),
31872
- (probablySupportsClipboardBlob || isFirefox4) && /* @__PURE__ */ jsx113(
32563
+ (probablySupportsClipboardBlob || isFirefox4) && /* @__PURE__ */ jsx114(
31873
32564
  Shortcut2,
31874
32565
  {
31875
32566
  label: t("labels.copyAsPng"),
31876
32567
  shortcuts: [getShortcutKey("Shift+Alt+C")]
31877
32568
  }
31878
32569
  ),
31879
- /* @__PURE__ */ jsx113(
32570
+ /* @__PURE__ */ jsx114(
31880
32571
  Shortcut2,
31881
32572
  {
31882
32573
  label: t("labels.sendToBack"),
@@ -31885,7 +32576,7 @@ var HelpDialog = ({ onClose }) => {
31885
32576
  ]
31886
32577
  }
31887
32578
  ),
31888
- /* @__PURE__ */ jsx113(
32579
+ /* @__PURE__ */ jsx114(
31889
32580
  Shortcut2,
31890
32581
  {
31891
32582
  label: t("labels.bringToFront"),
@@ -31894,56 +32585,56 @@ var HelpDialog = ({ onClose }) => {
31894
32585
  ]
31895
32586
  }
31896
32587
  ),
31897
- /* @__PURE__ */ jsx113(
32588
+ /* @__PURE__ */ jsx114(
31898
32589
  Shortcut2,
31899
32590
  {
31900
32591
  label: t("labels.sendBackward"),
31901
32592
  shortcuts: [getShortcutKey("CtrlOrCmd+[")]
31902
32593
  }
31903
32594
  ),
31904
- /* @__PURE__ */ jsx113(
32595
+ /* @__PURE__ */ jsx114(
31905
32596
  Shortcut2,
31906
32597
  {
31907
32598
  label: t("labels.bringForward"),
31908
32599
  shortcuts: [getShortcutKey("CtrlOrCmd+]")]
31909
32600
  }
31910
32601
  ),
31911
- /* @__PURE__ */ jsx113(
32602
+ /* @__PURE__ */ jsx114(
31912
32603
  Shortcut2,
31913
32604
  {
31914
32605
  label: t("labels.alignTop"),
31915
32606
  shortcuts: [getShortcutKey("CtrlOrCmd+Shift+Up")]
31916
32607
  }
31917
32608
  ),
31918
- /* @__PURE__ */ jsx113(
32609
+ /* @__PURE__ */ jsx114(
31919
32610
  Shortcut2,
31920
32611
  {
31921
32612
  label: t("labels.alignBottom"),
31922
32613
  shortcuts: [getShortcutKey("CtrlOrCmd+Shift+Down")]
31923
32614
  }
31924
32615
  ),
31925
- /* @__PURE__ */ jsx113(
32616
+ /* @__PURE__ */ jsx114(
31926
32617
  Shortcut2,
31927
32618
  {
31928
32619
  label: t("labels.alignLeft"),
31929
32620
  shortcuts: [getShortcutKey("CtrlOrCmd+Shift+Left")]
31930
32621
  }
31931
32622
  ),
31932
- /* @__PURE__ */ jsx113(
32623
+ /* @__PURE__ */ jsx114(
31933
32624
  Shortcut2,
31934
32625
  {
31935
32626
  label: t("labels.alignRight"),
31936
32627
  shortcuts: [getShortcutKey("CtrlOrCmd+Shift+Right")]
31937
32628
  }
31938
32629
  ),
31939
- /* @__PURE__ */ jsx113(
32630
+ /* @__PURE__ */ jsx114(
31940
32631
  Shortcut2,
31941
32632
  {
31942
32633
  label: t("labels.arrangeElements"),
31943
32634
  shortcuts: [getShortcutKey("Shift+R")]
31944
32635
  }
31945
32636
  ),
31946
- /* @__PURE__ */ jsx113(
32637
+ /* @__PURE__ */ jsx114(
31947
32638
  Shortcut2,
31948
32639
  {
31949
32640
  label: t("labels.duplicateSelection"),
@@ -31953,21 +32644,21 @@ var HelpDialog = ({ onClose }) => {
31953
32644
  ]
31954
32645
  }
31955
32646
  ),
31956
- /* @__PURE__ */ jsx113(
32647
+ /* @__PURE__ */ jsx114(
31957
32648
  Shortcut2,
31958
32649
  {
31959
32650
  label: t("helpDialog.toggleElementLock"),
31960
32651
  shortcuts: [getShortcutKey("CtrlOrCmd+Shift+L")]
31961
32652
  }
31962
32653
  ),
31963
- /* @__PURE__ */ jsx113(
32654
+ /* @__PURE__ */ jsx114(
31964
32655
  Shortcut2,
31965
32656
  {
31966
32657
  label: t("buttons.undo"),
31967
32658
  shortcuts: [getShortcutKey("CtrlOrCmd+Z")]
31968
32659
  }
31969
32660
  ),
31970
- /* @__PURE__ */ jsx113(
32661
+ /* @__PURE__ */ jsx114(
31971
32662
  Shortcut2,
31972
32663
  {
31973
32664
  label: t("buttons.redo"),
@@ -31977,63 +32668,63 @@ var HelpDialog = ({ onClose }) => {
31977
32668
  ] : [getShortcutKey("CtrlOrCmd+Shift+Z")]
31978
32669
  }
31979
32670
  ),
31980
- /* @__PURE__ */ jsx113(
32671
+ /* @__PURE__ */ jsx114(
31981
32672
  Shortcut2,
31982
32673
  {
31983
32674
  label: t("labels.group"),
31984
32675
  shortcuts: [getShortcutKey("CtrlOrCmd+G")]
31985
32676
  }
31986
32677
  ),
31987
- /* @__PURE__ */ jsx113(
32678
+ /* @__PURE__ */ jsx114(
31988
32679
  Shortcut2,
31989
32680
  {
31990
32681
  label: t("labels.ungroup"),
31991
32682
  shortcuts: [getShortcutKey("CtrlOrCmd+Shift+G")]
31992
32683
  }
31993
32684
  ),
31994
- /* @__PURE__ */ jsx113(
32685
+ /* @__PURE__ */ jsx114(
31995
32686
  Shortcut2,
31996
32687
  {
31997
32688
  label: t("labels.flipHorizontal"),
31998
32689
  shortcuts: [getShortcutKey("Shift+H")]
31999
32690
  }
32000
32691
  ),
32001
- /* @__PURE__ */ jsx113(
32692
+ /* @__PURE__ */ jsx114(
32002
32693
  Shortcut2,
32003
32694
  {
32004
32695
  label: t("labels.flipVertical"),
32005
32696
  shortcuts: [getShortcutKey("Shift+V")]
32006
32697
  }
32007
32698
  ),
32008
- /* @__PURE__ */ jsx113(
32699
+ /* @__PURE__ */ jsx114(
32009
32700
  Shortcut2,
32010
32701
  {
32011
32702
  label: t("labels.showStroke"),
32012
32703
  shortcuts: [getShortcutKey("S")]
32013
32704
  }
32014
32705
  ),
32015
- /* @__PURE__ */ jsx113(
32706
+ /* @__PURE__ */ jsx114(
32016
32707
  Shortcut2,
32017
32708
  {
32018
32709
  label: t("labels.showBackground"),
32019
32710
  shortcuts: [getShortcutKey("G")]
32020
32711
  }
32021
32712
  ),
32022
- /* @__PURE__ */ jsx113(
32713
+ /* @__PURE__ */ jsx114(
32023
32714
  Shortcut2,
32024
32715
  {
32025
32716
  label: t("labels.showFonts"),
32026
32717
  shortcuts: [getShortcutKey("Shift+F")]
32027
32718
  }
32028
32719
  ),
32029
- /* @__PURE__ */ jsx113(
32720
+ /* @__PURE__ */ jsx114(
32030
32721
  Shortcut2,
32031
32722
  {
32032
32723
  label: t("labels.decreaseFontSize"),
32033
32724
  shortcuts: [getShortcutKey("CtrlOrCmd+Shift+<")]
32034
32725
  }
32035
32726
  ),
32036
- /* @__PURE__ */ jsx113(
32727
+ /* @__PURE__ */ jsx114(
32037
32728
  Shortcut2,
32038
32729
  {
32039
32730
  label: t("labels.increaseFontSize"),
@@ -32043,7 +32734,7 @@ var HelpDialog = ({ onClose }) => {
32043
32734
  ]
32044
32735
  }
32045
32736
  )
32046
- ] }) : /* @__PURE__ */ jsx113(BasicHelpDialog, {})
32737
+ ] }) : /* @__PURE__ */ jsx114(BasicHelpDialog, {})
32047
32738
  }
32048
32739
  ) });
32049
32740
  };
@@ -32082,8 +32773,8 @@ var useCopyStatus = () => {
32082
32773
  };
32083
32774
 
32084
32775
  // components/Switch.tsx
32085
- import clsx49 from "clsx";
32086
- import { jsx as jsx114 } from "react/jsx-runtime";
32776
+ import clsx50 from "clsx";
32777
+ import { jsx as jsx115 } from "react/jsx-runtime";
32087
32778
  var Switch = ({
32088
32779
  title,
32089
32780
  name,
@@ -32091,7 +32782,7 @@ var Switch = ({
32091
32782
  onChange,
32092
32783
  disabled = false
32093
32784
  }) => {
32094
- return /* @__PURE__ */ jsx114("div", { className: clsx49("Switch", { toggled: checked, disabled }), children: /* @__PURE__ */ jsx114(
32785
+ return /* @__PURE__ */ jsx115("div", { className: clsx50("Switch", { toggled: checked, disabled }), children: /* @__PURE__ */ jsx115(
32095
32786
  "input",
32096
32787
  {
32097
32788
  name,
@@ -32111,12 +32802,12 @@ var Switch = ({
32111
32802
  };
32112
32803
 
32113
32804
  // components/ImageExportDialog.tsx
32114
- import { jsx as jsx115, jsxs as jsxs60 } from "react/jsx-runtime";
32805
+ import { jsx as jsx116, jsxs as jsxs61 } from "react/jsx-runtime";
32115
32806
  var ErrorCanvasPreview = () => {
32116
- return /* @__PURE__ */ jsxs60("div", { children: [
32117
- /* @__PURE__ */ jsx115("h3", { children: t("canvasError.cannotShowPreview") }),
32118
- /* @__PURE__ */ jsx115("p", { children: /* @__PURE__ */ jsx115("span", { children: t("canvasError.canvasTooBig") }) }),
32119
- /* @__PURE__ */ jsxs60("em", { children: [
32807
+ return /* @__PURE__ */ jsxs61("div", { children: [
32808
+ /* @__PURE__ */ jsx116("h3", { children: t("canvasError.cannotShowPreview") }),
32809
+ /* @__PURE__ */ jsx116("p", { children: /* @__PURE__ */ jsx116("span", { children: t("canvasError.canvasTooBig") }) }),
32810
+ /* @__PURE__ */ jsxs61("em", { children: [
32120
32811
  "(",
32121
32812
  t("canvasError.canvasTooBigTip"),
32122
32813
  ")"
@@ -32230,11 +32921,11 @@ var ImageExportModal = ({
32230
32921
  exportScale,
32231
32922
  embedScene
32232
32923
  ]);
32233
- return /* @__PURE__ */ jsxs60("div", { className: "ImageExportModal", children: [
32234
- /* @__PURE__ */ jsx115("h3", { children: t("imageExportDialog.header") }),
32235
- /* @__PURE__ */ jsxs60("div", { className: "ImageExportModal__preview", children: [
32236
- /* @__PURE__ */ jsx115("div", { className: "ImageExportModal__preview__canvas", ref: previewRef, children: renderError && /* @__PURE__ */ jsx115(ErrorCanvasPreview, {}) }),
32237
- /* @__PURE__ */ jsx115("div", { className: "ImageExportModal__preview__filename", children: !nativeFileSystemSupported && /* @__PURE__ */ jsx115(
32924
+ return /* @__PURE__ */ jsxs61("div", { className: "ImageExportModal", children: [
32925
+ /* @__PURE__ */ jsx116("h3", { children: t("imageExportDialog.header") }),
32926
+ /* @__PURE__ */ jsxs61("div", { className: "ImageExportModal__preview", children: [
32927
+ /* @__PURE__ */ jsx116("div", { className: "ImageExportModal__preview__canvas", ref: previewRef, children: renderError && /* @__PURE__ */ jsx116(ErrorCanvasPreview, {}) }),
32928
+ /* @__PURE__ */ jsx116("div", { className: "ImageExportModal__preview__filename", children: !nativeFileSystemSupported && /* @__PURE__ */ jsx116(
32238
32929
  "input",
32239
32930
  {
32240
32931
  type: "text",
@@ -32252,14 +32943,14 @@ var ImageExportModal = ({
32252
32943
  }
32253
32944
  ) })
32254
32945
  ] }),
32255
- /* @__PURE__ */ jsxs60("div", { className: "ImageExportModal__settings", children: [
32256
- /* @__PURE__ */ jsx115("h3", { children: t("imageExportDialog.header") }),
32257
- hasSelection && /* @__PURE__ */ jsx115(
32946
+ /* @__PURE__ */ jsxs61("div", { className: "ImageExportModal__settings", children: [
32947
+ /* @__PURE__ */ jsx116("h3", { children: t("imageExportDialog.header") }),
32948
+ hasSelection && /* @__PURE__ */ jsx116(
32258
32949
  ExportSetting,
32259
32950
  {
32260
32951
  label: t("imageExportDialog.label.onlySelected"),
32261
32952
  name: "exportOnlySelected",
32262
- children: /* @__PURE__ */ jsx115(
32953
+ children: /* @__PURE__ */ jsx116(
32263
32954
  Switch,
32264
32955
  {
32265
32956
  name: "exportOnlySelected",
@@ -32271,12 +32962,12 @@ var ImageExportModal = ({
32271
32962
  )
32272
32963
  }
32273
32964
  ),
32274
- /* @__PURE__ */ jsx115(
32965
+ /* @__PURE__ */ jsx116(
32275
32966
  ExportSetting,
32276
32967
  {
32277
32968
  label: t("imageExportDialog.label.withBackground"),
32278
32969
  name: "exportBackgroundSwitch",
32279
- children: /* @__PURE__ */ jsx115(
32970
+ children: /* @__PURE__ */ jsx116(
32280
32971
  Switch,
32281
32972
  {
32282
32973
  name: "exportBackgroundSwitch",
@@ -32293,12 +32984,12 @@ var ImageExportModal = ({
32293
32984
  )
32294
32985
  }
32295
32986
  ),
32296
- /* @__PURE__ */ jsx115(
32987
+ /* @__PURE__ */ jsx116(
32297
32988
  ExportSetting,
32298
32989
  {
32299
32990
  label: t("imageExportDialog.label.darkMode"),
32300
32991
  name: "exportDarkModeSwitch",
32301
- children: /* @__PURE__ */ jsx115(
32992
+ children: /* @__PURE__ */ jsx116(
32302
32993
  Switch,
32303
32994
  {
32304
32995
  name: "exportDarkModeSwitch",
@@ -32314,13 +33005,13 @@ var ImageExportModal = ({
32314
33005
  )
32315
33006
  }
32316
33007
  ),
32317
- /* @__PURE__ */ jsx115(
33008
+ /* @__PURE__ */ jsx116(
32318
33009
  ExportSetting,
32319
33010
  {
32320
33011
  label: t("imageExportDialog.label.embedScene"),
32321
33012
  tooltip: t("imageExportDialog.tooltip.embedScene"),
32322
33013
  name: "exportEmbedSwitch",
32323
- children: /* @__PURE__ */ jsx115(
33014
+ children: /* @__PURE__ */ jsx116(
32324
33015
  Switch,
32325
33016
  {
32326
33017
  name: "exportEmbedSwitch",
@@ -32337,12 +33028,12 @@ var ImageExportModal = ({
32337
33028
  )
32338
33029
  }
32339
33030
  ),
32340
- /* @__PURE__ */ jsx115(
33031
+ /* @__PURE__ */ jsx116(
32341
33032
  ExportSetting,
32342
33033
  {
32343
33034
  label: t("imageExportDialog.label.scale"),
32344
33035
  name: "exportScale",
32345
- children: /* @__PURE__ */ jsx115(
33036
+ children: /* @__PURE__ */ jsx116(
32346
33037
  RadioGroup,
32347
33038
  {
32348
33039
  name: "exportScale",
@@ -32359,8 +33050,8 @@ var ImageExportModal = ({
32359
33050
  )
32360
33051
  }
32361
33052
  ),
32362
- /* @__PURE__ */ jsxs60("div", { className: "ImageExportModal__settings__buttons", children: [
32363
- /* @__PURE__ */ jsx115(
33053
+ /* @__PURE__ */ jsxs61("div", { className: "ImageExportModal__settings__buttons", children: [
33054
+ /* @__PURE__ */ jsx116(
32364
33055
  FilledButton,
32365
33056
  {
32366
33057
  className: "ImageExportModal__settings__buttons__button",
@@ -32372,7 +33063,7 @@ var ImageExportModal = ({
32372
33063
  children: t("imageExportDialog.button.exportToPng")
32373
33064
  }
32374
33065
  ),
32375
- /* @__PURE__ */ jsx115(
33066
+ /* @__PURE__ */ jsx116(
32376
33067
  FilledButton,
32377
33068
  {
32378
33069
  className: "ImageExportModal__settings__buttons__button",
@@ -32384,7 +33075,7 @@ var ImageExportModal = ({
32384
33075
  children: t("imageExportDialog.button.exportToSvg")
32385
33076
  }
32386
33077
  ),
32387
- (probablySupportsClipboardBlob || isFirefox5) && /* @__PURE__ */ jsx115(
33078
+ (probablySupportsClipboardBlob || isFirefox5) && /* @__PURE__ */ jsx116(
32388
33079
  FilledButton,
32389
33080
  {
32390
33081
  className: "ImageExportModal__settings__buttons__button",
@@ -32414,19 +33105,19 @@ var ExportSetting = ({
32414
33105
  tooltip,
32415
33106
  name
32416
33107
  }) => {
32417
- return /* @__PURE__ */ jsxs60("div", { className: "ImageExportModal__settings__setting", title: label, children: [
32418
- /* @__PURE__ */ jsxs60(
33108
+ return /* @__PURE__ */ jsxs61("div", { className: "ImageExportModal__settings__setting", title: label, children: [
33109
+ /* @__PURE__ */ jsxs61(
32419
33110
  "label",
32420
33111
  {
32421
33112
  htmlFor: name,
32422
33113
  className: "ImageExportModal__settings__setting__label",
32423
33114
  children: [
32424
33115
  label,
32425
- tooltip && /* @__PURE__ */ jsx115(Tooltip, { label: tooltip, long: true, children: helpIcon })
33116
+ tooltip && /* @__PURE__ */ jsx116(Tooltip, { label: tooltip, long: true, children: helpIcon })
32426
33117
  ]
32427
33118
  }
32428
33119
  ),
32429
- /* @__PURE__ */ jsx115("div", { className: "ImageExportModal__settings__setting__content", children })
33120
+ /* @__PURE__ */ jsx116("div", { className: "ImageExportModal__settings__setting__content", children })
32430
33121
  ] });
32431
33122
  };
32432
33123
  var ImageExportDialog = ({
@@ -32444,7 +33135,7 @@ var ImageExportDialog = ({
32444
33135
  elementsSnapshot: cloneJSON4(elements)
32445
33136
  };
32446
33137
  });
32447
- return /* @__PURE__ */ jsx115(Dialog, { onCloseRequest, size: "wide", title: false, children: /* @__PURE__ */ jsx115(
33138
+ return /* @__PURE__ */ jsx116(Dialog, { onCloseRequest, size: "wide", title: false, children: /* @__PURE__ */ jsx116(
32448
33139
  ImageExportModal,
32449
33140
  {
32450
33141
  elementsSnapshot,
@@ -32459,13 +33150,13 @@ var ImageExportDialog = ({
32459
33150
  };
32460
33151
 
32461
33152
  // components/DefaultSidebar.tsx
32462
- import clsx54 from "clsx";
33153
+ import clsx55 from "clsx";
32463
33154
  import { CANVAS_SEARCH_TAB as CANVAS_SEARCH_TAB2, DEFAULT_SIDEBAR as DEFAULT_SIDEBAR2 } from "@excalidraw/common";
32464
33155
 
32465
33156
  // components/SearchMenu.tsx
32466
- import clsx50 from "clsx";
33157
+ import clsx51 from "clsx";
32467
33158
  import debounce3 from "lodash.debounce";
32468
- import { Fragment as Fragment20, memo as memo3, useEffect as useEffect32, useMemo as useMemo11, useRef as useRef26, useState as useState31 } from "react";
33159
+ import { Fragment as Fragment21, memo as memo3, useEffect as useEffect32, useMemo as useMemo11, useRef as useRef26, useState as useState31 } from "react";
32469
33160
  import {
32470
33161
  CLASSES as CLASSES7,
32471
33162
  EVENT as EVENT8,
@@ -32474,7 +33165,7 @@ import {
32474
33165
  getLineHeight as getLineHeight7
32475
33166
  } from "@excalidraw/common";
32476
33167
  import {
32477
- getCommonBounds as getCommonBounds11,
33168
+ getCommonBounds as getCommonBounds12,
32478
33169
  isElementCompletelyInViewport
32479
33170
  } from "@excalidraw/element";
32480
33171
  import { measureText as measureText7 } from "@excalidraw/element";
@@ -32487,7 +33178,7 @@ import {
32487
33178
  import { newTextElement as newTextElement5 } from "@excalidraw/element";
32488
33179
  import { isTextElement as isTextElement16, isFrameLikeElement as isFrameLikeElement16 } from "@excalidraw/element";
32489
33180
  import { getDefaultFrameName } from "@excalidraw/element/frame";
32490
- import { Fragment as Fragment21, jsx as jsx116, jsxs as jsxs61 } from "react/jsx-runtime";
33181
+ import { Fragment as Fragment22, jsx as jsx117, jsxs as jsxs62 } from "react/jsx-runtime";
32491
33182
  var searchQueryAtom = atom("");
32492
33183
  var searchItemInFocusAtom = atom(null);
32493
33184
  var SEARCH_DEBOUNCE = 350;
@@ -32612,7 +33303,7 @@ var SearchMenu2 = () => {
32612
33303
  ) || isTextTiny) {
32613
33304
  const behavior = isTextTiny && fontSize < FONT_SIZE_LEGIBILITY_THRESHOLD ? "contain" : "scale-down";
32614
33305
  app.viewport.setViewport({
32615
- target: getCommonBounds11([matchAsElement]),
33306
+ target: getCommonBounds12([matchAsElement]),
32616
33307
  fit: behavior,
32617
33308
  animation: { duration: 300 },
32618
33309
  offsets: { ui: true }
@@ -32685,9 +33376,9 @@ var SearchMenu2 = () => {
32685
33376
  });
32686
33377
  }, [setAppState, stableState, app]);
32687
33378
  const matchCount = `${searchMatches.items.length} ${searchMatches.items.length === 1 ? t("search.singleResult") : t("search.multipleResults")}`;
32688
- return /* @__PURE__ */ jsxs61("div", { className: "layer-ui__search", children: [
32689
- /* @__PURE__ */ jsxs61("div", { className: "layer-ui__search-header", children: [
32690
- /* @__PURE__ */ jsx116(
33379
+ return /* @__PURE__ */ jsxs62("div", { className: "layer-ui__search", children: [
33380
+ /* @__PURE__ */ jsxs62("div", { className: "layer-ui__search-header", children: [
33381
+ /* @__PURE__ */ jsx117(
32691
33382
  TextField,
32692
33383
  {
32693
33384
  className: CLASSES7.SEARCH_MENU_INPUT_WRAPPER,
@@ -32723,7 +33414,7 @@ var SearchMenu2 = () => {
32723
33414
  selectOnRender: true
32724
33415
  }
32725
33416
  ),
32726
- /* @__PURE__ */ jsx116(
33417
+ /* @__PURE__ */ jsx117(
32727
33418
  Button,
32728
33419
  {
32729
33420
  "data-testid": "sidebar-close",
@@ -32738,15 +33429,15 @@ var SearchMenu2 = () => {
32738
33429
  }
32739
33430
  )
32740
33431
  ] }),
32741
- /* @__PURE__ */ jsxs61("div", { className: "layer-ui__search-count", children: [
32742
- searchMatches.items.length > 0 && /* @__PURE__ */ jsxs61(Fragment21, { children: [
32743
- focusIndex !== null && focusIndex > -1 ? /* @__PURE__ */ jsxs61("div", { children: [
33432
+ /* @__PURE__ */ jsxs62("div", { className: "layer-ui__search-count", children: [
33433
+ searchMatches.items.length > 0 && /* @__PURE__ */ jsxs62(Fragment22, { children: [
33434
+ focusIndex !== null && focusIndex > -1 ? /* @__PURE__ */ jsxs62("div", { children: [
32744
33435
  focusIndex + 1,
32745
33436
  " / ",
32746
33437
  matchCount
32747
- ] }) : /* @__PURE__ */ jsx116("div", { children: matchCount }),
32748
- /* @__PURE__ */ jsxs61("div", { className: "result-nav", children: [
32749
- /* @__PURE__ */ jsx116(
33438
+ ] }) : /* @__PURE__ */ jsx117("div", { children: matchCount }),
33439
+ /* @__PURE__ */ jsxs62("div", { className: "result-nav", children: [
33440
+ /* @__PURE__ */ jsx117(
32750
33441
  Button,
32751
33442
  {
32752
33443
  onSelect: () => {
@@ -32756,7 +33447,7 @@ var SearchMenu2 = () => {
32756
33447
  children: collapseDownIcon
32757
33448
  }
32758
33449
  ),
32759
- /* @__PURE__ */ jsx116(
33450
+ /* @__PURE__ */ jsx117(
32760
33451
  Button,
32761
33452
  {
32762
33453
  onSelect: () => {
@@ -32768,9 +33459,9 @@ var SearchMenu2 = () => {
32768
33459
  )
32769
33460
  ] })
32770
33461
  ] }),
32771
- searchMatches.items.length === 0 && searchQuery && searchedQueryRef.current && /* @__PURE__ */ jsx116("div", { style: { margin: "1rem auto" }, children: t("search.noMatch") })
33462
+ searchMatches.items.length === 0 && searchQuery && searchedQueryRef.current && /* @__PURE__ */ jsx117("div", { style: { margin: "1rem auto" }, children: t("search.noMatch") })
32772
33463
  ] }),
32773
- /* @__PURE__ */ jsx116(
33464
+ /* @__PURE__ */ jsx117(
32774
33465
  MatchList,
32775
33466
  {
32776
33467
  matches: searchMatches,
@@ -32794,11 +33485,11 @@ var ListItem = (props) => {
32794
33485
  ),
32795
33486
  props.preview.moreAfter ? "..." : ""
32796
33487
  ];
32797
- return /* @__PURE__ */ jsx116(
33488
+ return /* @__PURE__ */ jsx117(
32798
33489
  "div",
32799
33490
  {
32800
33491
  tabIndex: -1,
32801
- className: clsx50("layer-ui__result-item", {
33492
+ className: clsx51("layer-ui__result-item", {
32802
33493
  active: props.highlighted
32803
33494
  }),
32804
33495
  onClick: props.onClick,
@@ -32807,7 +33498,7 @@ var ListItem = (props) => {
32807
33498
  ref?.scrollIntoView({ behavior: "auto", block: "nearest" });
32808
33499
  }
32809
33500
  },
32810
- children: /* @__PURE__ */ jsx116("div", { className: "preview-text", children: preview.flatMap((text, idx) => /* @__PURE__ */ jsx116(Fragment20, { children: idx === 2 ? /* @__PURE__ */ jsx116("b", { children: text }) : text }, idx)) })
33501
+ children: /* @__PURE__ */ jsx117("div", { className: "preview-text", children: preview.flatMap((text, idx) => /* @__PURE__ */ jsx117(Fragment21, { children: idx === 2 ? /* @__PURE__ */ jsx117("b", { children: text }) : text }, idx)) })
32811
33502
  }
32812
33503
  );
32813
33504
  };
@@ -32820,13 +33511,13 @@ var MatchListBase = (props) => {
32820
33511
  () => props.matches.items.filter((match) => isTextElement16(match.element)),
32821
33512
  [props.matches]
32822
33513
  );
32823
- return /* @__PURE__ */ jsxs61("div", { className: "layer-ui__search-results", children: [
32824
- frameNameMatches.length > 0 && /* @__PURE__ */ jsxs61("div", { className: "layer-ui__search-result-container", children: [
32825
- /* @__PURE__ */ jsxs61("div", { className: "layer-ui__search-result-title", children: [
32826
- /* @__PURE__ */ jsx116("div", { className: "title-icon", children: frameToolIcon }),
32827
- /* @__PURE__ */ jsx116("div", { children: t("search.frames") })
33514
+ return /* @__PURE__ */ jsxs62("div", { className: "layer-ui__search-results", children: [
33515
+ frameNameMatches.length > 0 && /* @__PURE__ */ jsxs62("div", { className: "layer-ui__search-result-container", children: [
33516
+ /* @__PURE__ */ jsxs62("div", { className: "layer-ui__search-result-title", children: [
33517
+ /* @__PURE__ */ jsx117("div", { className: "title-icon", children: frameToolIcon }),
33518
+ /* @__PURE__ */ jsx117("div", { children: t("search.frames") })
32828
33519
  ] }),
32829
- frameNameMatches.map((searchMatch, index) => /* @__PURE__ */ jsx116(
33520
+ frameNameMatches.map((searchMatch, index) => /* @__PURE__ */ jsx117(
32830
33521
  ListItem,
32831
33522
  {
32832
33523
  searchQuery: props.searchQuery,
@@ -32836,14 +33527,14 @@ var MatchListBase = (props) => {
32836
33527
  },
32837
33528
  searchMatch.element.id + searchMatch.index
32838
33529
  )),
32839
- textMatches.length > 0 && /* @__PURE__ */ jsx116("div", { className: "layer-ui__divider" })
33530
+ textMatches.length > 0 && /* @__PURE__ */ jsx117("div", { className: "layer-ui__divider" })
32840
33531
  ] }),
32841
- textMatches.length > 0 && /* @__PURE__ */ jsxs61("div", { className: "layer-ui__search-result-container", children: [
32842
- /* @__PURE__ */ jsxs61("div", { className: "layer-ui__search-result-title", children: [
32843
- /* @__PURE__ */ jsx116("div", { className: "title-icon", children: TextIcon }),
32844
- /* @__PURE__ */ jsx116("div", { children: t("search.texts") })
33532
+ textMatches.length > 0 && /* @__PURE__ */ jsxs62("div", { className: "layer-ui__search-result-container", children: [
33533
+ /* @__PURE__ */ jsxs62("div", { className: "layer-ui__search-result-title", children: [
33534
+ /* @__PURE__ */ jsx117("div", { className: "title-icon", children: TextIcon }),
33535
+ /* @__PURE__ */ jsx117("div", { children: t("search.texts") })
32845
33536
  ] }),
32846
- textMatches.map((searchMatch, index) => /* @__PURE__ */ jsx116(
33537
+ textMatches.map((searchMatch, index) => /* @__PURE__ */ jsx117(
32847
33538
  ListItem,
32848
33539
  {
32849
33540
  searchQuery: props.searchQuery,
@@ -33022,11 +33713,11 @@ var handleSearch = debounce3(
33022
33713
  const texts = elements.filter(
33023
33714
  (el) => isTextElement16(el)
33024
33715
  );
33025
- const frames = elements.filter(
33716
+ const frames2 = elements.filter(
33026
33717
  (el) => isFrameLikeElement16(el)
33027
33718
  );
33028
33719
  texts.sort((a, b) => a.y - b.y);
33029
- frames.sort((a, b) => a.y - b.y);
33720
+ frames2.sort((a, b) => a.y - b.y);
33030
33721
  const textMatches = [];
33031
33722
  const regex = new RegExp(escapeSpecialCharacters(searchQuery), "gi");
33032
33723
  for (const textEl of texts) {
@@ -33047,7 +33738,7 @@ var handleSearch = debounce3(
33047
33738
  }
33048
33739
  }
33049
33740
  const frameMatches = [];
33050
- for (const frame of frames) {
33741
+ for (const frame of frames2) {
33051
33742
  let match = null;
33052
33743
  const name = frame.name ?? getDefaultFrameName(frame);
33053
33744
  while ((match = regex.exec(name)) !== null) {
@@ -33082,7 +33773,7 @@ var handleSearch = debounce3(
33082
33773
  );
33083
33774
 
33084
33775
  // components/Sidebar/Sidebar.tsx
33085
- import clsx53 from "clsx";
33776
+ import clsx54 from "clsx";
33086
33777
  import {
33087
33778
  useEffect as useEffect33,
33088
33779
  useLayoutEffect as useLayoutEffect9,
@@ -33101,15 +33792,15 @@ import {
33101
33792
  } from "@excalidraw/common";
33102
33793
 
33103
33794
  // components/Sidebar/SidebarHeader.tsx
33104
- import clsx51 from "clsx";
33795
+ import clsx52 from "clsx";
33105
33796
  import { useContext as useContext3 } from "react";
33106
33797
 
33107
33798
  // components/Sidebar/common.ts
33108
- import React34 from "react";
33109
- var SidebarPropsContext = React34.createContext({});
33799
+ import React35 from "react";
33800
+ var SidebarPropsContext = React35.createContext({});
33110
33801
 
33111
33802
  // components/Sidebar/SidebarHeader.tsx
33112
- import { jsx as jsx117, jsxs as jsxs62 } from "react/jsx-runtime";
33803
+ import { jsx as jsx118, jsxs as jsxs63 } from "react/jsx-runtime";
33113
33804
  var SidebarHeader = ({
33114
33805
  children,
33115
33806
  className
@@ -33117,15 +33808,15 @@ var SidebarHeader = ({
33117
33808
  const editorInterface = useEditorInterface();
33118
33809
  const props = useContext3(SidebarPropsContext);
33119
33810
  const renderDockButton = !!(editorInterface.canFitSidebar && props.shouldRenderDockButton);
33120
- return /* @__PURE__ */ jsxs62(
33811
+ return /* @__PURE__ */ jsxs63(
33121
33812
  "div",
33122
33813
  {
33123
- className: clsx51("sidebar__header", className),
33814
+ className: clsx52("sidebar__header", className),
33124
33815
  "data-testid": "sidebar-header",
33125
33816
  children: [
33126
33817
  children,
33127
- /* @__PURE__ */ jsxs62("div", { className: "sidebar__header__buttons", children: [
33128
- renderDockButton && /* @__PURE__ */ jsx117(Tooltip, { label: t("labels.sidebarLock"), children: /* @__PURE__ */ jsx117(
33818
+ /* @__PURE__ */ jsxs63("div", { className: "sidebar__header__buttons", children: [
33819
+ renderDockButton && /* @__PURE__ */ jsx118(Tooltip, { label: t("labels.sidebarLock"), children: /* @__PURE__ */ jsx118(
33129
33820
  Button,
33130
33821
  {
33131
33822
  onSelect: () => props.onDock?.(!props.docked),
@@ -33136,7 +33827,7 @@ var SidebarHeader = ({
33136
33827
  children: PinIcon
33137
33828
  }
33138
33829
  ) }),
33139
- /* @__PURE__ */ jsx117(
33830
+ /* @__PURE__ */ jsx118(
33140
33831
  Button,
33141
33832
  {
33142
33833
  "data-testid": "sidebar-close",
@@ -33155,14 +33846,14 @@ SidebarHeader.displayName = "SidebarHeader";
33155
33846
 
33156
33847
  // components/Sidebar/SidebarTabTrigger.tsx
33157
33848
  import { Tabs as RadixTabs } from "radix-ui";
33158
- import { jsx as jsx118 } from "react/jsx-runtime";
33849
+ import { jsx as jsx119 } from "react/jsx-runtime";
33159
33850
  var SidebarTabTrigger = ({
33160
33851
  children,
33161
33852
  tab,
33162
33853
  onSelect,
33163
33854
  ...rest
33164
33855
  }) => {
33165
- return /* @__PURE__ */ jsx118(RadixTabs.Trigger, { value: tab, asChild: true, onSelect, children: /* @__PURE__ */ jsx118(
33856
+ return /* @__PURE__ */ jsx119(RadixTabs.Trigger, { value: tab, asChild: true, onSelect, children: /* @__PURE__ */ jsx119(
33166
33857
  "button",
33167
33858
  {
33168
33859
  type: "button",
@@ -33176,18 +33867,18 @@ SidebarTabTrigger.displayName = "SidebarTabTrigger";
33176
33867
 
33177
33868
  // components/Sidebar/SidebarTabTriggers.tsx
33178
33869
  import { Tabs as RadixTabs2 } from "radix-ui";
33179
- import { jsx as jsx119 } from "react/jsx-runtime";
33870
+ import { jsx as jsx120 } from "react/jsx-runtime";
33180
33871
  var SidebarTabTriggers = ({
33181
33872
  children,
33182
33873
  ...rest
33183
33874
  }) => {
33184
- return /* @__PURE__ */ jsx119(RadixTabs2.List, { className: "sidebar-triggers", ...rest, children });
33875
+ return /* @__PURE__ */ jsx120(RadixTabs2.List, { className: "sidebar-triggers", ...rest, children });
33185
33876
  };
33186
33877
  SidebarTabTriggers.displayName = "SidebarTabTriggers";
33187
33878
 
33188
33879
  // components/Sidebar/SidebarTrigger.tsx
33189
- import clsx52 from "clsx";
33190
- import { jsx as jsx120, jsxs as jsxs63 } from "react/jsx-runtime";
33880
+ import clsx53 from "clsx";
33881
+ import { jsx as jsx121, jsxs as jsxs64 } from "react/jsx-runtime";
33191
33882
  var SidebarTrigger = ({
33192
33883
  name,
33193
33884
  tab,
@@ -33201,7 +33892,7 @@ var SidebarTrigger = ({
33201
33892
  const setAppState = useExcalidrawSetAppState();
33202
33893
  const appState = useUIAppState();
33203
33894
  const isOpen = appState.openSidebar?.name === name;
33204
- return /* @__PURE__ */ jsx120(
33895
+ return /* @__PURE__ */ jsx121(
33205
33896
  "button",
33206
33897
  {
33207
33898
  type: "button",
@@ -33220,9 +33911,9 @@ var SidebarTrigger = ({
33220
33911
  });
33221
33912
  onToggle?.(nextOpen);
33222
33913
  },
33223
- children: /* @__PURE__ */ jsxs63("div", { className: clsx52("sidebar-trigger", className), style, children: [
33224
- icon && /* @__PURE__ */ jsx120("div", { children: icon }),
33225
- children && /* @__PURE__ */ jsx120("div", { className: "sidebar-trigger__label", children })
33914
+ children: /* @__PURE__ */ jsxs64("div", { className: clsx53("sidebar-trigger", className), style, children: [
33915
+ icon && /* @__PURE__ */ jsx121("div", { children: icon }),
33916
+ children && /* @__PURE__ */ jsx121("div", { className: "sidebar-trigger__label", children })
33226
33917
  ] })
33227
33918
  }
33228
33919
  );
@@ -33231,7 +33922,7 @@ SidebarTrigger.displayName = "SidebarTrigger";
33231
33922
 
33232
33923
  // components/Sidebar/SidebarTabs.tsx
33233
33924
  import { Tabs as RadixTabs3 } from "radix-ui";
33234
- import { jsx as jsx121 } from "react/jsx-runtime";
33925
+ import { jsx as jsx122 } from "react/jsx-runtime";
33235
33926
  var SidebarTabs = ({
33236
33927
  children,
33237
33928
  ...rest
@@ -33242,7 +33933,7 @@ var SidebarTabs = ({
33242
33933
  return null;
33243
33934
  }
33244
33935
  const { name } = appState.openSidebar;
33245
- return /* @__PURE__ */ jsx121(
33936
+ return /* @__PURE__ */ jsx122(
33246
33937
  RadixTabs3.Root,
33247
33938
  {
33248
33939
  className: "sidebar-tabs-root",
@@ -33260,18 +33951,18 @@ SidebarTabs.displayName = "SidebarTabs";
33260
33951
 
33261
33952
  // components/Sidebar/SidebarTab.tsx
33262
33953
  import { Tabs as RadixTabs4 } from "radix-ui";
33263
- import { jsx as jsx122 } from "react/jsx-runtime";
33954
+ import { jsx as jsx123 } from "react/jsx-runtime";
33264
33955
  var SidebarTab = ({
33265
33956
  tab,
33266
33957
  children,
33267
33958
  ...rest
33268
33959
  }) => {
33269
- return /* @__PURE__ */ jsx122(RadixTabs4.Content, { ...rest, value: tab, "data-testid": tab, children });
33960
+ return /* @__PURE__ */ jsx123(RadixTabs4.Content, { ...rest, value: tab, "data-testid": tab, children });
33270
33961
  };
33271
33962
  SidebarTab.displayName = "SidebarTab";
33272
33963
 
33273
33964
  // components/Sidebar/Sidebar.tsx
33274
- import { jsx as jsx123 } from "react/jsx-runtime";
33965
+ import { jsx as jsx124 } from "react/jsx-runtime";
33275
33966
  import { createElement } from "react";
33276
33967
  var isSidebarDockedAtom = atom(false);
33277
33968
  var SidebarInner = forwardRef5(
@@ -33345,11 +34036,11 @@ var SidebarInner = forwardRef5(
33345
34036
  document.removeEventListener(EVENT9.KEYDOWN, handleKeyDown);
33346
34037
  };
33347
34038
  }, [closeSidebar, docked, editorInterface.canFitSidebar]);
33348
- return /* @__PURE__ */ jsx123(
34039
+ return /* @__PURE__ */ jsx124(
33349
34040
  Island,
33350
34041
  {
33351
34042
  ...rest,
33352
- className: clsx53(
34043
+ className: clsx54(
33353
34044
  CLASSES8.SIDEBAR,
33354
34045
  { "sidebar--docked": docked },
33355
34046
  className
@@ -33357,7 +34048,7 @@ var SidebarInner = forwardRef5(
33357
34048
  "data-viewport-ui": editorInterface.formFactor !== "phone" ? "side" : void 0,
33358
34049
  "data-viewport-ui-name": editorInterface.formFactor !== "phone" ? "sidebar" : void 0,
33359
34050
  ref: islandRef,
33360
- children: /* @__PURE__ */ jsx123(SidebarPropsContext.Provider, { value: headerPropsRef.current, children })
34051
+ children: /* @__PURE__ */ jsx124(SidebarPropsContext.Provider, { value: headerPropsRef.current, children })
33361
34052
  }
33362
34053
  );
33363
34054
  }
@@ -33404,13 +34095,13 @@ var Sidebar = Object.assign(
33404
34095
  Sidebar.displayName = "Sidebar";
33405
34096
 
33406
34097
  // components/DefaultSidebar.tsx
33407
- import { jsx as jsx124, jsxs as jsxs64 } from "react/jsx-runtime";
34098
+ import { jsx as jsx125, jsxs as jsxs65 } from "react/jsx-runtime";
33408
34099
  import { createElement as createElement2 } from "react";
33409
34100
  var DefaultSidebarTrigger = withInternalFallback(
33410
34101
  "DefaultSidebarTrigger",
33411
34102
  (props) => {
33412
34103
  const { DefaultSidebarTriggerTunnel } = useTunnels();
33413
- return /* @__PURE__ */ jsx124(DefaultSidebarTriggerTunnel.In, { children: /* @__PURE__ */ jsx124(
34104
+ return /* @__PURE__ */ jsx125(DefaultSidebarTriggerTunnel.In, { children: /* @__PURE__ */ jsx125(
33414
34105
  Sidebar.Trigger,
33415
34106
  {
33416
34107
  ...props,
@@ -33423,7 +34114,7 @@ var DefaultSidebarTrigger = withInternalFallback(
33423
34114
  DefaultSidebarTrigger.displayName = "DefaultSidebarTrigger";
33424
34115
  var DefaultTabTriggers = ({ children }) => {
33425
34116
  const { DefaultSidebarTabTriggersTunnel } = useTunnels();
33426
- return /* @__PURE__ */ jsx124(DefaultSidebarTabTriggersTunnel.In, { children });
34117
+ return /* @__PURE__ */ jsx125(DefaultSidebarTabTriggersTunnel.In, { children });
33427
34118
  };
33428
34119
  DefaultTabTriggers.displayName = "DefaultTabTriggers";
33429
34120
  var DefaultSidebar = Object.assign(
@@ -33447,7 +34138,7 @@ var DefaultSidebar = Object.assign(
33447
34138
  ...rest,
33448
34139
  name: "default",
33449
34140
  key: "default",
33450
- className: clsx54(
34141
+ className: clsx55(
33451
34142
  "default-sidebar",
33452
34143
  { "default-sidebar--search-only": isSearchSidebar },
33453
34144
  className
@@ -33460,9 +34151,9 @@ var DefaultSidebar = Object.assign(
33460
34151
  onDock?.(nextDocked);
33461
34152
  } : void 0
33462
34153
  },
33463
- /* @__PURE__ */ jsxs64(Sidebar.Tabs, { children: [
33464
- !isSearchSidebar && /* @__PURE__ */ jsx124(Sidebar.Header, {}),
33465
- /* @__PURE__ */ jsx124(Sidebar.Tab, { tab: CANVAS_SEARCH_TAB2, children: /* @__PURE__ */ jsx124(SearchMenu2, {}) }),
34154
+ /* @__PURE__ */ jsxs65(Sidebar.Tabs, { children: [
34155
+ !isSearchSidebar && /* @__PURE__ */ jsx125(Sidebar.Header, {}),
34156
+ /* @__PURE__ */ jsx125(Sidebar.Tab, { tab: CANVAS_SEARCH_TAB2, children: /* @__PURE__ */ jsx125(SearchMenu2, {}) }),
33466
34157
  !isSearchSidebar && children
33467
34158
  ] })
33468
34159
  );
@@ -33475,11 +34166,11 @@ var DefaultSidebar = Object.assign(
33475
34166
  );
33476
34167
 
33477
34168
  // components/JSONExportDialog.tsx
33478
- import React36 from "react";
34169
+ import React37 from "react";
33479
34170
  import { getFrame } from "@excalidraw/common";
33480
34171
 
33481
34172
  // components/Card.tsx
33482
- import { jsx as jsx125 } from "react/jsx-runtime";
34173
+ import { jsx as jsx126 } from "react/jsx-runtime";
33483
34174
  var COLOR_MAP = {
33484
34175
  primary: {
33485
34176
  base: "var(--color-primary)",
@@ -33504,7 +34195,7 @@ var COLOR_MAP = {
33504
34195
  }
33505
34196
  };
33506
34197
  var Card = ({ children, color }) => {
33507
- return /* @__PURE__ */ jsx125(
34198
+ return /* @__PURE__ */ jsx126(
33508
34199
  "div",
33509
34200
  {
33510
34201
  className: "Card",
@@ -33519,7 +34210,7 @@ var Card = ({ children, color }) => {
33519
34210
  };
33520
34211
 
33521
34212
  // components/JSONExportDialog.tsx
33522
- import { Fragment as Fragment22, jsx as jsx126, jsxs as jsxs65 } from "react/jsx-runtime";
34213
+ import { Fragment as Fragment23, jsx as jsx127, jsxs as jsxs66 } from "react/jsx-runtime";
33523
34214
  var JSONExportModal = ({
33524
34215
  elements,
33525
34216
  appState,
@@ -33531,15 +34222,15 @@ var JSONExportModal = ({
33531
34222
  onCloseRequest
33532
34223
  }) => {
33533
34224
  const { onExportToBackend } = exportOpts;
33534
- return /* @__PURE__ */ jsx126("div", { className: "ExportDialog ExportDialog--json", children: /* @__PURE__ */ jsxs65("div", { className: "ExportDialog-cards", children: [
33535
- exportOpts.saveFileToDisk && /* @__PURE__ */ jsxs65(Card, { color: "lime", children: [
33536
- /* @__PURE__ */ jsx126("div", { className: "Card-icon", children: exportToFileIcon }),
33537
- /* @__PURE__ */ jsx126("h2", { children: t("exportDialog.disk_title") }),
33538
- /* @__PURE__ */ jsxs65("div", { className: "Card-details", children: [
34225
+ return /* @__PURE__ */ jsx127("div", { className: "ExportDialog ExportDialog--json", children: /* @__PURE__ */ jsxs66("div", { className: "ExportDialog-cards", children: [
34226
+ exportOpts.saveFileToDisk && /* @__PURE__ */ jsxs66(Card, { color: "lime", children: [
34227
+ /* @__PURE__ */ jsx127("div", { className: "Card-icon", children: exportToFileIcon }),
34228
+ /* @__PURE__ */ jsx127("h2", { children: t("exportDialog.disk_title") }),
34229
+ /* @__PURE__ */ jsxs66("div", { className: "Card-details", children: [
33539
34230
  t("exportDialog.disk_details"),
33540
34231
  !nativeFileSystemSupported && actionManager.renderAction("changeProjectName")
33541
34232
  ] }),
33542
- /* @__PURE__ */ jsx126(
34233
+ /* @__PURE__ */ jsx127(
33543
34234
  IconButton,
33544
34235
  {
33545
34236
  className: "Card-button",
@@ -33553,11 +34244,11 @@ var JSONExportModal = ({
33553
34244
  }
33554
34245
  )
33555
34246
  ] }),
33556
- onExportToBackend && /* @__PURE__ */ jsxs65(Card, { color: "pink", children: [
33557
- /* @__PURE__ */ jsx126("div", { className: "Card-icon", children: LinkIcon }),
33558
- /* @__PURE__ */ jsx126("h2", { children: t("exportDialog.link_title") }),
33559
- /* @__PURE__ */ jsx126("div", { className: "Card-details", children: t("exportDialog.link_details") }),
33560
- /* @__PURE__ */ jsx126(
34247
+ onExportToBackend && /* @__PURE__ */ jsxs66(Card, { color: "pink", children: [
34248
+ /* @__PURE__ */ jsx127("div", { className: "Card-icon", children: LinkIcon }),
34249
+ /* @__PURE__ */ jsx127("h2", { children: t("exportDialog.link_title") }),
34250
+ /* @__PURE__ */ jsx127("div", { className: "Card-details", children: t("exportDialog.link_details") }),
34251
+ /* @__PURE__ */ jsx127(
33561
34252
  IconButton,
33562
34253
  {
33563
34254
  className: "Card-button",
@@ -33589,10 +34280,10 @@ var JSONExportDialog = ({
33589
34280
  canvas,
33590
34281
  setAppState
33591
34282
  }) => {
33592
- const handleClose = React36.useCallback(() => {
34283
+ const handleClose = React37.useCallback(() => {
33593
34284
  setAppState({ openDialog: null });
33594
34285
  }, [setAppState]);
33595
- return /* @__PURE__ */ jsx126(Fragment22, { children: appState.openDialog?.name === "jsonExport" && /* @__PURE__ */ jsx126(Dialog, { onCloseRequest: handleClose, title: t("buttons.export"), children: /* @__PURE__ */ jsx126(
34286
+ return /* @__PURE__ */ jsx127(Fragment23, { children: appState.openDialog?.name === "jsonExport" && /* @__PURE__ */ jsx127(Dialog, { onCloseRequest: handleClose, title: t("buttons.export"), children: /* @__PURE__ */ jsx127(
33596
34287
  JSONExportModal,
33597
34288
  {
33598
34289
  elements,
@@ -33608,13 +34299,13 @@ var JSONExportDialog = ({
33608
34299
  };
33609
34300
 
33610
34301
  // components/LaserPointerButton.tsx
33611
- import clsx55 from "clsx";
33612
- import { jsx as jsx127 } from "react/jsx-runtime";
34302
+ import clsx56 from "clsx";
34303
+ import { jsx as jsx128 } from "react/jsx-runtime";
33613
34304
  var LaserPointerButton = (props) => {
33614
- return /* @__PURE__ */ jsx127(
34305
+ return /* @__PURE__ */ jsx128(
33615
34306
  IconButton,
33616
34307
  {
33617
- className: clsx55("ToolIcon__LaserPointer", {
34308
+ className: clsx56("ToolIcon__LaserPointer", {
33618
34309
  "is-mobile": props.isMobile
33619
34310
  }),
33620
34311
  type: "toggle",
@@ -33630,7 +34321,7 @@ var LaserPointerButton = (props) => {
33630
34321
  };
33631
34322
 
33632
34323
  // components/Toolbar.tsx
33633
- import clsx57 from "clsx";
34324
+ import clsx58 from "clsx";
33634
34325
  import { useState as useState33 } from "react";
33635
34326
  import { CANVAS_SEARCH_TAB as CANVAS_SEARCH_TAB4, DEFAULT_SIDEBAR as DEFAULT_SIDEBAR4, KEYS as KEYS51 } from "@excalidraw/common";
33636
34327
 
@@ -33646,7 +34337,7 @@ import {
33646
34337
  isTextElement as isTextElement17
33647
34338
  } from "@excalidraw/element";
33648
34339
  import { isNodeInFlowchart } from "@excalidraw/element";
33649
- import { jsx as jsx128 } from "react/jsx-runtime";
34340
+ import { jsx as jsx129 } from "react/jsx-runtime";
33650
34341
  var getTaggedShortcutKey = (key) => Array.isArray(key) ? `<kbd>${key.map(getShortcutKey).join(" + ")}</kbd>` : `<kbd>${getShortcutKey(key)}</kbd>`;
33651
34342
  var getHints = ({
33652
34343
  appState,
@@ -33823,21 +34514,21 @@ var HintViewer = ({
33823
34514
  const hintJSX = hint.split(/(<kbd>[^<]+<\/kbd>)/g).map((part, index) => {
33824
34515
  if (index % 2 === 1) {
33825
34516
  const shortcutMatch = part[0] === "<" && part.match(/^<kbd>([^<]+)<\/kbd>$/);
33826
- return /* @__PURE__ */ jsx128("kbd", { children: shortcutMatch ? shortcutMatch[1] : part }, index);
34517
+ return /* @__PURE__ */ jsx129("kbd", { children: shortcutMatch ? shortcutMatch[1] : part }, index);
33827
34518
  }
33828
34519
  return part;
33829
34520
  });
33830
- return /* @__PURE__ */ jsx128("div", { className: "HintViewer", children: /* @__PURE__ */ jsx128("span", { children: hintJSX }) });
34521
+ return /* @__PURE__ */ jsx129("div", { className: "HintViewer", children: /* @__PURE__ */ jsx129("span", { children: hintJSX }) });
33831
34522
  };
33832
34523
 
33833
34524
  // components/LockButton.tsx
33834
- import clsx56 from "clsx";
33835
- import { jsx as jsx129 } from "react/jsx-runtime";
34525
+ import clsx57 from "clsx";
34526
+ import { jsx as jsx130 } from "react/jsx-runtime";
33836
34527
  var LockButton = (props) => {
33837
- return /* @__PURE__ */ jsx129(
34528
+ return /* @__PURE__ */ jsx130(
33838
34529
  IconButton,
33839
34530
  {
33840
- className: clsx56("ToolIcon__lock", { "is-mobile": props.isMobile }),
34531
+ className: clsx57("ToolIcon__lock", { "is-mobile": props.isMobile }),
33841
34532
  type: "toggle",
33842
34533
  icon: props.checked ? LockedIcon : UnlockedIcon,
33843
34534
  checked: props.checked,
@@ -33851,14 +34542,14 @@ var LockButton = (props) => {
33851
34542
  };
33852
34543
 
33853
34544
  // components/Toolbar.tsx
33854
- import { Fragment as Fragment23, jsx as jsx130, jsxs as jsxs66 } from "react/jsx-runtime";
34545
+ import { Fragment as Fragment24, jsx as jsx131, jsxs as jsxs67 } from "react/jsx-runtime";
33855
34546
  var isToolHiddenByOptions = (type, UIOptions) => type === "image" && UIOptions.tools?.image === false;
33856
34547
  var ExtraToolsDropdownItem = ({
33857
34548
  app,
33858
34549
  activeTool,
33859
34550
  type,
33860
34551
  shortcut
33861
- }) => /* @__PURE__ */ jsx130(
34552
+ }) => /* @__PURE__ */ jsx131(
33862
34553
  DropdownMenu_default.Item,
33863
34554
  {
33864
34555
  onSelect: () => app.setActiveTool({ type }),
@@ -33870,7 +34561,7 @@ var ExtraToolsDropdownItem = ({
33870
34561
  children: t(`toolBar.${type}`)
33871
34562
  }
33872
34563
  );
33873
- var LockActiveToolDropdownItem = ({ app }) => /* @__PURE__ */ jsx130(
34564
+ var LockActiveToolDropdownItem = ({ app }) => /* @__PURE__ */ jsx131(
33874
34565
  DropdownMenu_default.Item,
33875
34566
  {
33876
34567
  onSelect: () => app.toggleLock(),
@@ -33889,7 +34580,7 @@ var ObjectsSnapModeDropdownItem = ({
33889
34580
  return null;
33890
34581
  }
33891
34582
  const shortcut = getShortcutFromShortcutName("objectsSnapMode");
33892
- return /* @__PURE__ */ jsx130(
34583
+ return /* @__PURE__ */ jsx131(
33893
34584
  DropdownMenu_default.Item,
33894
34585
  {
33895
34586
  onSelect: () => actionManager.executeAction(actionToggleObjectsSnapMode, "ui"),
@@ -33910,7 +34601,7 @@ var ObjectsSnapModeButton2 = ({
33910
34601
  }
33911
34602
  const label = t("buttons.objectsSnapMode");
33912
34603
  const shortcut = getShortcutFromShortcutName("objectsSnapMode");
33913
- return /* @__PURE__ */ jsx130(
34604
+ return /* @__PURE__ */ jsx131(
33914
34605
  IconButton,
33915
34606
  {
33916
34607
  type: "toggle",
@@ -33930,7 +34621,7 @@ var SearchMenuDropdownItem = ({
33930
34621
  }) => {
33931
34622
  const label = t("search.title");
33932
34623
  const shortcut = getShortcutFromShortcutName("searchMenu");
33933
- return /* @__PURE__ */ jsx130(
34624
+ return /* @__PURE__ */ jsx131(
33934
34625
  DropdownMenu_default.Item,
33935
34626
  {
33936
34627
  onSelect: () => actionManager.executeAction(actionToggleSearchMenu, "ui"),
@@ -33942,7 +34633,7 @@ var SearchMenuDropdownItem = ({
33942
34633
  }
33943
34634
  );
33944
34635
  };
33945
- var StrokeEyeDropperButton2 = ({ app }) => /* @__PURE__ */ jsx130(
34636
+ var StrokeEyeDropperButton2 = ({ app }) => /* @__PURE__ */ jsx131(
33946
34637
  IconButton,
33947
34638
  {
33948
34639
  type: "button",
@@ -33974,11 +34665,11 @@ var ExtraToolsDropdown = ({
33974
34665
  const myocSimplifiedToolSelected = isMyocSimplifiedMode && MYOC_SIMPLIFIED_EXTRA_TOOL_TYPES.includes(
33975
34666
  activeTool.type
33976
34667
  );
33977
- return /* @__PURE__ */ jsxs66(DropdownMenu_default, { open: isExtraToolsMenuOpen, children: [
33978
- /* @__PURE__ */ jsx130(
34668
+ return /* @__PURE__ */ jsxs67(DropdownMenu_default, { open: isExtraToolsMenuOpen, children: [
34669
+ /* @__PURE__ */ jsx131(
33979
34670
  DropdownMenu_default.Trigger,
33980
34671
  {
33981
- className: clsx57("App-toolbar__extra-tools-trigger", {
34672
+ className: clsx58("App-toolbar__extra-tools-trigger", {
33982
34673
  "App-toolbar__extra-tools-trigger--selected": myocSimplifiedToolSelected || frameToolSelected || embeddableToolSelected || !isMyocSimplifiedMode && isFullStylesPanel && drawShapeToolSelected || lassoToolSelected || bucketFillToolSelected || // in collab we're already highlighting the laser button
33983
34674
  // outside toolbar, so let's not highlight extra-tools button
33984
34675
  // on top of it
@@ -33992,14 +34683,14 @@ var ExtraToolsDropdown = ({
33992
34683
  children: myocSimplifiedToolSelected ? TOOLS[activeTool.type].icon : frameToolSelected ? frameToolIcon : embeddableToolSelected ? EmbedIcon : !isMyocSimplifiedMode && isFullStylesPanel && drawShapeToolSelected ? drawShapeToolIcon : laserToolSelected && !app.props.isCollaborating ? laserPointerToolIcon : lassoToolSelected ? LassoIcon : bucketFillToolSelected ? bucketFillIcon : DotsIcon
33993
34684
  }
33994
34685
  ),
33995
- /* @__PURE__ */ jsx130(
34686
+ /* @__PURE__ */ jsx131(
33996
34687
  DropdownMenu_default.Content,
33997
34688
  {
33998
34689
  onClickOutside: () => setIsExtraToolsMenuOpen(false),
33999
34690
  onSelect: () => setIsExtraToolsMenuOpen(false),
34000
34691
  className: "App-toolbar__extra-tools-dropdown",
34001
- children: isMyocSimplifiedMode ? /* @__PURE__ */ jsxs66(Fragment23, { children: [
34002
- isFullStylesPanel && /* @__PURE__ */ jsx130(
34692
+ children: isMyocSimplifiedMode ? /* @__PURE__ */ jsxs67(Fragment24, { children: [
34693
+ isFullStylesPanel && /* @__PURE__ */ jsx131(
34003
34694
  DropdownMenu_default.Item,
34004
34695
  {
34005
34696
  onSelect: () => app.setActiveTool({ type: "lasso" }),
@@ -34012,7 +34703,7 @@ var ExtraToolsDropdown = ({
34012
34703
  ),
34013
34704
  MYOC_SIMPLIFIED_EXTRA_TOOL_TYPES.filter(
34014
34705
  (type) => !isToolHiddenByOptions(type, UIOptions)
34015
- ).map((type) => /* @__PURE__ */ jsx130(
34706
+ ).map((type) => /* @__PURE__ */ jsx131(
34016
34707
  ExtraToolsDropdownItem,
34017
34708
  {
34018
34709
  app,
@@ -34021,17 +34712,17 @@ var ExtraToolsDropdown = ({
34021
34712
  },
34022
34713
  type
34023
34714
  )),
34024
- /* @__PURE__ */ jsx130("div", { className: "App-toolbar__dropdown-divider" }),
34025
- /* @__PURE__ */ jsx130(
34715
+ /* @__PURE__ */ jsx131("div", { className: "App-toolbar__dropdown-divider" }),
34716
+ /* @__PURE__ */ jsx131(
34026
34717
  SearchMenuDropdownItem,
34027
34718
  {
34028
34719
  actionManager,
34029
34720
  appState: app.state
34030
34721
  }
34031
34722
  ),
34032
- app.props.activeTool == null && /* @__PURE__ */ jsx130(Fragment23, { children: /* @__PURE__ */ jsx130(LockActiveToolDropdownItem, { app }) })
34033
- ] }) : /* @__PURE__ */ jsxs66(Fragment23, { children: [
34034
- /* @__PURE__ */ jsx130(
34723
+ app.props.activeTool == null && /* @__PURE__ */ jsx131(Fragment24, { children: /* @__PURE__ */ jsx131(LockActiveToolDropdownItem, { app }) })
34724
+ ] }) : /* @__PURE__ */ jsxs67(Fragment24, { children: [
34725
+ /* @__PURE__ */ jsx131(
34035
34726
  DropdownMenu_default.Item,
34036
34727
  {
34037
34728
  onSelect: () => app.setActiveTool({ type: "frame" }),
@@ -34043,7 +34734,7 @@ var ExtraToolsDropdown = ({
34043
34734
  children: t("toolBar.frame")
34044
34735
  }
34045
34736
  ),
34046
- /* @__PURE__ */ jsx130(
34737
+ /* @__PURE__ */ jsx131(
34047
34738
  DropdownMenu_default.Item,
34048
34739
  {
34049
34740
  onSelect: () => app.setActiveTool({ type: "embeddable" }),
@@ -34054,7 +34745,7 @@ var ExtraToolsDropdown = ({
34054
34745
  children: t("toolBar.embeddable")
34055
34746
  }
34056
34747
  ),
34057
- /* @__PURE__ */ jsx130(
34748
+ /* @__PURE__ */ jsx131(
34058
34749
  DropdownMenu_default.Item,
34059
34750
  {
34060
34751
  onSelect: () => app.setActiveTool({ type: "autoshape" }),
@@ -34066,7 +34757,7 @@ var ExtraToolsDropdown = ({
34066
34757
  children: t("toolBar.autoshape")
34067
34758
  }
34068
34759
  ),
34069
- /* @__PURE__ */ jsx130(
34760
+ /* @__PURE__ */ jsx131(
34070
34761
  DropdownMenu_default.Item,
34071
34762
  {
34072
34763
  onSelect: () => app.setActiveTool({ type: "laser" }),
@@ -34077,7 +34768,7 @@ var ExtraToolsDropdown = ({
34077
34768
  children: t("toolBar.laser")
34078
34769
  }
34079
34770
  ),
34080
- /* @__PURE__ */ jsx130(
34771
+ /* @__PURE__ */ jsx131(
34081
34772
  DropdownMenu_default.Item,
34082
34773
  {
34083
34774
  onSelect: () => app.setActiveTool({ type: "bucketfill" }),
@@ -34088,7 +34779,7 @@ var ExtraToolsDropdown = ({
34088
34779
  children: t("toolBar.bucketfill")
34089
34780
  }
34090
34781
  ),
34091
- isFullStylesPanel && /* @__PURE__ */ jsx130(
34782
+ isFullStylesPanel && /* @__PURE__ */ jsx131(
34092
34783
  DropdownMenu_default.Item,
34093
34784
  {
34094
34785
  onSelect: () => app.setActiveTool({ type: "lasso" }),
@@ -34099,22 +34790,22 @@ var ExtraToolsDropdown = ({
34099
34790
  children: t("toolBar.lasso")
34100
34791
  }
34101
34792
  ),
34102
- /* @__PURE__ */ jsx130("div", { className: "App-toolbar__dropdown-divider" }),
34103
- /* @__PURE__ */ jsx130(
34793
+ /* @__PURE__ */ jsx131("div", { className: "App-toolbar__dropdown-divider" }),
34794
+ /* @__PURE__ */ jsx131(
34104
34795
  ObjectsSnapModeDropdownItem,
34105
34796
  {
34106
34797
  actionManager,
34107
34798
  app
34108
34799
  }
34109
34800
  ),
34110
- /* @__PURE__ */ jsx130(
34801
+ /* @__PURE__ */ jsx131(
34111
34802
  SearchMenuDropdownItem,
34112
34803
  {
34113
34804
  actionManager,
34114
34805
  appState: app.state
34115
34806
  }
34116
34807
  ),
34117
- app.props.activeTool == null && /* @__PURE__ */ jsx130(LockActiveToolDropdownItem, { app })
34808
+ app.props.activeTool == null && /* @__PURE__ */ jsx131(LockActiveToolDropdownItem, { app })
34118
34809
  ] })
34119
34810
  }
34120
34811
  )
@@ -34135,18 +34826,18 @@ var Toolbar = ({
34135
34826
  const activeTool = appState.activeTool;
34136
34827
  const toolProps = { app, activeTool };
34137
34828
  const isMyocSimplifiedMode = appState.myocSimplifiedMode;
34138
- const selectionTool = isCompactStylesPanel ? /* @__PURE__ */ jsx130(SelectionToolPopover, { ...toolProps, setAppState }) : appState.preferredSelectionTool.type === "lasso" ? /* @__PURE__ */ jsx130(LassoToolButton, { ...toolProps }) : /* @__PURE__ */ jsx130(SelectionToolButton, { ...toolProps });
34139
- return /* @__PURE__ */ jsxs66(
34829
+ const selectionTool = isCompactStylesPanel ? /* @__PURE__ */ jsx131(SelectionToolPopover, { ...toolProps, setAppState }) : appState.preferredSelectionTool.type === "lasso" ? /* @__PURE__ */ jsx131(LassoToolButton, { ...toolProps }) : /* @__PURE__ */ jsx131(SelectionToolButton, { ...toolProps });
34830
+ return /* @__PURE__ */ jsxs67(
34140
34831
  Island,
34141
34832
  {
34142
34833
  padding: 1,
34143
- className: clsx57("App-toolbar", {
34834
+ className: clsx58("App-toolbar", {
34144
34835
  "zen-mode": appState.zenModeEnabled,
34145
34836
  "App-toolbar--compact": isCompactStylesPanel
34146
34837
  }),
34147
34838
  "data-viewport-ui": "top",
34148
34839
  children: [
34149
- /* @__PURE__ */ jsx130(
34840
+ /* @__PURE__ */ jsx131(
34150
34841
  HintViewer,
34151
34842
  {
34152
34843
  appState,
@@ -34156,8 +34847,8 @@ var Toolbar = ({
34156
34847
  }
34157
34848
  ),
34158
34849
  heading,
34159
- /* @__PURE__ */ jsxs66(Stack_default.Row, { gap: isCompactStylesPanel ? 0.5 : 1, children: [
34160
- !isCompactStylesPanel && /* @__PURE__ */ jsx130(
34850
+ /* @__PURE__ */ jsxs67(Stack_default.Row, { gap: isCompactStylesPanel ? 0.5 : 1, children: [
34851
+ !isCompactStylesPanel && /* @__PURE__ */ jsx131(
34161
34852
  PenModeButton,
34162
34853
  {
34163
34854
  checked: appState.penMode,
@@ -34166,8 +34857,8 @@ var Toolbar = ({
34166
34857
  penDetected: appState.penDetected
34167
34858
  }
34168
34859
  ),
34169
- app.props.activeTool == null && !isMyocSimplifiedMode && /* @__PURE__ */ jsxs66(Fragment23, { children: [
34170
- /* @__PURE__ */ jsx130(
34860
+ app.props.activeTool == null && !isMyocSimplifiedMode && /* @__PURE__ */ jsxs67(Fragment24, { children: [
34861
+ /* @__PURE__ */ jsx131(
34171
34862
  LockButton,
34172
34863
  {
34173
34864
  checked: appState.activeTool.locked,
@@ -34176,29 +34867,29 @@ var Toolbar = ({
34176
34867
  disabled: app.props.activeTool != null
34177
34868
  }
34178
34869
  ),
34179
- /* @__PURE__ */ jsx130("div", { className: "App-toolbar__divider" })
34870
+ /* @__PURE__ */ jsx131("div", { className: "App-toolbar__divider" })
34180
34871
  ] }),
34181
- /* @__PURE__ */ jsx130(HandToolButton, { ...toolProps }),
34872
+ /* @__PURE__ */ jsx131(HandToolButton, { ...toolProps }),
34182
34873
  selectionTool,
34183
- isMyocSimplifiedMode ? /* @__PURE__ */ jsxs66(Fragment23, { children: [
34184
- /* @__PURE__ */ jsx130(FreedrawToolButton, { ...toolProps }),
34185
- /* @__PURE__ */ jsx130(TextToolButton, { ...toolProps }),
34186
- /* @__PURE__ */ jsx130(StrokeEyeDropperButton2, { app }),
34187
- UIOptions.tools?.image !== false && /* @__PURE__ */ jsx130(ImageToolButton, { ...toolProps }),
34188
- /* @__PURE__ */ jsx130(EraserToolButton, { ...toolProps })
34189
- ] }) : /* @__PURE__ */ jsxs66(Fragment23, { children: [
34190
- /* @__PURE__ */ jsx130(RectangleToolButton, { ...toolProps }),
34191
- /* @__PURE__ */ jsx130(DiamondToolButton, { ...toolProps }),
34192
- /* @__PURE__ */ jsx130(EllipseToolButton, { ...toolProps }),
34193
- /* @__PURE__ */ jsx130(ArrowToolButton, { ...toolProps }),
34194
- /* @__PURE__ */ jsx130(LineToolButton, { ...toolProps }),
34195
- isCompactStylesPanel ? /* @__PURE__ */ jsx130(FreedrawToolPopover, { ...toolProps }) : /* @__PURE__ */ jsx130(FreedrawToolButton, { ...toolProps }),
34196
- /* @__PURE__ */ jsx130(TextToolButton, { ...toolProps }),
34197
- UIOptions.tools?.image !== false && /* @__PURE__ */ jsx130(ImageToolButton, { ...toolProps }),
34198
- /* @__PURE__ */ jsx130(EraserToolButton, { ...toolProps })
34874
+ isMyocSimplifiedMode ? /* @__PURE__ */ jsxs67(Fragment24, { children: [
34875
+ /* @__PURE__ */ jsx131(FreedrawToolButton, { ...toolProps }),
34876
+ /* @__PURE__ */ jsx131(TextToolButton, { ...toolProps }),
34877
+ /* @__PURE__ */ jsx131(StrokeEyeDropperButton2, { app }),
34878
+ UIOptions.tools?.image !== false && /* @__PURE__ */ jsx131(ImageToolButton, { ...toolProps }),
34879
+ /* @__PURE__ */ jsx131(EraserToolButton, { ...toolProps })
34880
+ ] }) : /* @__PURE__ */ jsxs67(Fragment24, { children: [
34881
+ /* @__PURE__ */ jsx131(RectangleToolButton, { ...toolProps }),
34882
+ /* @__PURE__ */ jsx131(DiamondToolButton, { ...toolProps }),
34883
+ /* @__PURE__ */ jsx131(EllipseToolButton, { ...toolProps }),
34884
+ /* @__PURE__ */ jsx131(ArrowToolButton, { ...toolProps }),
34885
+ /* @__PURE__ */ jsx131(LineToolButton, { ...toolProps }),
34886
+ isCompactStylesPanel ? /* @__PURE__ */ jsx131(FreedrawToolPopover, { ...toolProps }) : /* @__PURE__ */ jsx131(FreedrawToolButton, { ...toolProps }),
34887
+ /* @__PURE__ */ jsx131(TextToolButton, { ...toolProps }),
34888
+ UIOptions.tools?.image !== false && /* @__PURE__ */ jsx131(ImageToolButton, { ...toolProps }),
34889
+ /* @__PURE__ */ jsx131(EraserToolButton, { ...toolProps })
34199
34890
  ] }),
34200
- /* @__PURE__ */ jsx130("div", { className: "App-toolbar__divider" }),
34201
- /* @__PURE__ */ jsx130(
34891
+ /* @__PURE__ */ jsx131("div", { className: "App-toolbar__divider" }),
34892
+ /* @__PURE__ */ jsx131(
34202
34893
  ExtraToolsDropdown,
34203
34894
  {
34204
34895
  app,
@@ -34209,9 +34900,9 @@ var Toolbar = ({
34209
34900
  actionManager
34210
34901
  }
34211
34902
  ),
34212
- isMyocSimplifiedMode && /* @__PURE__ */ jsxs66(Fragment23, { children: [
34213
- /* @__PURE__ */ jsx130("div", { className: "App-toolbar__divider" }),
34214
- /* @__PURE__ */ jsx130(ObjectsSnapModeButton2, { actionManager, app })
34903
+ isMyocSimplifiedMode && /* @__PURE__ */ jsxs67(Fragment24, { children: [
34904
+ /* @__PURE__ */ jsx131("div", { className: "App-toolbar__divider" }),
34905
+ /* @__PURE__ */ jsx131(ObjectsSnapModeButton2, { actionManager, app })
34215
34906
  ] })
34216
34907
  ] })
34217
34908
  ]
@@ -34220,26 +34911,26 @@ var Toolbar = ({
34220
34911
  };
34221
34912
 
34222
34913
  // components/LayerUI.tsx
34223
- import { Fragment as Fragment24, jsx as jsx131, jsxs as jsxs67 } from "react/jsx-runtime";
34914
+ import { Fragment as Fragment25, jsx as jsx132, jsxs as jsxs68 } from "react/jsx-runtime";
34224
34915
  var DefaultMainMenu = ({ UIOptions }) => {
34225
- return /* @__PURE__ */ jsxs67(MainMenu_default, { __fallback: true, children: [
34226
- /* @__PURE__ */ jsx131(MainMenu_default.DefaultItems.LoadScene, {}),
34227
- /* @__PURE__ */ jsx131(MainMenu_default.DefaultItems.SaveToActiveFile, {}),
34228
- UIOptions.canvasActions.export && /* @__PURE__ */ jsx131(MainMenu_default.DefaultItems.Export, {}),
34229
- UIOptions.canvasActions.saveAsImage && /* @__PURE__ */ jsx131(MainMenu_default.DefaultItems.SaveAsImage, {}),
34230
- /* @__PURE__ */ jsx131(MainMenu_default.DefaultItems.SearchMenu, {}),
34231
- /* @__PURE__ */ jsx131(MainMenu_default.DefaultItems.Help, {}),
34232
- /* @__PURE__ */ jsx131(MainMenu_default.Separator, {}),
34233
- /* @__PURE__ */ jsx131(MainMenu_default.Group, { title: "Excalidraw links", children: /* @__PURE__ */ jsx131(MainMenu_default.DefaultItems.Socials, {}) }),
34234
- /* @__PURE__ */ jsx131(MainMenu_default.Separator, {}),
34235
- /* @__PURE__ */ jsx131(MainMenu_default.DefaultItems.ToggleTheme, { allowSystemTheme: false }),
34236
- /* @__PURE__ */ jsx131(MainMenu_default.DefaultItems.ChangeCanvasBackground, {})
34916
+ return /* @__PURE__ */ jsxs68(MainMenu_default, { __fallback: true, children: [
34917
+ /* @__PURE__ */ jsx132(MainMenu_default.DefaultItems.LoadScene, {}),
34918
+ /* @__PURE__ */ jsx132(MainMenu_default.DefaultItems.SaveToActiveFile, {}),
34919
+ UIOptions.canvasActions.export && /* @__PURE__ */ jsx132(MainMenu_default.DefaultItems.Export, {}),
34920
+ UIOptions.canvasActions.saveAsImage && /* @__PURE__ */ jsx132(MainMenu_default.DefaultItems.SaveAsImage, {}),
34921
+ /* @__PURE__ */ jsx132(MainMenu_default.DefaultItems.SearchMenu, {}),
34922
+ /* @__PURE__ */ jsx132(MainMenu_default.DefaultItems.Help, {}),
34923
+ /* @__PURE__ */ jsx132(MainMenu_default.Separator, {}),
34924
+ /* @__PURE__ */ jsx132(MainMenu_default.Group, { title: "Excalidraw links", children: /* @__PURE__ */ jsx132(MainMenu_default.DefaultItems.Socials, {}) }),
34925
+ /* @__PURE__ */ jsx132(MainMenu_default.Separator, {}),
34926
+ /* @__PURE__ */ jsx132(MainMenu_default.DefaultItems.ToggleTheme, { allowSystemTheme: false }),
34927
+ /* @__PURE__ */ jsx132(MainMenu_default.DefaultItems.ChangeCanvasBackground, {})
34237
34928
  ] });
34238
34929
  };
34239
34930
  var DefaultOverwriteConfirmDialog = () => {
34240
- return /* @__PURE__ */ jsxs67(OverwriteConfirmDialog, { __fallback: true, children: [
34241
- /* @__PURE__ */ jsx131(OverwriteConfirmDialog.Actions.SaveToDisk, {}),
34242
- /* @__PURE__ */ jsx131(OverwriteConfirmDialog.Actions.ExportToImage, {})
34931
+ return /* @__PURE__ */ jsxs68(OverwriteConfirmDialog, { __fallback: true, children: [
34932
+ /* @__PURE__ */ jsx132(OverwriteConfirmDialog.Actions.SaveToDisk, {}),
34933
+ /* @__PURE__ */ jsx132(OverwriteConfirmDialog.Actions.ExportToImage, {})
34243
34934
  ] });
34244
34935
  };
34245
34936
  var LayerUI = ({
@@ -34293,7 +34984,7 @@ var LayerUI = ({
34293
34984
  if (!UIOptions.canvasActions.export) {
34294
34985
  return null;
34295
34986
  }
34296
- return /* @__PURE__ */ jsx131(
34987
+ return /* @__PURE__ */ jsx132(
34297
34988
  JSONExportDialog,
34298
34989
  {
34299
34990
  elements,
@@ -34310,7 +35001,7 @@ var LayerUI = ({
34310
35001
  if (!UIOptions.canvasActions.saveAsImage || appState.openDialog?.name !== "imageExport") {
34311
35002
  return null;
34312
35003
  }
34313
- return /* @__PURE__ */ jsx131(
35004
+ return /* @__PURE__ */ jsx132(
34314
35005
  ImageExportDialog,
34315
35006
  {
34316
35007
  elements,
@@ -34323,26 +35014,26 @@ var LayerUI = ({
34323
35014
  }
34324
35015
  );
34325
35016
  };
34326
- const renderCanvasActions = () => /* @__PURE__ */ jsxs67("div", { style: { position: "relative" }, children: [
34327
- /* @__PURE__ */ jsxs67("div", { className: "excalidraw-ui-top-left", children: [
35017
+ const renderCanvasActions = () => /* @__PURE__ */ jsxs68("div", { style: { position: "relative" }, children: [
35018
+ /* @__PURE__ */ jsxs68("div", { className: "excalidraw-ui-top-left", children: [
34328
35019
  renderTopLeftUI?.(false, appState),
34329
- /* @__PURE__ */ jsx131(tunnels.MainMenuTunnel.Out, {}),
34330
- /* @__PURE__ */ jsx131(tunnels.DefaultSidebarTriggerTunnel.Out, {})
35020
+ /* @__PURE__ */ jsx132(tunnels.MainMenuTunnel.Out, {}),
35021
+ /* @__PURE__ */ jsx132(tunnels.DefaultSidebarTriggerTunnel.Out, {})
34331
35022
  ] }),
34332
- renderWelcomeScreen && /* @__PURE__ */ jsx131(tunnels.WelcomeScreenMenuHintTunnel.Out, {})
35023
+ renderWelcomeScreen && /* @__PURE__ */ jsx132(tunnels.WelcomeScreenMenuHintTunnel.Out, {})
34333
35024
  ] });
34334
35025
  const renderSelectedShapeActions = () => {
34335
- return /* @__PURE__ */ jsx131(
35026
+ return /* @__PURE__ */ jsx132(
34336
35027
  Section,
34337
35028
  {
34338
35029
  heading: "selectedShapeActions",
34339
- className: clsx58("selected-shape-actions zen-mode-transition", {
35030
+ className: clsx59("selected-shape-actions zen-mode-transition", {
34340
35031
  "transition-left": appState.zenModeEnabled
34341
35032
  }),
34342
- children: isCompactStylesPanel ? /* @__PURE__ */ jsx131(
35033
+ children: isCompactStylesPanel ? /* @__PURE__ */ jsx132(
34343
35034
  Island,
34344
35035
  {
34345
- className: clsx58("compact-shape-actions-island"),
35036
+ className: clsx59("compact-shape-actions-island"),
34346
35037
  padding: 0,
34347
35038
  "data-viewport-ui": "side",
34348
35039
  "data-viewport-ui-name": "stylesPanel",
@@ -34351,7 +35042,7 @@ var LayerUI = ({
34351
35042
  // approximate height of hamburgerMenu + footer
34352
35043
  maxHeight: `${appState.height - 166}px`
34353
35044
  },
34354
- children: /* @__PURE__ */ jsx131(
35045
+ children: /* @__PURE__ */ jsx132(
34355
35046
  CompactShapeActions,
34356
35047
  {
34357
35048
  appState,
@@ -34362,7 +35053,7 @@ var LayerUI = ({
34362
35053
  }
34363
35054
  )
34364
35055
  }
34365
- ) : /* @__PURE__ */ jsx131(
35056
+ ) : /* @__PURE__ */ jsx132(
34366
35057
  Island,
34367
35058
  {
34368
35059
  className: CLASSES9.SHAPE_ACTIONS_MENU,
@@ -34374,7 +35065,7 @@ var LayerUI = ({
34374
35065
  },
34375
35066
  "data-viewport-ui": "side",
34376
35067
  "data-viewport-ui-name": "stylesPanel",
34377
- children: /* @__PURE__ */ jsx131(
35068
+ children: /* @__PURE__ */ jsx132(
34378
35069
  SelectedShapeActions,
34379
35070
  {
34380
35071
  appState,
@@ -34391,24 +35082,24 @@ var LayerUI = ({
34391
35082
  const renderFixedSideContainer = () => {
34392
35083
  const shouldRenderSelectedShapeActions = defaultUIEnabled && showSelectedShapeActions(appState, elements);
34393
35084
  const shouldShowStats = defaultUIEnabled && appState.stats.open && !appState.zenModeEnabled && !appState.viewModeEnabled && appState.openDialog?.name !== "elementLinkSelector";
34394
- return /* @__PURE__ */ jsx131(FixedSideContainer, { side: "top", children: /* @__PURE__ */ jsxs67("div", { className: "App-menu App-menu_top", children: [
34395
- /* @__PURE__ */ jsxs67(
35085
+ return /* @__PURE__ */ jsx132(FixedSideContainer, { side: "top", children: /* @__PURE__ */ jsxs68("div", { className: "App-menu App-menu_top", children: [
35086
+ /* @__PURE__ */ jsxs68(
34396
35087
  Stack_default.Col,
34397
35088
  {
34398
35089
  gap: spacing.menuTopGap,
34399
- className: clsx58("App-menu_top__left"),
35090
+ className: clsx59("App-menu_top__left"),
34400
35091
  children: [
34401
35092
  renderCanvasActions(),
34402
- defaultUIEnabled && /* @__PURE__ */ jsx131(
35093
+ defaultUIEnabled && /* @__PURE__ */ jsx132(
34403
35094
  "div",
34404
35095
  {
34405
- className: clsx58("selected-shape-actions-container", {
35096
+ className: clsx59("selected-shape-actions-container", {
34406
35097
  "selected-shape-actions-container--compact": isCompactStylesPanel
34407
35098
  }),
34408
35099
  children: shouldRenderSelectedShapeActions && renderSelectedShapeActions()
34409
35100
  }
34410
35101
  ),
34411
- defaultUIEnabled && isCompactStylesPanel && !appState.viewModeEnabled && shouldRenderSelectedShapeActions && /* @__PURE__ */ jsx131(
35102
+ defaultUIEnabled && isCompactStylesPanel && !appState.viewModeEnabled && shouldRenderSelectedShapeActions && /* @__PURE__ */ jsx132(
34412
35103
  PenModeButton,
34413
35104
  {
34414
35105
  checked: appState.penMode,
@@ -34421,17 +35112,17 @@ var LayerUI = ({
34421
35112
  ]
34422
35113
  }
34423
35114
  ),
34424
- defaultUIEnabled && !appState.viewModeEnabled && appState.openDialog?.name !== "elementLinkSelector" && /* @__PURE__ */ jsx131(Section, { heading: "shapes", className: "shapes-section", children: (heading) => /* @__PURE__ */ jsxs67("div", { style: { position: "relative" }, children: [
34425
- renderWelcomeScreen && /* @__PURE__ */ jsx131(tunnels.WelcomeScreenToolbarHintTunnel.Out, {}),
34426
- /* @__PURE__ */ jsx131(Stack_default.Col, { gap: spacing.toolbarColGap, align: "start", children: /* @__PURE__ */ jsxs67(
35115
+ defaultUIEnabled && !appState.viewModeEnabled && appState.openDialog?.name !== "elementLinkSelector" && /* @__PURE__ */ jsx132(Section, { heading: "shapes", className: "shapes-section", children: (heading) => /* @__PURE__ */ jsxs68("div", { style: { position: "relative" }, children: [
35116
+ renderWelcomeScreen && /* @__PURE__ */ jsx132(tunnels.WelcomeScreenToolbarHintTunnel.Out, {}),
35117
+ /* @__PURE__ */ jsx132(Stack_default.Col, { gap: spacing.toolbarColGap, align: "start", children: /* @__PURE__ */ jsxs68(
34427
35118
  Stack_default.Row,
34428
35119
  {
34429
35120
  gap: spacing.toolbarRowGap,
34430
- className: clsx58("App-toolbar-container", {
35121
+ className: clsx59("App-toolbar-container", {
34431
35122
  "zen-mode": appState.zenModeEnabled
34432
35123
  }),
34433
35124
  children: [
34434
- /* @__PURE__ */ jsx131(
35125
+ /* @__PURE__ */ jsx132(
34435
35126
  Toolbar,
34436
35127
  {
34437
35128
  app,
@@ -34444,7 +35135,7 @@ var LayerUI = ({
34444
35135
  heading
34445
35136
  }
34446
35137
  ),
34447
- isCollaborating && /* @__PURE__ */ jsx131(
35138
+ isCollaborating && /* @__PURE__ */ jsx132(
34448
35139
  Island,
34449
35140
  {
34450
35141
  style: {
@@ -34452,7 +35143,7 @@ var LayerUI = ({
34452
35143
  alignSelf: "center",
34453
35144
  height: "fit-content"
34454
35145
  },
34455
- children: /* @__PURE__ */ jsx131(
35146
+ children: /* @__PURE__ */ jsx132(
34456
35147
  LaserPointerButton,
34457
35148
  {
34458
35149
  title: t("toolBar.laser"),
@@ -34467,10 +35158,10 @@ var LayerUI = ({
34467
35158
  }
34468
35159
  ) })
34469
35160
  ] }) }),
34470
- /* @__PURE__ */ jsxs67(
35161
+ /* @__PURE__ */ jsxs68(
34471
35162
  "div",
34472
35163
  {
34473
- className: clsx58(
35164
+ className: clsx59(
34474
35165
  "layer-ui__wrapper__top-right zen-mode-transition",
34475
35166
  {
34476
35167
  "transition-right": appState.zenModeEnabled,
@@ -34478,7 +35169,7 @@ var LayerUI = ({
34478
35169
  }
34479
35170
  ),
34480
35171
  children: [
34481
- defaultUIEnabled && appState.collaborators.size > 0 && /* @__PURE__ */ jsx131(
35172
+ defaultUIEnabled && appState.collaborators.size > 0 && /* @__PURE__ */ jsx132(
34482
35173
  UserList,
34483
35174
  {
34484
35175
  collaborators: appState.collaborators,
@@ -34490,7 +35181,7 @@ var LayerUI = ({
34490
35181
  editorInterface.formFactor === "phone",
34491
35182
  appState
34492
35183
  ),
34493
- shouldShowStats && /* @__PURE__ */ jsx131(
35184
+ shouldShowStats && /* @__PURE__ */ jsx132(
34494
35185
  Stats,
34495
35186
  {
34496
35187
  app,
@@ -34505,15 +35196,15 @@ var LayerUI = ({
34505
35196
  )
34506
35197
  ] }) });
34507
35198
  };
34508
- const renderSidebars = () => /* @__PURE__ */ jsx131(DefaultSidebar, {});
35199
+ const renderSidebars = () => /* @__PURE__ */ jsx132(DefaultSidebar, {});
34509
35200
  const isSidebarDockedAndFits = false;
34510
- const layerUIJSX = /* @__PURE__ */ jsxs67(Fragment24, { children: [
35201
+ const layerUIJSX = /* @__PURE__ */ jsxs68(Fragment25, { children: [
34511
35202
  children,
34512
- defaultUIEnabled && /* @__PURE__ */ jsx131(Fragment24, { children: /* @__PURE__ */ jsx131(DefaultMainMenu, { UIOptions }) }),
34513
- /* @__PURE__ */ jsx131(DefaultOverwriteConfirmDialog, {}),
34514
- defaultUIEnabled && appState.isLoading && /* @__PURE__ */ jsx131(LoadingMessage, { delay: 250 }),
34515
- defaultUIEnabled && appState.errorMessage && /* @__PURE__ */ jsx131(ErrorDialog, { onClose: () => setAppState({ errorMessage: null }), children: appState.errorMessage }),
34516
- defaultUIEnabled && eyeDropperState && editorInterface.formFactor !== "phone" && /* @__PURE__ */ jsx131(
35203
+ defaultUIEnabled && /* @__PURE__ */ jsx132(Fragment25, { children: /* @__PURE__ */ jsx132(DefaultMainMenu, { UIOptions }) }),
35204
+ /* @__PURE__ */ jsx132(DefaultOverwriteConfirmDialog, {}),
35205
+ defaultUIEnabled && appState.isLoading && /* @__PURE__ */ jsx132(LoadingMessage, { delay: 250 }),
35206
+ defaultUIEnabled && appState.errorMessage && /* @__PURE__ */ jsx132(ErrorDialog, { onClose: () => setAppState({ errorMessage: null }), children: appState.errorMessage }),
35207
+ defaultUIEnabled && eyeDropperState && editorInterface.formFactor !== "phone" && /* @__PURE__ */ jsx132(
34517
35208
  EyeDropper,
34518
35209
  {
34519
35210
  colorPickerType: eyeDropperState.colorPickerType,
@@ -34529,7 +35220,7 @@ var LayerUI = ({
34529
35220
  mutateElement6(element, arrayToMap33(elements), {
34530
35221
  [altKey && eyeDropperState.swapPreviewOnAlt ? colorPickerType === "elementBackground" ? "strokeColor" : "backgroundColor" : colorPickerType === "elementBackground" ? "backgroundColor" : "strokeColor"]: color
34531
35222
  });
34532
- ShapeCache4.delete(element);
35223
+ ShapeCache6.delete(element);
34533
35224
  }
34534
35225
  app.scene.triggerUpdate();
34535
35226
  } else if (colorPickerType === "elementBackground") {
@@ -34548,7 +35239,7 @@ var LayerUI = ({
34548
35239
  }
34549
35240
  }
34550
35241
  ),
34551
- appState.openDialog?.name === "help" && /* @__PURE__ */ jsx131(
35242
+ appState.openDialog?.name === "help" && /* @__PURE__ */ jsx132(
34552
35243
  HelpDialog,
34553
35244
  {
34554
35245
  onClose: () => {
@@ -34556,7 +35247,7 @@ var LayerUI = ({
34556
35247
  }
34557
35248
  }
34558
35249
  ),
34559
- defaultUIEnabled && appState.openDialog?.name === "elementLinkSelector" && /* @__PURE__ */ jsx131(
35250
+ defaultUIEnabled && appState.openDialog?.name === "elementLinkSelector" && /* @__PURE__ */ jsx132(
34560
35251
  ElementLinkDialog_default,
34561
35252
  {
34562
35253
  sourceElementId: appState.openDialog.sourceElementId,
@@ -34570,10 +35261,10 @@ var LayerUI = ({
34570
35261
  generateLinkForSelection
34571
35262
  }
34572
35263
  ),
34573
- /* @__PURE__ */ jsx131(tunnels.OverwriteConfirmDialogTunnel.Out, {}),
35264
+ /* @__PURE__ */ jsx132(tunnels.OverwriteConfirmDialogTunnel.Out, {}),
34574
35265
  renderImageExportDialog(),
34575
35266
  renderJSONExportDialog(),
34576
- defaultUIEnabled && appState.openDialog?.name === "charts" && /* @__PURE__ */ jsx131(
35267
+ defaultUIEnabled && appState.openDialog?.name === "charts" && /* @__PURE__ */ jsx132(
34577
35268
  PasteChartDialog,
34578
35269
  {
34579
35270
  data: appState.openDialog.data,
@@ -34583,7 +35274,15 @@ var LayerUI = ({
34583
35274
  })
34584
35275
  }
34585
35276
  ),
34586
- editorInterface.formFactor === "phone" && /* @__PURE__ */ jsx131(
35277
+ defaultUIEnabled && /* @__PURE__ */ jsx132(
35278
+ GifPlaybackControls,
35279
+ {
35280
+ app,
35281
+ files,
35282
+ setAppState
35283
+ }
35284
+ ),
35285
+ editorInterface.formFactor === "phone" && /* @__PURE__ */ jsx132(
34587
35286
  MobileMenu,
34588
35287
  {
34589
35288
  app,
@@ -34602,8 +35301,8 @@ var LayerUI = ({
34602
35301
  scrollBackToContentUIEnabled
34603
35302
  }
34604
35303
  ),
34605
- editorInterface.formFactor !== "phone" && /* @__PURE__ */ jsxs67(Fragment24, { children: [
34606
- appProps.viewportStatusFrame?.border && /* @__PURE__ */ jsx131(
35304
+ editorInterface.formFactor !== "phone" && /* @__PURE__ */ jsxs68(Fragment25, { children: [
35305
+ appProps.viewportStatusFrame?.border && /* @__PURE__ */ jsx132(
34607
35306
  ViewportStatusBorder,
34608
35307
  {
34609
35308
  border: appProps.viewportStatusFrame.border,
@@ -34615,15 +35314,15 @@ var LayerUI = ({
34615
35314
  } : void 0
34616
35315
  }
34617
35316
  ),
34618
- /* @__PURE__ */ jsxs67(
35317
+ /* @__PURE__ */ jsxs68(
34619
35318
  "div",
34620
35319
  {
34621
35320
  className: "layer-ui__wrapper",
34622
35321
  style: isSidebarDockedAndFits ? { width: `calc(100% - var(--right-sidebar-width))` } : {},
34623
35322
  children: [
34624
- renderWelcomeScreen && /* @__PURE__ */ jsx131(tunnels.WelcomeScreenCenterTunnel.Out, {}),
35323
+ renderWelcomeScreen && /* @__PURE__ */ jsx132(tunnels.WelcomeScreenCenterTunnel.Out, {}),
34625
35324
  renderFixedSideContainer(),
34626
- /* @__PURE__ */ jsx131(
35325
+ /* @__PURE__ */ jsx132(
34627
35326
  Footer_default,
34628
35327
  {
34629
35328
  appState,
@@ -34634,8 +35333,8 @@ var LayerUI = ({
34634
35333
  zoomUIEnabled
34635
35334
  }
34636
35335
  ),
34637
- (appState.toast || scrollBackToContentUIEnabled && appState.scrolledOutside || appProps.viewportStatusFrame?.label) && /* @__PURE__ */ jsxs67("div", { className: "floating-status-stack", children: [
34638
- appState.toast && /* @__PURE__ */ jsx131(
35336
+ (appState.toast || scrollBackToContentUIEnabled && appState.scrolledOutside || appProps.viewportStatusFrame?.label) && /* @__PURE__ */ jsxs68("div", { className: "floating-status-stack", children: [
35337
+ appState.toast && /* @__PURE__ */ jsx132(
34639
35338
  Toast,
34640
35339
  {
34641
35340
  message: appState.toast.message,
@@ -34644,7 +35343,7 @@ var LayerUI = ({
34644
35343
  closable: appState.toast.closable
34645
35344
  }
34646
35345
  ),
34647
- !appState.toast && scrollBackToContentUIEnabled && appState.scrolledOutside && /* @__PURE__ */ jsx131(
35346
+ !appState.toast && scrollBackToContentUIEnabled && appState.scrolledOutside && /* @__PURE__ */ jsx132(
34648
35347
  "button",
34649
35348
  {
34650
35349
  type: "button",
@@ -34657,7 +35356,7 @@ var LayerUI = ({
34657
35356
  children: t("buttons.scrollBackToContent")
34658
35357
  }
34659
35358
  ),
34660
- appProps.viewportStatusFrame?.label && /* @__PURE__ */ jsx131(
35359
+ appProps.viewportStatusFrame?.label && /* @__PURE__ */ jsx132(
34661
35360
  ViewportStatusBadge,
34662
35361
  {
34663
35362
  label: appProps.viewportStatusFrame.label,
@@ -34671,7 +35370,7 @@ var LayerUI = ({
34671
35370
  ] }),
34672
35371
  renderSidebars()
34673
35372
  ] });
34674
- return /* @__PURE__ */ jsx131(UIAppStateContext.Provider, { value: appState, children: /* @__PURE__ */ jsx131(TunnelsJotaiProvider, { children: /* @__PURE__ */ jsx131(TunnelsContext.Provider, { value: tunnels, children: layerUIJSX }) }) });
35373
+ return /* @__PURE__ */ jsx132(UIAppStateContext.Provider, { value: appState, children: /* @__PURE__ */ jsx132(TunnelsJotaiProvider, { children: /* @__PURE__ */ jsx132(TunnelsContext.Provider, { value: tunnels, children: layerUIJSX }) }) });
34675
35374
  };
34676
35375
  var stripIrrelevantAppStateProps = (appState) => {
34677
35376
  const {
@@ -34706,11 +35405,11 @@ var areEqual2 = (prevProps, nextProps) => {
34706
35405
  }
34707
35406
  ) && isShallowEqual6(prev, next);
34708
35407
  };
34709
- var LayerUI_default = React37.memo(LayerUI, areEqual2);
35408
+ var LayerUI_default = React38.memo(LayerUI, areEqual2);
34710
35409
 
34711
35410
  // components/SVGLayer.tsx
34712
35411
  import { useEffect as useEffect34, useRef as useRef28 } from "react";
34713
- import { jsx as jsx132 } from "react/jsx-runtime";
35412
+ import { jsx as jsx133 } from "react/jsx-runtime";
34714
35413
  var SVGLayer = ({ trails }) => {
34715
35414
  const svgRef = useRef28(null);
34716
35415
  useEffect34(() => {
@@ -34725,16 +35424,16 @@ var SVGLayer = ({ trails }) => {
34725
35424
  }
34726
35425
  };
34727
35426
  }, trails);
34728
- return /* @__PURE__ */ jsx132("div", { className: "SVGLayer", children: /* @__PURE__ */ jsx132("svg", { ref: svgRef }) });
35427
+ return /* @__PURE__ */ jsx133("div", { className: "SVGLayer", children: /* @__PURE__ */ jsx133("svg", { ref: svgRef }) });
34729
35428
  };
34730
35429
 
34731
35430
  // components/canvases/InteractiveCanvas.tsx
34732
- import React38, { useEffect as useEffect35, useRef as useRef29 } from "react";
35431
+ import React39, { useEffect as useEffect35, useRef as useRef29 } from "react";
34733
35432
  import {
34734
35433
  isShallowEqual as isShallowEqual7,
34735
- sceneCoordsToViewportCoords as sceneCoordsToViewportCoords4
35434
+ sceneCoordsToViewportCoords as sceneCoordsToViewportCoords5
34736
35435
  } from "@excalidraw/common";
34737
- import { jsx as jsx133 } from "react/jsx-runtime";
35436
+ import { jsx as jsx134 } from "react/jsx-runtime";
34738
35437
  var INTERACTIVE_SCENE_ANIMATION_KEY = "animateInteractiveScene";
34739
35438
  var InteractiveCanvas = (props) => {
34740
35439
  const isComponentMounted = useRef29(false);
@@ -34797,7 +35496,7 @@ var InteractiveCanvas = (props) => {
34797
35496
  }
34798
35497
  remotePointerViewportCoords.set(
34799
35498
  socketId,
34800
- sceneCoordsToViewportCoords4(
35499
+ sceneCoordsToViewportCoords5(
34801
35500
  {
34802
35501
  sceneX: user.pointer.x,
34803
35502
  sceneY: user.pointer.y
@@ -34858,7 +35557,7 @@ var InteractiveCanvas = (props) => {
34858
35557
  );
34859
35558
  }
34860
35559
  });
34861
- return /* @__PURE__ */ jsx133(
35560
+ return /* @__PURE__ */ jsx134(
34862
35561
  "canvas",
34863
35562
  {
34864
35563
  className: "excalidraw__canvas interactive",
@@ -34938,12 +35637,13 @@ var areEqual3 = (prevProps, nextProps) => {
34938
35637
  getRelevantAppStateProps(nextProps.appState)
34939
35638
  );
34940
35639
  };
34941
- var InteractiveCanvas_default = React38.memo(InteractiveCanvas, areEqual3);
35640
+ var InteractiveCanvas_default = React39.memo(InteractiveCanvas, areEqual3);
34942
35641
 
34943
35642
  // components/canvases/StaticCanvas.tsx
34944
- import React39, { useEffect as useEffect36, useRef as useRef30 } from "react";
35643
+ import React40, { useEffect as useEffect36, useRef as useRef30 } from "react";
34945
35644
  import { isShallowEqual as isShallowEqual8 } from "@excalidraw/common";
34946
- import { jsx as jsx134 } from "react/jsx-runtime";
35645
+ import { hasActiveGifDecode } from "@excalidraw/element";
35646
+ import { jsx as jsx135 } from "react/jsx-runtime";
34947
35647
  var StaticCanvas = (props) => {
34948
35648
  const wrapperRef = useRef30(null);
34949
35649
  const isComponentMounted = useRef30(false);
@@ -34952,7 +35652,7 @@ var StaticCanvas = (props) => {
34952
35652
  });
34953
35653
  const transitionFrameRef = useRef30(null);
34954
35654
  propsRef.current = props;
34955
- const renderCanvas = React39.useCallback(() => {
35655
+ const renderCanvas = React40.useCallback(() => {
34956
35656
  const currentProps = propsRef.current;
34957
35657
  const wrapper = wrapperRef.current;
34958
35658
  if (!wrapper) {
@@ -34987,7 +35687,11 @@ var StaticCanvas = (props) => {
34987
35687
  )?.transitionStart;
34988
35688
  return transitionStart !== void 0 && performance.now() - transitionStart < transitionDuration;
34989
35689
  });
34990
- if (hasActiveTransition && transitionFrameRef.current === null) {
35690
+ const hasActiveGifDecodeInRender = hasActiveGifDecode(
35691
+ currentProps.visibleElements,
35692
+ currentProps.renderConfig.imageCache
35693
+ );
35694
+ if ((hasActiveTransition || hasActiveGifDecodeInRender) && transitionFrameRef.current === null) {
34991
35695
  transitionFrameRef.current = requestAnimationFrame(() => {
34992
35696
  transitionFrameRef.current = null;
34993
35697
  renderCanvasRef.current();
@@ -35040,7 +35744,7 @@ var StaticCanvas = (props) => {
35040
35744
  },
35041
35745
  []
35042
35746
  );
35043
- return /* @__PURE__ */ jsx134("div", { className: "excalidraw__canvas-wrapper", ref: wrapperRef });
35747
+ return /* @__PURE__ */ jsx135("div", { className: "excalidraw__canvas-wrapper", ref: wrapperRef });
35044
35748
  };
35045
35749
  var getRelevantAppStateProps2 = (appState) => {
35046
35750
  const relevantAppStateProps = {
@@ -35085,7 +35789,7 @@ var areEqual4 = (prevProps, nextProps) => {
35085
35789
  getRelevantAppStateProps2(nextProps.appState)
35086
35790
  ) && isShallowEqual8(prevProps.renderConfig, nextProps.renderConfig);
35087
35791
  };
35088
- var StaticCanvas_default = React39.memo(StaticCanvas, areEqual4);
35792
+ var StaticCanvas_default = React40.memo(StaticCanvas, areEqual4);
35089
35793
 
35090
35794
  // components/canvases/NewElementCanvas.tsx
35091
35795
  import { useEffect as useEffect37, useRef as useRef31 } from "react";
@@ -35162,7 +35866,7 @@ var renderNewElementScene = (renderConfig, throttle5) => {
35162
35866
  };
35163
35867
 
35164
35868
  // components/canvases/NewElementCanvas.tsx
35165
- import { jsx as jsx135 } from "react/jsx-runtime";
35869
+ import { jsx as jsx136 } from "react/jsx-runtime";
35166
35870
  var NewElementCanvas = (props) => {
35167
35871
  const canvasRef = useRef31(null);
35168
35872
  useEffect37(() => {
@@ -35183,7 +35887,7 @@ var NewElementCanvas = (props) => {
35183
35887
  isRenderThrottlingEnabled()
35184
35888
  );
35185
35889
  });
35186
- return /* @__PURE__ */ jsx135(
35890
+ return /* @__PURE__ */ jsx136(
35187
35891
  "canvas",
35188
35892
  {
35189
35893
  className: "excalidraw__canvas",
@@ -35200,10 +35904,10 @@ var NewElementCanvas = (props) => {
35200
35904
  var NewElementCanvas_default = NewElementCanvas;
35201
35905
 
35202
35906
  // components/CursorHint.tsx
35203
- import clsx59 from "clsx";
35907
+ import clsx60 from "clsx";
35204
35908
  import { useLayoutEffect as useLayoutEffect10, useEffect as useEffect38, useRef as useRef32, useState as useState34 } from "react";
35205
35909
  import { ARROW_TYPE as ARROW_TYPE2, EVENT as EVENT10 } from "@excalidraw/common";
35206
- import { jsx as jsx136 } from "react/jsx-runtime";
35910
+ import { jsx as jsx137 } from "react/jsx-runtime";
35207
35911
  var CURSOR_HINT_DURATION = 700;
35208
35912
  var CURSOR_HINT_FADE_DURATION = 100;
35209
35913
  var CURSOR_HINT_GAP = 16;
@@ -35315,11 +36019,11 @@ var CursorHint = () => {
35315
36019
  if (!hint) {
35316
36020
  return null;
35317
36021
  }
35318
- return /* @__PURE__ */ jsx136(
36022
+ return /* @__PURE__ */ jsx137(
35319
36023
  "div",
35320
36024
  {
35321
36025
  ref: hintRef,
35322
- className: clsx59("CursorHint", {
36026
+ className: clsx60("CursorHint", {
35323
36027
  "CursorHint--fade-out": isFadingOut
35324
36028
  }),
35325
36029
  "data-testid": "cursor-hint",
@@ -35446,14 +36150,14 @@ var AppStateObserver = class {
35446
36150
 
35447
36151
  // components/UnlockPopup.tsx
35448
36152
  import {
35449
- getCommonBounds as getCommonBounds12,
36153
+ getCommonBounds as getCommonBounds13,
35450
36154
  getElementsInGroup as getElementsInGroup11,
35451
36155
  isNonDeletedElement as isNonDeletedElement5,
35452
36156
  selectGroupsFromGivenElements as selectGroupsFromGivenElements4
35453
36157
  } from "@excalidraw/element";
35454
- import { sceneCoordsToViewportCoords as sceneCoordsToViewportCoords5 } from "@excalidraw/common";
36158
+ import { sceneCoordsToViewportCoords as sceneCoordsToViewportCoords6 } from "@excalidraw/common";
35455
36159
  import { flushSync } from "react-dom";
35456
- import { jsx as jsx137 } from "react/jsx-runtime";
36160
+ import { jsx as jsx138 } from "react/jsx-runtime";
35457
36161
  var UnlockPopup = ({
35458
36162
  app,
35459
36163
  activeLockedId
@@ -35472,12 +36176,12 @@ var UnlockPopup = ({
35472
36176
  if (elements.length === 0) {
35473
36177
  return null;
35474
36178
  }
35475
- const [x, y] = getCommonBounds12(elements);
35476
- const { x: viewX, y: viewY } = sceneCoordsToViewportCoords5(
36179
+ const [x, y] = getCommonBounds13(elements);
36180
+ const { x: viewX, y: viewY } = sceneCoordsToViewportCoords6(
35477
36181
  { sceneX: x, sceneY: y },
35478
36182
  app.state
35479
36183
  );
35480
- return /* @__PURE__ */ jsx137(
36184
+ return /* @__PURE__ */ jsx138(
35481
36185
  "div",
35482
36186
  {
35483
36187
  className: "UnlockPopup",
@@ -35510,9 +36214,9 @@ var UnlockPopup = ({
35510
36214
  var UnlockPopup_default = UnlockPopup;
35511
36215
 
35512
36216
  // components/App.tsx
35513
- import { Fragment as Fragment25, jsx as jsx138, jsxs as jsxs68 } from "react/jsx-runtime";
35514
- var AppContext = React40.createContext(null);
35515
- var AppPropsContext = React40.createContext(null);
36217
+ import { Fragment as Fragment26, jsx as jsx139, jsxs as jsxs69 } from "react/jsx-runtime";
36218
+ var AppContext = React41.createContext(null);
36219
+ var AppPropsContext = React41.createContext(null);
35516
36220
  var editorInterfaceContextInitialValue = {
35517
36221
  formFactor: "desktop",
35518
36222
  desktopUIMode: "full",
@@ -35523,7 +36227,7 @@ var editorInterfaceContextInitialValue = {
35523
36227
  canFitSidebar: false,
35524
36228
  isLandscape: true
35525
36229
  };
35526
- var EditorInterfaceContext = React40.createContext(
36230
+ var EditorInterfaceContext = React41.createContext(
35527
36231
  editorInterfaceContextInitialValue
35528
36232
  );
35529
36233
  EditorInterfaceContext.displayName = "EditorInterfaceContext";
@@ -35532,11 +36236,11 @@ var editorLifecycleEventBehavior = {
35532
36236
  "editor:initialize": { cardinality: "once", replay: "last" },
35533
36237
  "editor:unmount": { cardinality: "once", replay: "last" }
35534
36238
  };
35535
- var ExcalidrawContainerContext = React40.createContext({ container: null, id: null });
36239
+ var ExcalidrawContainerContext = React41.createContext({ container: null, id: null });
35536
36240
  ExcalidrawContainerContext.displayName = "ExcalidrawContainerContext";
35537
- var ExcalidrawElementsContext = React40.createContext([]);
36241
+ var ExcalidrawElementsContext = React41.createContext([]);
35538
36242
  ExcalidrawElementsContext.displayName = "ExcalidrawElementsContext";
35539
- var ExcalidrawAppStateContext = React40.createContext({
36243
+ var ExcalidrawAppStateContext = React41.createContext({
35540
36244
  ...getDefaultAppState(),
35541
36245
  width: 0,
35542
36246
  height: 0,
@@ -35544,17 +36248,17 @@ var ExcalidrawAppStateContext = React40.createContext({
35544
36248
  offsetTop: 0
35545
36249
  });
35546
36250
  ExcalidrawAppStateContext.displayName = "ExcalidrawAppStateContext";
35547
- var ExcalidrawSetAppStateContext = React40.createContext(() => {
36251
+ var ExcalidrawSetAppStateContext = React41.createContext(() => {
35548
36252
  console.warn("Uninitialized ExcalidrawSetAppStateContext context!");
35549
36253
  });
35550
36254
  ExcalidrawSetAppStateContext.displayName = "ExcalidrawSetAppStateContext";
35551
- var ExcalidrawActionManagerContext = React40.createContext(
36255
+ var ExcalidrawActionManagerContext = React41.createContext(
35552
36256
  null
35553
36257
  );
35554
36258
  ExcalidrawActionManagerContext.displayName = "ExcalidrawActionManagerContext";
35555
- var ExcalidrawAPIContext = React40.createContext(null);
36259
+ var ExcalidrawAPIContext = React41.createContext(null);
35556
36260
  ExcalidrawAPIContext.displayName = "ExcalidrawAPIContext";
35557
- var ExcalidrawAPISetContext = React40.createContext(null);
36261
+ var ExcalidrawAPISetContext = React41.createContext(null);
35558
36262
  ExcalidrawAPISetContext.displayName = "ExcalidrawAPISetContext";
35559
36263
  var useApp = () => useContext4(AppContext);
35560
36264
  var useAppProps = () => useContext4(AppPropsContext);
@@ -35588,7 +36292,7 @@ var gesture = {
35588
36292
  initialDistance: null,
35589
36293
  initialScale: null
35590
36294
  };
35591
- var App = class _App extends React40.Component {
36295
+ var App = class _App extends React41.Component {
35592
36296
  constructor(props) {
35593
36297
  super(props);
35594
36298
  __publicField(this, "canvas");
@@ -35601,7 +36305,7 @@ var App = class _App extends React40.Component {
35601
36305
  __publicField(this, "stylesPanelMode", deriveStylesPanelMode2(
35602
36306
  editorInterfaceContextInitialValue
35603
36307
  ));
35604
- __publicField(this, "excalidrawContainerRef", React40.createRef());
36308
+ __publicField(this, "excalidrawContainerRef", React41.createRef());
35605
36309
  __publicField(this, "scene");
35606
36310
  __publicField(this, "fonts");
35607
36311
  __publicField(this, "renderer");
@@ -35643,6 +36347,7 @@ var App = class _App extends React40.Component {
35643
36347
  __publicField(this, "bucketFill", new AppBucketFill(this));
35644
36348
  __publicField(this, "flowchart", new AppFlowchart(this));
35645
36349
  __publicField(this, "cursor", new AppCursor(this));
36350
+ __publicField(this, "gifPlayback", new AppGifPlayback(this));
35646
36351
  __publicField(this, "zDragZoom", null);
35647
36352
  __publicField(this, "arrowText", new AppArrowText(this));
35648
36353
  __publicField(this, "viewport", new AppViewport(this, {
@@ -35763,7 +36468,7 @@ var App = class _App extends React40.Component {
35763
36468
  });
35764
36469
  __publicField(this, "updateEmbedValidationStatus", (element, status) => {
35765
36470
  this.embedsValidationStatus.set(element.id, status);
35766
- ShapeCache5.delete(element);
36471
+ ShapeCache7.delete(element);
35767
36472
  });
35768
36473
  __publicField(this, "updateEmbeddables", () => {
35769
36474
  const iframeLikes = /* @__PURE__ */ new Set();
@@ -35870,7 +36575,7 @@ var App = class _App extends React40.Component {
35870
36575
  }
35871
36576
  return null;
35872
36577
  }
35873
- const { x: x1, y: y1 } = sceneCoordsToViewportCoords6(
36578
+ const { x: x1, y: y1 } = sceneCoordsToViewportCoords7(
35874
36579
  { sceneX: f.x, sceneY: f.y },
35875
36580
  this.state
35876
36581
  );
@@ -35879,7 +36584,7 @@ var App = class _App extends React40.Component {
35879
36584
  const frameName = getFrameLikeTitle(f);
35880
36585
  if (f.id === this.state.editingFrame) {
35881
36586
  const frameNameInEdit = frameName;
35882
- frameNameJSX = /* @__PURE__ */ jsx138(
36587
+ frameNameJSX = /* @__PURE__ */ jsx139(
35883
36588
  "input",
35884
36589
  {
35885
36590
  autoFocus: true,
@@ -35924,7 +36629,7 @@ var App = class _App extends React40.Component {
35924
36629
  } else {
35925
36630
  frameNameJSX = frameName;
35926
36631
  }
35927
- return /* @__PURE__ */ jsx138(
36632
+ return /* @__PURE__ */ jsx139(
35928
36633
  "div",
35929
36634
  {
35930
36635
  id: this.getFrameNameDOMId(f),
@@ -36030,7 +36735,7 @@ var App = class _App extends React40.Component {
36030
36735
  this.updateScene({
36031
36736
  elements: this.scene.getElementsIncludingDeleted().map((el) => {
36032
36737
  if (this.state.selectedElementIds[el.id]) {
36033
- return newElementWith10(el, {
36738
+ return newElementWith11(el, {
36034
36739
  [shouldUpdateStrokeColor ? "strokeColor" : "backgroundColor"]: color
36035
36740
  });
36036
36741
  }
@@ -36113,6 +36818,7 @@ var App = class _App extends React40.Component {
36113
36818
  }
36114
36819
  }));
36115
36820
  __publicField(this, "scheduleCapture", () => this.store.scheduleCapture());
36821
+ __publicField(this, "scheduleUpdate", () => this.store.scheduleAction(CaptureUpdateAction39.NEVER));
36116
36822
  // Lifecycle
36117
36823
  __publicField(this, "onBlur", withBatchedUpdates(() => {
36118
36824
  isHoldingSpace = false;
@@ -36518,7 +37224,7 @@ var App = class _App extends React40.Component {
36518
37224
  this.reconcileStylesPanelMode(this.editorInterface);
36519
37225
  });
36520
37226
  __publicField(this, "onResize", withBatchedUpdates(() => {
36521
- this.scene.getElementsIncludingDeleted().forEach((element) => ShapeCache5.delete(element));
37227
+ this.scene.getElementsIncludingDeleted().forEach((element) => ShapeCache7.delete(element));
36522
37228
  this.refreshEditorInterface();
36523
37229
  this.updateDOMRect();
36524
37230
  this.setState({});
@@ -36704,7 +37410,7 @@ var App = class _App extends React40.Component {
36704
37410
  const elements = restoreElements(opts.elements, null, {
36705
37411
  deleteInvisibleElements: true
36706
37412
  });
36707
- const [minX, minY, maxX, maxY] = getCommonBounds13(elements);
37413
+ const [minX, minY, maxX, maxY] = getCommonBounds14(elements);
36708
37414
  const elementsCenterX = distance2(minX, maxX) / 2;
36709
37415
  const elementsCenterY = distance2(minY, maxY) / 2;
36710
37416
  const clientX = typeof opts.position === "object" ? opts.position.clientX : opts.position === "cursor" ? this.viewport.lastPosition.x : this.state.width / 2 + this.state.offsetLeft;
@@ -36719,7 +37425,7 @@ var App = class _App extends React40.Component {
36719
37425
  const { duplicatedElements } = duplicateElements2({
36720
37426
  type: "everything",
36721
37427
  elements: elements.map((element) => {
36722
- return newElementWith10(element, {
37428
+ return newElementWith11(element, {
36723
37429
  x: element.x + gridX - minX,
36724
37430
  y: element.y + gridY - minY
36725
37431
  });
@@ -36904,7 +37610,7 @@ var App = class _App extends React40.Component {
36904
37610
  return;
36905
37611
  }
36906
37612
  this.viewport.setViewport({
36907
- target: getCommonBounds13(elements),
37613
+ target: getCommonBounds14(elements),
36908
37614
  fit: "scale-down",
36909
37615
  animation: { duration: 300 },
36910
37616
  offsets: { ui: true }
@@ -36982,7 +37688,9 @@ var App = class _App extends React40.Component {
36982
37688
  const refreshImageCache = _updateImageCache({
36983
37689
  imageCache: this.imageCache,
36984
37690
  fileIds: Array.from(placeholderFileIds),
36985
- files: this.files
37691
+ files: this.files,
37692
+ onImageCacheUpdate: (fileId) => this.handleImageCacheUpdate(fileId),
37693
+ gifAutoDecodeMaxFileSizeBytes: this.props.imageOptions.gifAutoDecodeMaxFileSizeBytes
36986
37694
  });
36987
37695
  refreshImageCache.then(async ({ updatedFiles }) => {
36988
37696
  for (const [fileId, placeholderImagePromise] of placeholderImages) {
@@ -37045,9 +37753,13 @@ var App = class _App extends React40.Component {
37045
37753
  const placeholderEntry = {
37046
37754
  image: imagePromise,
37047
37755
  mimeType: normalizedFile.type,
37048
- isPlaceholder: true
37756
+ isPlaceholder: true,
37757
+ gifDecodeStatus: normalizedFile.type === MIME_TYPES11.gif ? "pending" : void 0
37049
37758
  };
37050
37759
  this.imageCache.set(fileId, placeholderEntry);
37760
+ if (placeholderEntry.gifDecodeStatus === "pending") {
37761
+ this.imagePlaceholderUpdateEmitter.trigger();
37762
+ }
37051
37763
  image.src = await getDataURL(normalizedFile);
37052
37764
  try {
37053
37765
  const loadedImage = await imagePromise;
@@ -37139,8 +37851,8 @@ var App = class _App extends React40.Component {
37139
37851
  });
37140
37852
  __publicField(this, "clearImageShapeCacheForFileId", (fileId) => {
37141
37853
  for (const element of this.scene.getNonDeletedElements()) {
37142
- if (isInitializedImageElement3(element) && element.fileId === fileId) {
37143
- ShapeCache5.delete(element);
37854
+ if (isInitializedImageElement5(element) && element.fileId === fileId) {
37855
+ ShapeCache7.delete(element);
37144
37856
  }
37145
37857
  }
37146
37858
  });
@@ -37154,11 +37866,11 @@ var App = class _App extends React40.Component {
37154
37866
  }
37155
37867
  addedFiles[fileData.id] = fileData;
37156
37868
  nextFiles[fileData.id] = fileData;
37157
- if (fileData.mimeType === MIME_TYPES9.svg) {
37869
+ if (fileData.mimeType === MIME_TYPES11.svg) {
37158
37870
  try {
37159
37871
  const restoredDataURL = getDataURL_sync(
37160
37872
  normalizeSVG(dataURLToString(fileData.dataURL)),
37161
- MIME_TYPES9.svg
37873
+ MIME_TYPES11.svg
37162
37874
  );
37163
37875
  if (fileData.dataURL !== restoredDataURL) {
37164
37876
  fileData.version = (fileData.version ?? 1) + 1;
@@ -38870,7 +39582,7 @@ var App = class _App extends React40.Component {
38870
39582
  }
38871
39583
  } else if (selectedElements.length > 1 && !isOverScrollBar && this.state.openDialog?.name !== "elementLinkSelector") {
38872
39584
  const transformHandleType = getTransformHandleTypeFromCoords(
38873
- getCommonBounds13(selectedElements),
39585
+ getCommonBounds14(selectedElements),
38874
39586
  scenePointerX,
38875
39587
  scenePointerY,
38876
39588
  this.state.zoom,
@@ -39579,7 +40291,7 @@ var App = class _App extends React40.Component {
39579
40291
  }
39580
40292
  } else if (selectedElements.length > 1) {
39581
40293
  pointerDownState.resize.handleType = getTransformHandleTypeFromCoords(
39582
- getCommonBounds13(selectedElements),
40294
+ getCommonBounds14(selectedElements),
39583
40295
  pointerDownState.origin.x,
39584
40296
  pointerDownState.origin.y,
39585
40297
  this.state.zoom,
@@ -40414,7 +41126,7 @@ var App = class _App extends React40.Component {
40414
41126
  const elements = this.scene.getElementsIncludingDeleted().map((ele) => {
40415
41127
  if (this.elementsPendingErasure.has(ele.id) || ele.frameId && this.elementsPendingErasure.has(ele.frameId) || isBoundToContainer10(ele) && this.elementsPendingErasure.has(ele.containerId)) {
40416
41128
  didChange = true;
40417
- return newElementWith10(ele, { isDeleted: true });
41129
+ return newElementWith11(ele, { isDeleted: true });
40418
41130
  }
40419
41131
  return ele;
40420
41132
  });
@@ -40429,7 +41141,11 @@ var App = class _App extends React40.Component {
40429
41141
  throw new Error(t("errors.unsupportedFileType"));
40430
41142
  }
40431
41143
  this.cursor.set("wait");
40432
- if (imageFile.type === MIME_TYPES9.svg) {
41144
+ const placeholderGifFileId = this.gifPlayback.createPlaceholderDecodeState(
41145
+ placeholderImageElement,
41146
+ imageFile
41147
+ );
41148
+ if (imageFile.type === MIME_TYPES11.svg) {
40433
41149
  try {
40434
41150
  imageFile = SVGStringToFile(
40435
41151
  normalizeSVG(await imageFile.text()),
@@ -40439,7 +41155,7 @@ var App = class _App extends React40.Component {
40439
41155
  console.warn(error);
40440
41156
  throw new Error(t("errors.svgImageInsertError"));
40441
41157
  }
40442
- } else {
41158
+ } else if (imageFile.type !== MIME_TYPES11.gif) {
40443
41159
  const { maxWidthOrHeight } = this.props.imageOptions;
40444
41160
  try {
40445
41161
  imageFile = await (this.props.compressImageFile ?? resizeImageFile)(
@@ -40451,6 +41167,7 @@ var App = class _App extends React40.Component {
40451
41167
  }
40452
41168
  }
40453
41169
  const mimeType = imageFile.type;
41170
+ const isGif = mimeType === MIME_TYPES11.gif;
40454
41171
  const fileId = await (this.props.generateIdForFile?.(
40455
41172
  imageFile
40456
41173
  ) || generateIdFromFile(imageFile));
@@ -40489,8 +41206,21 @@ var App = class _App extends React40.Component {
40489
41206
  lastRetrieved: Date.now()
40490
41207
  }
40491
41208
  ]);
41209
+ if (isGif) {
41210
+ initializedImageElement = this.gifPlayback.ensureElementPlaybackMetadata(
41211
+ initializedImageElement
41212
+ );
41213
+ this.scene.replaceAllElements(
41214
+ this.scene.getElementsIncludingDeleted().map(
41215
+ (element) => element.id === initializedImageElement.id ? initializedImageElement : element
41216
+ )
41217
+ );
41218
+ this.imagePlaceholderUpdateEmitter.trigger();
41219
+ }
40492
41220
  if (!this.imageCache.get(fileId)) {
40493
- this.addNewImagesToImageCache();
41221
+ if (!isGif) {
41222
+ this.addNewImagesToImageCache();
41223
+ }
40494
41224
  const { erroredFiles } = await this.updateImageCache([
40495
41225
  initializedImageElement
40496
41226
  ]);
@@ -40511,9 +41241,13 @@ var App = class _App extends React40.Component {
40511
41241
  );
40512
41242
  Object.assign(initializedImageElement, naturalDimensions);
40513
41243
  }
40514
- initializedImageElement = newElementWith10(initializedImageElement, {
41244
+ initializedImageElement = newElementWith11(initializedImageElement, {
40515
41245
  fileName: imageFile.name,
40516
41246
  thumbHash,
41247
+ gifPlayback: isGif ? this.gifPlayback.ensureElementPlaybackMetadata(
41248
+ initializedImageElement,
41249
+ { playing: true }
41250
+ ).gifPlayback : null,
40517
41251
  status: "saved"
40518
41252
  });
40519
41253
  this.files = {
@@ -40524,8 +41258,12 @@ var App = class _App extends React40.Component {
40524
41258
  thumbHash: thumbHash ?? void 0
40525
41259
  }
40526
41260
  };
41261
+ if (placeholderGifFileId && placeholderGifFileId !== fileId) {
41262
+ this.gifPlayback.removePlaceholderDecodeState(placeholderGifFileId);
41263
+ }
40527
41264
  resolve(initializedImageElement);
40528
41265
  } catch (error) {
41266
+ this.gifPlayback.removePlaceholderDecodeState(placeholderGifFileId);
40529
41267
  console.error(error);
40530
41268
  reject(new Error(t("errors.imageInsertError")));
40531
41269
  }
@@ -40539,7 +41277,7 @@ var App = class _App extends React40.Component {
40539
41277
  */
40540
41278
  __publicField(this, "getLatestInitializedImageElement", (imagePlaceholder, fileId) => {
40541
41279
  const latestImageElement = this.scene.getElement(imagePlaceholder.id) ?? imagePlaceholder;
40542
- return newElementWith10(
41280
+ return newElementWith11(
40543
41281
  latestImageElement,
40544
41282
  {
40545
41283
  fileId
@@ -40601,6 +41339,16 @@ var App = class _App extends React40.Component {
40601
41339
  });
40602
41340
  /** updates image cache, refreshing updated elements and/or setting status
40603
41341
  to error for images that fail during <img> element creation */
41342
+ __publicField(this, "handleImageCacheUpdate", (fileId) => {
41343
+ for (const element of this.scene.getNonDeletedElements()) {
41344
+ if (isInitializedImageElement5(element) && element.fileId === fileId) {
41345
+ ShapeCache7.delete(element);
41346
+ }
41347
+ }
41348
+ this.imagePlaceholderUpdateEmitter.trigger();
41349
+ this.scene.triggerUpdate();
41350
+ this.ensureGifPlaybackLoop();
41351
+ });
40604
41352
  __publicField(this, "updateImageCache", async (elements, files = this.files) => {
40605
41353
  const placeholderImages = /* @__PURE__ */ new Map();
40606
41354
  for (const element of elements) {
@@ -40615,7 +41363,9 @@ var App = class _App extends React40.Component {
40615
41363
  const { updatedFiles, erroredFiles } = await _updateImageCache({
40616
41364
  imageCache: this.imageCache,
40617
41365
  fileIds: elements.map((element) => element.fileId),
40618
- files
41366
+ files,
41367
+ onImageCacheUpdate: (fileId) => this.handleImageCacheUpdate(fileId),
41368
+ gifAutoDecodeMaxFileSizeBytes: this.props.imageOptions.gifAutoDecodeMaxFileSizeBytes
40619
41369
  });
40620
41370
  for (const [fileId, placeholderImagePromise] of placeholderImages) {
40621
41371
  const cacheEntry = this.imageCache.get(fileId);
@@ -40632,14 +41382,14 @@ var App = class _App extends React40.Component {
40632
41382
  this.store.scheduleAction(CaptureUpdateAction39.NEVER);
40633
41383
  this.scene.replaceAllElements(
40634
41384
  this.scene.getElementsIncludingDeleted().map((element) => {
40635
- if (isInitializedImageElement3(element)) {
41385
+ if (isInitializedImageElement5(element)) {
40636
41386
  if (erroredFiles.has(element.fileId)) {
40637
- return newElementWith10(element, {
41387
+ return newElementWith11(element, {
40638
41388
  status: "error"
40639
41389
  });
40640
41390
  }
40641
41391
  if (updatedFiles.has(element.fileId) && element.status === "error") {
40642
- return newElementWith10(element, {
41392
+ return newElementWith11(element, {
40643
41393
  status: "saved"
40644
41394
  });
40645
41395
  }
@@ -40650,6 +41400,32 @@ var App = class _App extends React40.Component {
40650
41400
  }
40651
41401
  return { updatedFiles, erroredFiles };
40652
41402
  });
41403
+ __publicField(this, "ensureGifPlaybackLoop", () => {
41404
+ this.gifPlayback.ensureLoop();
41405
+ });
41406
+ __publicField(this, "loadDeferredGif", async (fileId) => {
41407
+ const cacheEntry = this.imageCache.get(fileId);
41408
+ const fileData = this.files[fileId];
41409
+ if (fileData?.mimeType !== MIME_TYPES11.gif || !cacheEntry) {
41410
+ return;
41411
+ }
41412
+ this.imageCache.set(fileId, {
41413
+ ...cacheEntry,
41414
+ gifDecodeStatus: "pending"
41415
+ });
41416
+ this.handleImageCacheUpdate(fileId);
41417
+ await _updateImageCache({
41418
+ imageCache: this.imageCache,
41419
+ fileIds: [fileId],
41420
+ files: this.files,
41421
+ onImageCacheUpdate: (updatedFileId) => this.handleImageCacheUpdate(updatedFileId),
41422
+ forceGifDecode: true
41423
+ });
41424
+ });
41425
+ __publicField(this, "getGifPlaybackFrameIndex", (element) => this.gifPlayback.getFrameIndex(element));
41426
+ __publicField(this, "setGifPlaybackFrameIndex", (element, frameIndex) => {
41427
+ this.gifPlayback.setFrameIndex(element, frameIndex);
41428
+ });
40653
41429
  /** adds new images to imageCache and re-renders if needed */
40654
41430
  __publicField(this, "addNewImagesToImageCache", async (imageElements = getInitializedImageElements(
40655
41431
  this.scene.getNonDeletedElements()
@@ -40665,7 +41441,7 @@ var App = class _App extends React40.Component {
40665
41441
  if (updatedFiles.size) {
40666
41442
  for (const element of uncachedImageElements) {
40667
41443
  if (updatedFiles.has(element.fileId)) {
40668
- ShapeCache5.delete(element);
41444
+ ShapeCache7.delete(element);
40669
41445
  }
40670
41446
  }
40671
41447
  }
@@ -40726,7 +41502,7 @@ var App = class _App extends React40.Component {
40726
41502
  this.setState({
40727
41503
  errorMessage: error.message || t("errors.imageInsertError")
40728
41504
  });
40729
- return newElementWith10(placeholder, {
41505
+ return newElementWith11(placeholder, {
40730
41506
  isDeleted: true
40731
41507
  });
40732
41508
  }
@@ -40791,7 +41567,7 @@ var App = class _App extends React40.Component {
40791
41567
  }
40792
41568
  if (fileItems.length === 1) {
40793
41569
  const { file: file2, fileHandle } = fileItems[0];
40794
- if (file2 && (file2.type === MIME_TYPES9.png || file2.type === MIME_TYPES9.svg)) {
41570
+ if (file2 && (file2.type === MIME_TYPES11.png || file2.type === MIME_TYPES11.svg)) {
40795
41571
  try {
40796
41572
  const scene = await loadFromBlob(
40797
41573
  file2,
@@ -40834,7 +41610,7 @@ var App = class _App extends React40.Component {
40834
41610
  await this.loadFileToCanvas(file2, fileHandle);
40835
41611
  }
40836
41612
  }
40837
- const textItem = dataTransferList.findByType(MIME_TYPES9.text);
41613
+ const textItem = dataTransferList.findByType(MIME_TYPES11.text);
40838
41614
  if (textItem) {
40839
41615
  const text = textItem.value;
40840
41616
  if (text && embeddableURLValidator2(text, this.props.validateEmbeddable) && (/^(http|https):\/\/[^\s/$.?#].[^\s]*$/.test(text) || getEmbedLink2(text)?.type === "video")) {
@@ -40991,7 +41767,7 @@ var App = class _App extends React40.Component {
40991
41767
  pointerCoords.y,
40992
41768
  event[KEYS52.CTRL_OR_CMD] ? null : this.getEffectiveGridSize()
40993
41769
  );
40994
- const image = isInitializedImageElement3(newElement9) && this.imageCache.get(newElement9.fileId)?.image;
41770
+ const image = isInitializedImageElement5(newElement9) && this.imageCache.get(newElement9.fileId)?.image;
40995
41771
  const aspectRatio = image && !(image instanceof Promise) ? image.width / image.height : null;
40996
41772
  this.maybeCacheReferenceSnapPoints(event, [newElement9]);
40997
41773
  const { snapOffset, snapLines } = snapNewElement(
@@ -41063,7 +41839,7 @@ var App = class _App extends React40.Component {
41063
41839
  const croppingAtStateStart = pointerDownState.originalElements.get(
41064
41840
  croppingElement.id
41065
41841
  );
41066
- const image = isInitializedImageElement3(croppingElement) && this.imageCache.get(croppingElement.fileId)?.image;
41842
+ const image = isInitializedImageElement5(croppingElement) && this.imageCache.get(croppingElement.fileId)?.image;
41067
41843
  if (croppingAtStateStart && isImageElement9(croppingAtStateStart) && image && !(image instanceof Promise)) {
41068
41844
  const [gridX, gridY] = getGridPoint4(
41069
41845
  pointerCoords.x,
@@ -42075,8 +42851,8 @@ var App = class _App extends React40.Component {
42075
42851
  const embeddableElements = this.scene.getNonDeletedElements().filter(
42076
42852
  (el) => isEmbeddableElement4(el) && this.embedsValidationStatus.get(el.id) === true || isIframeElement2(el)
42077
42853
  );
42078
- return /* @__PURE__ */ jsx138(Fragment25, { children: embeddableElements.map((el) => {
42079
- const { x, y } = sceneCoordsToViewportCoords6(
42854
+ return /* @__PURE__ */ jsx139(Fragment26, { children: embeddableElements.map((el) => {
42855
+ const { x, y } = sceneCoordsToViewportCoords7(
42080
42856
  { sceneX: el.x, sceneY: el.y },
42081
42857
  this.state
42082
42858
  );
@@ -42104,10 +42880,10 @@ var App = class _App extends React40.Component {
42104
42880
  0.75,
42105
42881
  MAX_EMBEDDABLE_VIEWPORT_SCALE
42106
42882
  );
42107
- return /* @__PURE__ */ jsx138(
42883
+ return /* @__PURE__ */ jsx139(
42108
42884
  "div",
42109
42885
  {
42110
- className: clsx60("excalidraw__embeddable-container", {
42886
+ className: clsx61("excalidraw__embeddable-container", {
42111
42887
  "is-hovered": isHovered
42112
42888
  }),
42113
42889
  style: {
@@ -42125,7 +42901,7 @@ var App = class _App extends React40.Component {
42125
42901
  el
42126
42902
  )}px`
42127
42903
  },
42128
- children: /* @__PURE__ */ jsxs68(
42904
+ children: /* @__PURE__ */ jsxs69(
42129
42905
  "div",
42130
42906
  {
42131
42907
  className: "excalidraw__embeddable-container__inner",
@@ -42136,15 +42912,15 @@ var App = class _App extends React40.Component {
42136
42912
  pointerEvents: isActive ? POINTER_EVENTS.enabled : POINTER_EVENTS.disabled
42137
42913
  },
42138
42914
  children: [
42139
- isHovered && /* @__PURE__ */ jsx138("div", { className: "excalidraw__embeddable-hint", children: t("buttons.embeddableInteractionButton") }),
42140
- /* @__PURE__ */ jsx138(
42915
+ isHovered && /* @__PURE__ */ jsx139("div", { className: "excalidraw__embeddable-hint", children: t("buttons.embeddableInteractionButton") }),
42916
+ /* @__PURE__ */ jsx139(
42141
42917
  "div",
42142
42918
  {
42143
42919
  className: "excalidraw__embeddable__outer",
42144
42920
  style: {
42145
42921
  padding: `${el.strokeWidth}px`
42146
42922
  },
42147
- children: /* @__PURE__ */ jsx138(
42923
+ children: /* @__PURE__ */ jsx139(
42148
42924
  "div",
42149
42925
  {
42150
42926
  className: "excalidraw__embeddable__content",
@@ -42153,7 +42929,7 @@ var App = class _App extends React40.Component {
42153
42929
  height: `${embeddableViewportScale * 100}%`,
42154
42930
  transform: `scale(${1 / embeddableViewportScale})`
42155
42931
  },
42156
- children: (isEmbeddableElement4(el) ? this.props.renderEmbeddable?.(el, this.state) : null) ?? /* @__PURE__ */ jsx138(
42932
+ children: (isEmbeddableElement4(el) ? this.props.renderEmbeddable?.(el, this.state) : null) ?? /* @__PURE__ */ jsx139(
42157
42933
  "iframe",
42158
42934
  {
42159
42935
  ref: (ref) => this.cacheEmbeddableRef(el, ref),
@@ -42220,11 +42996,11 @@ var App = class _App extends React40.Component {
42220
42996
  );
42221
42997
  const firstSelectedElement = selectedElements[0];
42222
42998
  const showShapeSwitchPanel = editorJotaiStore.get(convertElementTypePopupAtom)?.type === "panel";
42223
- return /* @__PURE__ */ jsx138(
42999
+ return /* @__PURE__ */ jsx139(
42224
43000
  "div",
42225
43001
  {
42226
43002
  translate: "no",
42227
- className: clsx60(
43003
+ className: clsx61(
42228
43004
  "excalidraw excalidraw-container notranslate",
42229
43005
  this.props.className,
42230
43006
  {
@@ -42252,25 +43028,25 @@ var App = class _App extends React40.Component {
42252
43028
  onKeyDown: this.props.handleKeyboardGlobally || !this.isInteractionEnabled() ? void 0 : this.onKeyDown,
42253
43029
  onPointerEnter: this.isInteractionEnabled() ? this.toggleOverscrollBehavior : void 0,
42254
43030
  onPointerLeave: this.isInteractionEnabled() ? this.toggleOverscrollBehavior : void 0,
42255
- children: /* @__PURE__ */ jsx138(ExcalidrawAPIContext.Provider, { value: this.api, children: /* @__PURE__ */ jsx138(AppContext.Provider, { value: this, children: /* @__PURE__ */ jsx138(AppPropsContext.Provider, { value: this.props, children: /* @__PURE__ */ jsx138(
43031
+ children: /* @__PURE__ */ jsx139(ExcalidrawAPIContext.Provider, { value: this.api, children: /* @__PURE__ */ jsx139(AppContext.Provider, { value: this, children: /* @__PURE__ */ jsx139(AppPropsContext.Provider, { value: this.props, children: /* @__PURE__ */ jsx139(
42256
43032
  ExcalidrawContainerContext.Provider,
42257
43033
  {
42258
43034
  value: this.excalidrawContainerValue,
42259
- children: /* @__PURE__ */ jsx138(EditorInterfaceContext.Provider, { value: this.editorInterface, children: /* @__PURE__ */ jsx138(
43035
+ children: /* @__PURE__ */ jsx139(EditorInterfaceContext.Provider, { value: this.editorInterface, children: /* @__PURE__ */ jsx139(
42260
43036
  ExcalidrawSetAppStateContext.Provider,
42261
43037
  {
42262
43038
  value: this.setAppState,
42263
- children: /* @__PURE__ */ jsx138(ExcalidrawAppStateContext.Provider, { value: this.state, children: /* @__PURE__ */ jsxs68(
43039
+ children: /* @__PURE__ */ jsx139(ExcalidrawAppStateContext.Provider, { value: this.state, children: /* @__PURE__ */ jsxs69(
42264
43040
  ExcalidrawElementsContext.Provider,
42265
43041
  {
42266
43042
  value: this.scene.getNonDeletedElements(),
42267
43043
  children: [
42268
- /* @__PURE__ */ jsxs68(
43044
+ /* @__PURE__ */ jsxs69(
42269
43045
  ExcalidrawActionManagerContext.Provider,
42270
43046
  {
42271
43047
  value: this.actionManager,
42272
43048
  children: [
42273
- /* @__PURE__ */ jsx138(
43049
+ /* @__PURE__ */ jsx139(
42274
43050
  LayerUI_default,
42275
43051
  {
42276
43052
  canvas: this.canvas,
@@ -42301,10 +43077,10 @@ var App = class _App extends React40.Component {
42301
43077
  children: this.props.children
42302
43078
  }
42303
43079
  ),
42304
- /* @__PURE__ */ jsx138("div", { className: "excalidraw-textEditorContainer" }),
42305
- /* @__PURE__ */ jsx138("div", { className: "excalidraw-contextMenuContainer" }),
42306
- /* @__PURE__ */ jsx138("div", { className: "excalidraw-eye-dropper-container" }),
42307
- /* @__PURE__ */ jsx138(
43080
+ /* @__PURE__ */ jsx139("div", { className: "excalidraw-textEditorContainer" }),
43081
+ /* @__PURE__ */ jsx139("div", { className: "excalidraw-contextMenuContainer" }),
43082
+ /* @__PURE__ */ jsx139("div", { className: "excalidraw-eye-dropper-container" }),
43083
+ /* @__PURE__ */ jsx139(
42308
43084
  SVGLayer,
42309
43085
  {
42310
43086
  trails: [
@@ -42315,8 +43091,8 @@ var App = class _App extends React40.Component {
42315
43091
  ]
42316
43092
  }
42317
43093
  ),
42318
- this.isDefaultUIEnabled() && /* @__PURE__ */ jsx138(CursorHint, {}),
42319
- this.isDefaultUIEnabled() && selectedElements.length === 1 && this.state.openDialog?.name !== "elementLinkSelector" && this.state.showHyperlinkPopup && /* @__PURE__ */ jsx138(
43094
+ this.isDefaultUIEnabled() && /* @__PURE__ */ jsx139(CursorHint, {}),
43095
+ this.isDefaultUIEnabled() && selectedElements.length === 1 && this.state.openDialog?.name !== "elementLinkSelector" && this.state.showHyperlinkPopup && /* @__PURE__ */ jsx139(
42320
43096
  Hyperlink,
42321
43097
  {
42322
43098
  element: firstSelectedElement,
@@ -42328,7 +43104,7 @@ var App = class _App extends React40.Component {
42328
43104
  },
42329
43105
  firstSelectedElement.id
42330
43106
  ),
42331
- this.isDefaultUIEnabled() && this.state.contextMenu && /* @__PURE__ */ jsx138(
43107
+ this.isDefaultUIEnabled() && this.state.contextMenu && /* @__PURE__ */ jsx139(
42332
43108
  ContextMenu2,
42333
43109
  {
42334
43110
  items: this.state.contextMenu.items,
@@ -42343,7 +43119,7 @@ var App = class _App extends React40.Component {
42343
43119
  }
42344
43120
  }
42345
43121
  ),
42346
- /* @__PURE__ */ jsx138(
43122
+ /* @__PURE__ */ jsx139(
42347
43123
  StaticCanvas_default,
42348
43124
  {
42349
43125
  app: this,
@@ -42358,6 +43134,7 @@ var App = class _App extends React40.Component {
42358
43134
  appState: this.state,
42359
43135
  renderConfig: {
42360
43136
  imageCache: this.imageCache,
43137
+ getGifFrameIndex: this.gifPlayback.getFrameIndex,
42361
43138
  isExporting: false,
42362
43139
  renderGrid: isGridModeEnabled(this),
42363
43140
  renderLinks: this.isLinksEnabled(),
@@ -42370,7 +43147,7 @@ var App = class _App extends React40.Component {
42370
43147
  }
42371
43148
  }
42372
43149
  ),
42373
- newElementCanvasElement && /* @__PURE__ */ jsx138(
43150
+ newElementCanvasElement && /* @__PURE__ */ jsx139(
42374
43151
  NewElementCanvas_default,
42375
43152
  {
42376
43153
  appState: this.state,
@@ -42381,6 +43158,7 @@ var App = class _App extends React40.Component {
42381
43158
  allElementsMap,
42382
43159
  renderConfig: {
42383
43160
  imageCache: this.imageCache,
43161
+ getGifFrameIndex: this.gifPlayback.getFrameIndex,
42384
43162
  isExporting: false,
42385
43163
  imageTransitionDuration: this.props.imageOptions.placeholderTransitionDuration,
42386
43164
  renderGrid: false,
@@ -42392,7 +43170,7 @@ var App = class _App extends React40.Component {
42392
43170
  }
42393
43171
  }
42394
43172
  ),
42395
- /* @__PURE__ */ jsx138(
43173
+ /* @__PURE__ */ jsx139(
42396
43174
  InteractiveCanvas_default,
42397
43175
  {
42398
43176
  app: this,
@@ -42422,21 +43200,21 @@ var App = class _App extends React40.Component {
42422
43200
  onDoubleClick: this.handleCanvasDoubleClick
42423
43201
  }
42424
43202
  ),
42425
- this.props.viewportStatusFrame?.border && this.editorInterface.formFactor === "phone" && /* @__PURE__ */ jsx138(
43203
+ this.props.viewportStatusFrame?.border && this.editorInterface.formFactor === "phone" && /* @__PURE__ */ jsx139(
42426
43204
  ViewportStatusBorder,
42427
43205
  {
42428
43206
  border: this.props.viewportStatusFrame.border
42429
43207
  }
42430
43208
  ),
42431
43209
  this.renderFrameNames(),
42432
- this.isDefaultUIEnabled() && this.state.activeLockedId && /* @__PURE__ */ jsx138(
43210
+ this.isDefaultUIEnabled() && this.state.activeLockedId && /* @__PURE__ */ jsx139(
42433
43211
  UnlockPopup_default,
42434
43212
  {
42435
43213
  app: this,
42436
43214
  activeLockedId: this.state.activeLockedId
42437
43215
  }
42438
43216
  ),
42439
- this.isDefaultUIEnabled() && showShapeSwitchPanel && /* @__PURE__ */ jsx138(ConvertElementTypePopup_default, { app: this })
43217
+ this.isDefaultUIEnabled() && showShapeSwitchPanel && /* @__PURE__ */ jsx139(ConvertElementTypePopup_default, { app: this })
42440
43218
  ]
42441
43219
  }
42442
43220
  ),
@@ -42454,9 +43232,9 @@ var App = class _App extends React40.Component {
42454
43232
  clearImageShapeCache(filesMap) {
42455
43233
  const files = filesMap ?? this.files;
42456
43234
  this.scene.getNonDeletedElements().forEach((element) => {
42457
- if (isInitializedImageElement3(element) && files[element.fileId]) {
43235
+ if (isInitializedImageElement5(element) && files[element.fileId]) {
42458
43236
  this.imageCache.delete(element.fileId);
42459
- ShapeCache5.delete(element);
43237
+ ShapeCache7.delete(element);
42460
43238
  }
42461
43239
  });
42462
43240
  }
@@ -42525,7 +43303,7 @@ var App = class _App extends React40.Component {
42525
43303
  }
42526
43304
  if (isBrave() && !isMeasureTextSupported()) {
42527
43305
  this.setState({
42528
- errorMessage: /* @__PURE__ */ jsx138(BraveMeasureTextError_default, {})
43306
+ errorMessage: /* @__PURE__ */ jsx139(BraveMeasureTextError_default, {})
42529
43307
  });
42530
43308
  }
42531
43309
  const mountPayload = {
@@ -42537,6 +43315,7 @@ var App = class _App extends React40.Component {
42537
43315
  this.props.onExcalidrawAPI?.(this.api);
42538
43316
  }
42539
43317
  componentWillUnmount() {
43318
+ this.gifPlayback.stop();
42540
43319
  this.api = { ...this.api, isDestroyed: true };
42541
43320
  for (const key of Object.keys(this.api)) {
42542
43321
  if ((key.startsWith("get") || key === "onStateChange" || key === "onEvent") && typeof this.api[key] === "function") {
@@ -42571,7 +43350,7 @@ var App = class _App extends React40.Component {
42571
43350
  this.store.onDurableIncrementEmitter.clear();
42572
43351
  this.appStateObserver.clear();
42573
43352
  this.editorLifecycleEvents.clear();
42574
- ShapeCache5.destroy();
43353
+ ShapeCache7.destroy();
42575
43354
  SnapCache.destroy();
42576
43355
  clearTimeout(touchTimeout);
42577
43356
  isSomeElementSelected.clearCache();
@@ -42790,6 +43569,7 @@ var App = class _App extends React40.Component {
42790
43569
  }
42791
43570
  this.handleInteractionStateChange(prevProps, prevState);
42792
43571
  this.handleForcedToolChange(prevProps, prevState);
43572
+ this.ensureGifPlaybackLoop();
42793
43573
  this.appStateObserver.flush(prevState);
42794
43574
  this.updateEmbeddables();
42795
43575
  const elements = this.scene.getElementsIncludingDeleted();
@@ -43170,7 +43950,7 @@ var App = class _App extends React40.Component {
43170
43950
  // Not sure why we include deleted elements as well hence using deleted elements map
43171
43951
  ...this.scene.getElementsIncludingDeleted().map((_element) => {
43172
43952
  if (_element.id === element.id && isTextElement18(_element)) {
43173
- return newElementWith10(_element, {
43953
+ return newElementWith11(_element, {
43174
43954
  originalText: nextOriginalText,
43175
43955
  isDeleted: isDeleted ?? _element.isDeleted,
43176
43956
  // returns (wrapped) text and new dimensions
@@ -43189,7 +43969,7 @@ var App = class _App extends React40.Component {
43189
43969
  this.textWysiwygSubmitHandler = textWysiwyg({
43190
43970
  canvas: this.canvas,
43191
43971
  getViewportCoords: (x, y) => {
43192
- const { x: viewportX, y: viewportY } = sceneCoordsToViewportCoords6(
43972
+ const { x: viewportX, y: viewportY } = sceneCoordsToViewportCoords7(
43193
43973
  {
43194
43974
  sceneX: x,
43195
43975
  sceneY: y
@@ -43574,7 +44354,7 @@ var App = class _App extends React40.Component {
43574
44354
  initialPointerDownState(event) {
43575
44355
  const origin = viewportCoordsToSceneCoords3(event, this.state);
43576
44356
  const selectedElements = this.scene.getSelectedElements(this.state);
43577
- const [minX, minY, maxX, maxY] = getCommonBounds13(selectedElements);
44357
+ const [minX, minY, maxX, maxY] = getCommonBounds14(selectedElements);
43578
44358
  const isElbowArrowOnly = selectedElements.findIndex(isElbowArrow10) === 0;
43579
44359
  return {
43580
44360
  origin,
@@ -43675,7 +44455,7 @@ var App = class _App extends React40.Component {
43675
44455
  1
43676
44456
  );
43677
44457
  const boundsPadding = DEFAULT_TRANSFORM_HANDLE_SPACING4 * 2 / this.state.zoom.value;
43678
- const [x1, y1, x2, y2] = getCommonBounds13(selectedElements);
44458
+ const [x1, y1, x2, y2] = getCommonBounds14(selectedElements);
43679
44459
  return point.x > x1 - boundsPadding - threshold && point.x < x2 + boundsPadding + threshold && point.y > y1 - boundsPadding - threshold && point.y < y2 + boundsPadding + threshold;
43680
44460
  }
43681
44461
  getCurrentItemRoundness(elementType) {
@@ -43985,7 +44765,7 @@ var App = class _App extends React40.Component {
43985
44765
  const croppingElement = this.scene.getNonDeletedElementsMap().get(this.state.croppingElementId);
43986
44766
  if (croppingElement && isImageElement9(croppingElement) && croppingElement.crop !== null && pointerDownState.hit.element === croppingElement) {
43987
44767
  const crop = croppingElement.crop;
43988
- const image = isInitializedImageElement3(croppingElement) && this.imageCache.get(croppingElement.fileId)?.image;
44768
+ const image = isInitializedImageElement5(croppingElement) && this.imageCache.get(croppingElement.fileId)?.image;
43989
44769
  if (image && !(image instanceof Promise)) {
43990
44770
  const uncroppedSize = getUncroppedWidthAndHeight4(croppingElement);
43991
44771
  const instantDragOffset = vector4(
@@ -44127,7 +44907,7 @@ var App = class _App extends React40.Component {
44127
44907
  if (idsOfElementsToDuplicate.has(el.id)) {
44128
44908
  const origEl = pointerDownState.originalElements.get(el.id);
44129
44909
  if (origEl) {
44130
- return newElementWith10(el, {
44910
+ return newElementWith11(el, {
44131
44911
  x: origEl.x,
44132
44912
  y: origEl.y
44133
44913
  });
@@ -45149,7 +45929,7 @@ var App = class _App extends React40.Component {
45149
45929
  );
45150
45930
  const isSnappedToCenter = distanceToCenter < TEXT_TO_CENTER_SNAP_THRESHOLD;
45151
45931
  if (isSnappedToCenter) {
45152
- const { x: viewportX, y: viewportY } = sceneCoordsToViewportCoords6(
45932
+ const { x: viewportX, y: viewportY } = sceneCoordsToViewportCoords7(
45153
45933
  { sceneX: elementCenterX, sceneY: elementCenterY },
45154
45934
  appState
45155
45935
  );
@@ -45206,7 +45986,7 @@ var App_default = App;
45206
45986
 
45207
45987
  // components/InitializeApp.tsx
45208
45988
  import { useEffect as useEffect39, useState as useState35 } from "react";
45209
- import { jsx as jsx139 } from "react/jsx-runtime";
45989
+ import { jsx as jsx140 } from "react/jsx-runtime";
45210
45990
  var InitializeApp = (props) => {
45211
45991
  const [loading, setLoading] = useState35(true);
45212
45992
  useEffect39(() => {
@@ -45217,19 +45997,19 @@ var InitializeApp = (props) => {
45217
45997
  const currentLang2 = languages.find((lang) => lang.code === props.langCode) || defaultLang;
45218
45998
  updateLang();
45219
45999
  }, [props.langCode]);
45220
- return loading ? /* @__PURE__ */ jsx139(LoadingMessage, { theme: props.theme }) : props.children;
46000
+ return loading ? /* @__PURE__ */ jsx140(LoadingMessage, { theme: props.theme }) : props.children;
45221
46001
  };
45222
46002
 
45223
46003
  // components/footer/FooterCenter.tsx
45224
- import clsx61 from "clsx";
45225
- import { jsx as jsx140 } from "react/jsx-runtime";
46004
+ import clsx62 from "clsx";
46005
+ import { jsx as jsx141 } from "react/jsx-runtime";
45226
46006
  var FooterCenter = ({ children }) => {
45227
46007
  const { FooterCenterTunnel } = useTunnels();
45228
46008
  const appState = useUIAppState();
45229
- return /* @__PURE__ */ jsx140(FooterCenterTunnel.In, { children: /* @__PURE__ */ jsx140(
46009
+ return /* @__PURE__ */ jsx141(FooterCenterTunnel.In, { children: /* @__PURE__ */ jsx141(
45230
46010
  "div",
45231
46011
  {
45232
- className: clsx61("footer-center zen-mode-transition", {
46012
+ className: clsx62("footer-center zen-mode-transition", {
45233
46013
  "layer-ui__wrapper__footer-left--transition-bottom": appState.zenModeEnabled
45234
46014
  }),
45235
46015
  children
@@ -45240,9 +46020,9 @@ var FooterCenter_default = FooterCenter;
45240
46020
  FooterCenter.displayName = "FooterCenter";
45241
46021
 
45242
46022
  // components/live-collaboration/LiveCollaborationTrigger.tsx
45243
- import clsx62 from "clsx";
46023
+ import clsx63 from "clsx";
45244
46024
  import { MQ_MIN_WIDTH_DESKTOP } from "@excalidraw/common";
45245
- import { jsx as jsx141, jsxs as jsxs69 } from "react/jsx-runtime";
46025
+ import { jsx as jsx142, jsxs as jsxs70 } from "react/jsx-runtime";
45246
46026
  var LiveCollaborationTrigger2 = ({
45247
46027
  isCollaborating,
45248
46028
  onSelect,
@@ -45251,18 +46031,18 @@ var LiveCollaborationTrigger2 = ({
45251
46031
  }) => {
45252
46032
  const appState = useUIAppState();
45253
46033
  const showIconOnly = editorInterface?.formFactor !== "desktop" || appState.width < MQ_MIN_WIDTH_DESKTOP;
45254
- return /* @__PURE__ */ jsxs69(
46034
+ return /* @__PURE__ */ jsxs70(
45255
46035
  Button,
45256
46036
  {
45257
46037
  ...rest,
45258
- className: clsx62("collab-button", { active: isCollaborating }),
46038
+ className: clsx63("collab-button", { active: isCollaborating }),
45259
46039
  type: "button",
45260
46040
  onSelect,
45261
46041
  style: { position: "relative", width: showIconOnly ? void 0 : "auto" },
45262
46042
  title: t("labels.liveCollaboration"),
45263
46043
  children: [
45264
46044
  showIconOnly ? share : t("labels.share"),
45265
- appState.collaborators.size > 0 && /* @__PURE__ */ jsx141("div", { className: "CollabButton-collaborators", children: appState.collaborators.size })
46045
+ appState.collaborators.size > 0 && /* @__PURE__ */ jsx142("div", { className: "CollabButton-collaborators", children: appState.collaborators.size })
45266
46046
  ]
45267
46047
  }
45268
46048
  );
@@ -45271,15 +46051,15 @@ var LiveCollaborationTrigger_default = LiveCollaborationTrigger2;
45271
46051
  LiveCollaborationTrigger2.displayName = "LiveCollaborationTrigger";
45272
46052
 
45273
46053
  // components/ExcalidrawLogo.tsx
45274
- import { jsx as jsx142, jsxs as jsxs70 } from "react/jsx-runtime";
45275
- var LogoIcon = () => /* @__PURE__ */ jsx142(
46054
+ import { jsx as jsx143, jsxs as jsxs71 } from "react/jsx-runtime";
46055
+ var LogoIcon = () => /* @__PURE__ */ jsx143(
45276
46056
  "svg",
45277
46057
  {
45278
46058
  viewBox: "0 0 40 40",
45279
46059
  fill: "none",
45280
46060
  xmlns: "http://www.w3.org/2000/svg",
45281
46061
  className: "ExcalidrawLogo-icon",
45282
- children: /* @__PURE__ */ jsx142(
46062
+ children: /* @__PURE__ */ jsx143(
45283
46063
  "path",
45284
46064
  {
45285
46065
  d: "M39.9 32.889a.326.326 0 0 0-.279-.056c-2.094-3.083-4.774-6-7.343-8.833l-.419-.472a.212.212 0 0 0-.056-.139.586.586 0 0 0-.167-.111l-.084-.083-.056-.056c-.084-.167-.28-.278-.475-.167-.782.39-1.507.973-2.206 1.528-.92.722-1.842 1.445-2.708 2.25a8.405 8.405 0 0 0-.977 1.028c-.14.194-.028.361.14.444-.615.611-1.23 1.223-1.843 1.861a.315.315 0 0 0-.084.223c0 .083.056.166.111.194l1.09.833v.028c1.535 1.528 4.244 3.611 7.12 5.861.418.334.865.667 1.284 1 .195.223.39.473.558.695.084.11.28.139.391.055.056.056.14.111.196.167a.398.398 0 0 0 .167.056.255.255 0 0 0 .224-.111.394.394 0 0 0 .055-.167c.029 0 .028.028.056.028a.318.318 0 0 0 .224-.084l5.082-5.528a.309.309 0 0 0 0-.444Zm-14.63-1.917a.485.485 0 0 0 .111.14c.586.5 1.2 1 1.843 1.555l-2.569-1.945-.251-.166c-.056-.028-.112-.084-.168-.111l-.195-.167.056-.056.055-.055.112-.111c.866-.861 2.346-2.306 3.1-3.028-.81.805-2.43 3.167-2.095 3.944Zm8.767 6.89-2.122-1.612a44.713 44.713 0 0 0-2.625-2.5c1.145.861 2.122 1.611 2.262 1.75 1.117.972 1.06.806 1.815 1.445l.921.666a1.06 1.06 0 0 1-.251.25Zm.558.416-.056-.028c.084-.055.168-.111.252-.194l-.196.222ZM1.089 5.75c.055.361.14.722.195 1.056.335 1.833.67 3.5 1.284 4.75l.252.944c.084.361.223.806.363.917 1.424 1.25 3.602 3.11 5.947 4.889a.295.295 0 0 0 .363 0s0 .027.028.027a.254.254 0 0 0 .196.084.318.318 0 0 0 .223-.084c2.988-3.305 5.221-6.027 6.813-8.305.112-.111.14-.278.14-.417.111-.111.195-.25.307-.333.111-.111.111-.306 0-.39l-.028-.027c0-.055-.028-.139-.084-.167-.698-.666-1.2-1.138-1.731-1.638-.922-.862-1.871-1.75-3.881-3.75l-.028-.028c-.028-.028-.056-.056-.112-.056-.558-.194-1.703-.389-3.127-.639C6.087 2.223 3.21 1.723.614.944c0 0-.168 0-.196.028l-.083.084c-.028.027-.056.055-.224.11h.056-.056c.028.167.028.278.084.473 0 .055.112.5.112.555l.782 3.556Zm15.496 3.278-.335-.334c.084.112.196.195.335.334Zm-3.546 4.666-.056.056c0-.028.028-.056.056-.056Zm-2.038-10c.168.167.866.834 1.033.973-.726-.334-2.54-1.167-3.379-1.445.838.167 1.983.334 2.346.472ZM1.424 2.306c.419.722.754 3.222 1.089 5.666-.196-.778-.335-1.555-.503-2.278-.251-1.277-.503-2.416-.838-3.416.056 0 .14 0 .252.028Zm-.168-.584c-.112 0-.223-.028-.307-.028 0-.027 0-.055-.028-.055.14 0 .223.028.335.083Zm-1.089.222c0-.027 0-.027 0 0ZM39.453 1.333c.028-.11-.558-.61-.363-.639.42-.027.42-.666 0-.666-.558.028-1.144.166-1.675.25-.977.194-1.982.389-2.96.61-2.205.473-4.383.973-6.561 1.557-.67.194-1.424.333-2.066.666-.224.111-.196.333-.084.472-.056.028-.084.028-.14.056-.195.028-.363.056-.558.083-.168.028-.252.167-.224.334 0 .027.028.083.028.11-1.173 1.556-2.485 3.195-3.909 4.945-1.396 1.611-2.876 3.306-4.356 5.056-4.719 5.5-10.052 11.75-15.943 17.25a.268.268 0 0 0 0 .389c.028.027.056.055.084.055-.084.084-.168.14-.252.222-.056.056-.084.111-.084.167a.605.605 0 0 0-.111.139c-.112.111-.112.305.028.389.111.11.307.11.39-.028.029-.028.029-.056.056-.056a.44.44 0 0 1 .615 0c.335.362.67.723.977 1.028l-.698-.583c-.112-.111-.307-.083-.39.028-.113.11-.085.305.027.389l7.427 6.194c.056.056.112.056.196.056s.14-.028.195-.084l.168-.166c.028.027.083.027.111.027.084 0 .14-.027.196-.083 10.052-10.055 18.15-17.639 27.42-24.417.083-.055.111-.166.111-.25.112 0 .196-.083.251-.194 1.704-5.194 2.039-9.806 2.15-12.083v-.028c0-.028.028-.056.028-.083.028-.056.028-.084.028-.084a1.626 1.626 0 0 0-.111-1.028ZM21.472 9.5c.446-.5.893-1.028 1.34-1.5-2.876 3.778-7.65 9.583-14.408 16.5 4.607-5.083 9.242-10.333 13.068-15ZM5.193 35.778h.084-.084Zm3.462 3.194c-.027-.028-.027-.028 0-.028v.028Zm4.16-3.583c.224-.25.448-.472.699-.722 0 0 0 .027.028.027-.252.223-.475.445-.726.695Zm1.146-1.111c.14-.14.279-.334.446-.5l.028-.028c1.648-1.694 3.351-3.389 5.082-5.111l.028-.028c.419-.333.921-.694 1.368-1.028a379.003 379.003 0 0 0-6.952 6.695ZM24.794 6.472c-.921 1.195-1.954 2.778-2.82 4.028-2.736 3.944-11.532 13.583-11.727 13.75a1976.983 1976.983 0 0 1-8.042 7.639l-.167.167c-.14-.167-.14-.417.028-.556C14.49 19.861 22.03 10.167 25.074 5.917c-.084.194-.14.36-.28.555Zm4.83 5.695c-1.116-.64-1.646-1.64-1.34-2.611l.084-.334c.028-.083.084-.194.14-.277.307-.5.754-.917 1.257-1.167.027 0 .055 0 .083-.028-.028-.056-.028-.139-.028-.222.028-.167.14-.278.335-.278.335 0 1.369.306 1.76.639.111.083.223.194.335.305.14.167.363.445.474.667.056.028.112.306.196.445.056.222.111.472.084.694-.028.028 0 .194-.028.194a2.668 2.668 0 0 1-.363 1.028c-.028.028-.028.056-.056.084l-.028.027c-.14.223-.335.417-.53.556-.643.444-1.369.583-2.095.389 0 0-.195-.084-.28-.111Zm8.154-.834a39.098 39.098 0 0 1-.893 3.167c0 .028-.028.083 0 .111-.056 0-.084.028-.14.056-2.206 1.61-4.356 3.305-6.506 5.028 1.843-1.64 3.686-3.306 5.613-4.945.558-.5.949-1.139 1.06-1.861l.28-1.667v-.055c.14-.334.67-.195.586.166Z",
@@ -45288,7 +46068,7 @@ var LogoIcon = () => /* @__PURE__ */ jsx142(
45288
46068
  )
45289
46069
  }
45290
46070
  );
45291
- var LogoText = () => /* @__PURE__ */ jsxs70(
46071
+ var LogoText = () => /* @__PURE__ */ jsxs71(
45292
46072
  "svg",
45293
46073
  {
45294
46074
  viewBox: "0 0 450 55",
@@ -45296,28 +46076,28 @@ var LogoText = () => /* @__PURE__ */ jsxs70(
45296
46076
  fill: "none",
45297
46077
  className: "ExcalidrawLogo-text",
45298
46078
  children: [
45299
- /* @__PURE__ */ jsx142(
46079
+ /* @__PURE__ */ jsx143(
45300
46080
  "path",
45301
46081
  {
45302
46082
  d: "M429.27 96.74c2.47-1.39 4.78-3.02 6.83-4.95 1.43-1.35 2.73-2.86 3.81-4.51-.66.9-1.4 1.77-2.23 2.59-2.91 2.84-5.72 5.09-8.42 6.87h.01ZM343.6 69.36c.33 3.13.58 6.27.79 9.4.09 1.37.18 2.75.25 4.12-.12-4.46-.27-8.93-.5-13.39-.11-2.08-.24-4.16-.4-6.24-.06 1.79-.11 3.85-.13 6.11h-.01ZM378.47 98.34c.01-.37.07-1.13.01-6.51-.11 1.9-.22 3.81-.31 5.71-.07 1.42-.22 2.91-.16 4.35.39.03.78.07 1.17.1-.92-.85-.76-2.01-.72-3.66l.01.01ZM344.09 86.12c-.09-2.41-.22-4.83-.39-7.24v12.21c.15-.05.32-.09.47-.14.05-1.61-.03-3.23-.09-4.83h.01ZM440.69 66.79c-.22-.34-.45-.67-.69-.99-3.71-4.87-9.91-7.14-15.65-8.55-1.05-.26-2.12-.49-3.18-.71 2.29.59 4.48 1.26 6.64 2.02 7.19 2.54 10.57 5.41 12.88 8.23ZM305.09 72.46l1.2 3.6c.84 2.53 1.67 5.06 2.46 7.61.24.78.5 1.57.73 2.36.22-.04.44-.08.67-.12a776.9 776.9 0 0 1-5.01-13.57c-.02.04-.03.09-.05.13v-.01ZM345.49 90.25v.31c1.48-.42 3.05-.83 4.66-1.2-1.56.25-3.12.52-4.66.89ZM371.02 90.22c0-.57-.04-1.14-.11-1.71-.06-.02-.12-.04-.19-.05-.21-.05-.43-.08-.65-.11.42.16.74.88.95 1.87ZM398.93 54.23c-.13 0-.27-.01-.4-.02l.03.4c.11-.15.23-.27.37-.38ZM401.57 62.28v-.15c-1.22-.24-2.86-.61-3.23-1.25-.09-.15-.18-.51-.27-.98-.09.37-.2.73-.33 1.09 1.24.56 2.52.98 3.83 1.29ZM421.73 88.68c-2.97 1.65-6.28 3.12-9.69 3.68v.18c4.72-.14 11.63-3.85 16.33-8.38-2.04 1.75-4.33 3.24-6.63 4.53l-.01-.01ZM411.28 80.92c-.05-1.2-.09-2.4-.15-3.6-.21 5.66-.46 11.38-.47 14.51.24-.02.48-.04.71-.07.15-3.61.05-7.23-.09-10.83v-.01Z",
45303
46083
  transform: "translate(-144.023 -51.76)"
45304
46084
  }
45305
46085
  ),
45306
- /* @__PURE__ */ jsx142(
46086
+ /* @__PURE__ */ jsx143(
45307
46087
  "path",
45308
46088
  {
45309
46089
  d: "M425.38 67.41c-3.5-1.45-7.19-2.57-14.06-3.62.09 1.97.06 4.88-.03 8.12.03.04.06.09.06.15.19 1.36.28 2.73.37 4.1.25 3.77.39 7.55.41 11.33 0 1.38-.01 2.76-.07 4.13 1.4-.25 2.78-.65 4.12-1.15 4.07-1.5 7.94-3.78 11.28-6.54 2.33-1.92 5.13-4.49 5.88-7.58.63-3.53-2.45-6.68-7.97-8.96l.01.02ZM411.35 92.53v-.06l-.34.03c.11.01.22.03.34.03ZM314.26 64.06c-.23-.59-.47-1.17-.7-1.75.57 1.62 1.11 3.25 1.6 4.9l.15.54 2.35 6.05c.32.82.66 1.64.98 2.46-1.38-4.1-2.83-8.17-4.39-12.2h.01ZM156.82 103.07c-.18.13-.38.23-.58.33 1.32-.03 2.66-.2 3.93-.34.86-.09 1.72-.22 2.58-.33-2.12.1-4.12.17-5.94.34h.01ZM210.14 68.88s.03.04.05.07c.18-.31.39-.64.58-.96-.21.3-.42.6-.64.89h.01ZM201.65 82.8c-.5.77-1.02 1.56-1.49 2.37 1.11-1.55 2.21-3.1 3.2-4.59-.23.23-.49.51-.75.79-.32.47-.65.95-.96 1.43ZM194.03 98.66c-.33-.4-.65-.84-1.05-1.17-.24-.2-.07-.49.17-.56-.23-.26-.42-.5-.63-.75 1.51-2.55 3.93-5.87 6.4-9.28-.17-.08-.29-.28-.2-.49.04-.09.09-.17.13-.26-1.21 1.78-2.42 3.55-3.61 5.33-.87 1.31-1.74 2.64-2.54 4-.29.5-.63 1.04-.87 1.61.81.65 1.63 1.27 2.47 1.88-.09-.11-.18-.21-.27-.32v.01ZM307.79 82.93c-1-3.17-2.05-6.32-3.1-9.48-1.62 4.08-3.69 9.17-6.16 15.19 3.32-1.04 6.77-1.87 10.27-2.5-.32-1.08-.67-2.15-1.01-3.21ZM149.5 80.7c.05-1.71.04-3.43 0-5.14-.1 2.26-.16 4.51-.22 6.77-.02.73-.03 1.46-.04 2.19.14-1.27.2-2.55.24-3.82h.02ZM228.98 98.3c.39 1.25.91 3.03.94 3.91.06-.03.12-.07.17-.1.08-1.29-.55-2.65-1.11-3.81ZM307.72 53.36c.81.5 1.53 1.04 2.07 1.49-.38-.8-.78-1.58-1.21-2.35-.17.03-.34.06-.51.11-.43.12-.86.26-1.29.41.35-.01.53.1.94.34ZM283.69 96.14c3.91-7.25 6.89-13.35 8.88-18.15l1.1-2.66c-1.27 2.64-2.56 5.27-3.83 7.9-1.53 3.15-3.06 6.31-4.58 9.47-.87 1.81-1.76 3.62-2.54 5.47.04.02.07.04.11.07.05.05.1.09.15.14.05-.73.27-1.48.71-2.24ZM289.92 103.23s-.04.01-.05.03c0-.02.04-.03.05-.04.05-.05.11-.1.16-.15l.21-.21c-.55 0-1.5-.27-2.55-.72.4.26.8.51 1.22.74.24.13.48.26.73.37.05.02.1.03.14.05a.27.27 0 0 1 .08-.07h.01ZM269.23 68.49c-.39-.19-.82-.48-1.33-.87-3.06-1.56-6.31-2.78-9.36-2.35-3.5.49-5.7 1.11-7.74 2.44 5.71-2.6 12.82-2.07 18.44.79l-.01-.01ZM177.87 53.69l1.06.03c-.96-.22-2-.25-2.89-.3-4.95-.26-9.99.33-14.86 1.19-2.44.43-4.88.95-7.28 1.59 9.09-1.76 15.69-2.77 23.97-2.51ZM219.85 55.51c-.18.12-.36.27-.56.45-.45.53-.86 1.11-1.26 1.66-1.91 2.61-3.71 5.31-5.57 7.95l-.12.18 8.05-10.11c-.18-.05-.36-.1-.55-.13h.01ZM510.71 54.1c.12-.15.29-.3.53-.45.69-.4 3.72-.63 5.87-.74-.36-.02-.73-.04-1.09-.05-1.84-.03-3.67.09-5.49.35.05.3.12.59.18.88v.01ZM510.76 86.02c1.37-3.07 2.49-6.27 3.57-9.46.55-1.64 1.12-3.3 1.6-4.97-1.59 4.01-3.67 9.14-6.2 15.3.24-.08.5-.14.74-.22.1-.22.19-.44.29-.65ZM566.95 75.76c.11-.02.23.03.31.11-.05-.13-.09-.26-.14-.39-.05.09-.11.18-.17.28ZM511.33 86.41c3.08-.89 6.24-1.62 9.46-2.14-1.51-3.98-2.98-7.96-4.39-11.87-.05.15-.09.31-.14.46-1.02 3.32-2.15 6.61-3.39 9.85-.48 1.25-.98 2.49-1.53 3.7h-.01ZM578.24 74.45c.11-.44.23-.87.35-1.31-.31.7-.64 1.39-.97 2.08.09.21.19.4.28.61.12-.46.23-.92.35-1.38h-.01ZM520.62 53.11c-.09 0-.18-.01-.28-.02.38.34.29 1.08.93 2.53l6.65 17.15c2.2 5.68 4.69 11.36 7.41 16.87l1.06 2.17c-2.95-7.05-5.92-14.08-8.87-21.13-1.58-3.79-3.16-7.59-4.7-11.4-.78-1.92-1.73-3.89-2.25-5.91-.03-.1 0-.19.04-.26h.01ZM578.78 77.87c1.45-5.77 3.07-10.43 3.58-13.36.05-.34.16-.88.31-1.55-.67 1.79-1.37 3.56-2.08 5.33-.12.43-.23.86-.35 1.29-.65 2.43-1.29 4.86-1.9 7.3.14.33.29.65.43 1l.01-.01ZM545.3 94.66c.02-.44.03-.83.05-1.12.02-1.01.05-2.02.11-3.02.03-6.66-.46-14.33-1.46-22.8-.13-.42-.27-1.24-.56-2.89 0-.02 0-.04-.01-.06.62 6.61.95 13.25 1.32 19.87.17 3.08.33 6.16.52 9.23.02.25.03.52.04.78l-.01.01ZM580.77 102.81c.13.2.27.38.37.49.27-.11.53-.22.8-.32-.43.09-.82.05-1.17-.16v-.01ZM530.48 104.07h.33c-.36-.13-.71-.32-1.04-.56.14.24.3.47.45.7.06-.08.14-.13.26-.13v-.01ZM542.63 58.82c.06.23.11.47.15.71.14-.33.36-.62.7-.86-.28.05-.57.11-.85.15ZM583.81 57.87c.15-.7.29-1.41.42-2.11-.14.45-.28.9-.42 1.34-.46 1.44-.89 2.89-1.31 4.34.44-1.19.88-2.37 1.31-3.57ZM523.62 91.48c-4.66 1.17-9.05 2.89-14.02 5.27 4.65-1.84 9.48-3.29 14.28-4.63-.09-.22-.17-.41-.26-.64ZM460.64 78.3c-.04-2.9-.11-5.81-.28-8.71-.1-1.68-.17-3.43-.5-5.09-.07.02-.14.03-.2.05.3 6.54.45 12.17.51 17.12.17-.07.34-.14.51-.2 0-1.06-.01-2.11-.03-3.17h-.01ZM470.63 63.24c-3.38-.26-6.81.32-10.1 1.1.41 2.01.47 4.14.57 6.18.18 3.55.25 7.11.27 10.67 3.31-1.38 6.5-3.12 9.3-5.35 1.96-1.56 3.86-3.41 5.02-5.66.73-1.41 1.19-3.22.26-4.65-1.09-1.7-3.46-2.14-5.32-2.29ZM460.29 63.68c1-.24 2.01-.46 3.04-.65-1.15.16-2.37.38-3.71.69v.13c.07-.02.15-.04.22-.05.11-.13.3-.18.45-.11v-.01ZM457.24 100.96c.43-.03.86-.07 1.29-.11.14-.49.27-.99.38-1.49-.44.7-1 1.23-1.67 1.6ZM482.88 104.98c-.18.23-.36.38-.55.47.14.09.27.19.4.28a70.76 70.76 0 0 0 4.37-4.63c.76-.89 1.52-1.81 2.19-2.77-.3-.27-.61-.53-.92-.79-.07 1.94-4.62 6.32-5.49 7.45v-.01Z",
45310
46090
  transform: "translate(-144.023 -51.76)"
45311
46091
  }
45312
46092
  ),
45313
- /* @__PURE__ */ jsx142(
46093
+ /* @__PURE__ */ jsx143(
45314
46094
  "path",
45315
46095
  {
45316
46096
  d: "M474.36 63.31c-.4-.16-.84-.27-1.29-.37 1.56.42 3.08 1.22 3.76 2.74.62 1.4.32 2.95-.28 4.32.7-1.22.94-2.34.74-3.47-.24-1.33-1.19-2.54-2.93-3.21v-.01ZM477.34 89.18c-1.2-.81-2.4-1.62-3.6-2.42-.14.1-.26.19-.4.29 1.4.67 2.73 1.39 4 2.13ZM465.88 93.85c.37.25.74.5 1.1.75.46.32.92.65 1.38.97-1.57-1.2-2.01-1.61-2.49-1.72h.01ZM574.92 90.06c-2.28-5.21-4.93-11.13-5.67-12.26-.1-.15-1.57-3.01-1.63-3.08 0 0-.01.02-.02.02.4 1.37 1.09 2.69 1.65 3.99 2.14 4.95 4.36 9.86 6.67 14.73.6 1.26 1.21 2.52 1.83 3.78-.75-2.01-1.64-4.45-2.83-7.18ZM448.73 65.29c.1.2.22.38.34.57.22-.02.43-.06.65-.08v-.08c-.14-.05-.25 0-.99-.41ZM460.16 94.81c-.02.31-.06.59-.1.89-.03 1.71-.33 3.43-.79 5.07.15-.02.3-.03.45-.05.01-.04.02-.08.03-.11.09-.34.15-.69.2-1.03.17-1.07.25-2.16.33-3.24.05-.69.08-1.39.12-2.08-.27.1-.27.26-.24.57v-.02Z",
45317
46097
  transform: "translate(-144.023 -51.76)"
45318
46098
  }
45319
46099
  ),
45320
- /* @__PURE__ */ jsx142(
46100
+ /* @__PURE__ */ jsx143(
45321
46101
  "path",
45322
46102
  {
45323
46103
  d: "m328.67 98.12-3.22-6.58c-1.29-2.63-2.53-5.29-3.72-7.97-.25-.85-.52-1.69-.79-2.53-.81-2.57-1.67-5.12-2.55-7.67-1.92-5.53-3.9-11.08-6.32-16.41-.72-1.58-1.46-3.44-2.63-4.79-.03-.17-.16-.29-.34-.36a.282.282 0 0 0-.23-.04c-.06-.01-.12 0-.18.01-.74.06-1.5.38-2.19.61-2.22.77-4.4 1.64-6.63 2.38-.03-.08-.06-.16-.09-.25-.15-.42-.82-.24-.67.19.03.09.07.19.1.28l-.18.06c-.36.11-.28.6 0 .68.18 1.18.63 2.36.98 3.49.03.09.06.17.08.26-.08.23-.17.46-.24.64-.37.98-.79 1.94-1.21 2.9-1.27 2.89-2.62 5.75-3.98 8.6-3.18 6.67-6.44 13.31-9.64 19.97-1.08 2.25-2.2 4.5-3.15 6.81-.13.32.24.5.5.37 1.34 1.33 2.84 2.5 4.4 3.57.65.44 1.31.87 2.01 1.24.4.22.86.48 1.33.5.24.01.35-.19.33-.37.11-.1.21-.21.28-.28.41-.41.81-.84 1.2-1.26.85-.92 1.69-1.87 2.5-2.84 6.31-2.34 12.6-4.31 18.71-5.84 2.14 5.3 3.43 8.43 3.97 9.58.55 1.05 1.15 1.88 1.82 2.52 1.32.56 6.96-.03 9.23-1.96.87-1.28 1.19-2.67.93-4.15-.09-.5-.22-.95-.4-1.33l-.01-.03Zm-20.09-45.61c.43.77.83 1.56 1.21 2.35-.54-.45-1.27-.99-2.07-1.49-.42-.24-.6-.35-.94-.34.43-.15.85-.29 1.29-.41.17-.05.34-.08.51-.11Zm-25.86 45.66c.78-1.85 1.67-3.66 2.54-5.47 1.51-3.16 3.05-6.31 4.58-9.47 1.28-2.63 2.56-5.26 3.83-7.9l-1.1 2.66c-1.99 4.79-4.97 10.9-8.88 18.15-.43.76-.66 1.51-.71 2.24-.05-.05-.1-.09-.15-.14a.259.259 0 0 0-.11-.07Zm6.24 4.71c-.42-.23-.82-.48-1.22-.74 1.05.45 2 .72 2.55.72l-.21.21c-.05.05-.11.1-.16.15-.01.01-.04.03-.05.04 0-.02.03-.02.05-.03a.27.27 0 0 0-.08.07c-.05-.02-.1-.03-.14-.05-.25-.1-.49-.24-.73-.37h-.01Zm15.73-29.43c1.05 3.15 2.1 6.31 3.1 9.48.34 1.06.69 2.13 1.01 3.21-3.5.63-6.95 1.46-10.27 2.5 2.48-6.03 4.54-11.11 6.16-15.19Zm4.79 12.57c-.23-.79-.49-1.58-.73-2.36-.79-2.54-1.63-5.08-2.46-7.61l-1.2-3.6c.02-.04.04-.09.05-.13 1.6 4.45 3.28 9 5.01 13.57l-.67.12v.01Zm5.83-18.27-.15-.54c-.49-1.64-1.03-3.28-1.6-4.9.23.58.47 1.17.7 1.75 1.56 4.03 3.01 8.1 4.39 12.2-.33-.82-.67-1.64-.98-2.46l-2.35-6.05h-.01ZM390.43 79.37c-.13-10.43-.22-17.5-.24-19.97-.24-1.6.21-2.88-.65-3.65-.14-.13-.32-.23-.52-.32h.03c.45 0 .45-.69 0-.7-1.75-.03-3.5-.04-5.25-.14-1.38-.08-2.76-.21-4.15-.31-.07 0-.12.01-.17.04-.21-.07-.47.03-.45.31l.03.45c-.11.14-.19.3-.22.5-.21 1.26-.32 13.67-.36 23.59-.32 5.79-.67 11.57-.97 17.36-.09 1.73-.29 3.54-.21 5.3-.39.02-.38.64.04.69v.12c.05.44.74.45.7 0v-.06c1.1.09 2.2.21 3.3.3 1.14.19 2.44.2 3.29.17 1.73-.05 2.92-.05 3.8-.37.45-.05.9-.11 1.35-.17.44-.06.25-.73-.19-.67h-.01c.24-.32.45-.72.62-1.25.66-1.84.41-6.36.34-11.33l-.13-9.9.02.01Zm-12.26 18.17c.09-1.91.2-3.81.31-5.71.06 5.38 0 6.14-.01 6.51-.05 1.65-.21 2.81.72 3.66-.39-.04-.78-.07-1.17-.1-.06-1.44.09-2.93.16-4.35l-.01-.01ZM588.97 53.85c-2.06-.25-3.17-.51-3.76-.6a.3.3 0 0 1 .04-.08c.22-.39-.39-.75-.6-.35-.56 1.02-.9 2.19-1.26 3.29-.61 1.88-1.17 3.78-1.72 5.68-.63 2.19-1.24 4.39-1.83 6.59-.81 2.03-1.67 4.05-2.61 6.03-1.7-3.64-3.11-6.04-4.03-7.57-2.26-3.74-2.85-5.48-3.57-6.08l.31-.09c.43-.12.25-.8-.19-.67-1.06.3-2.12.6-3.17.95-.93.32-1.85.69-2.76 1.07-.13.05-.19.16-.22.27-.04.02-.08.05-.11.07-.04-.06-.07-.12-.11-.18a.354.354 0 0 0-.48-.12c-.16.09-.22.32-.13.48l.33.54c0 .09.02.18.06.28.51 1.16.78 1.38.72 1.47-2.42 3.44-5.41 7.86-6.2 9.1-1.27 1.97-2.01 3.14-2.45 3.84l-.91-6.56-.43-4.1c-.19-1.85-.37-3.23-.53-4.13-.19-1.1-.3-2.15-.45-3.16-.2-1.36-.29-2.06-.47-2.42h.04c.45.02.45-.68 0-.7-3.43-.16-6.81.94-10.17 1.48-.24-.22-.73-.04-.58.32.24.59.33 1.25.43 1.87.17 1.06.29 2.13.4 3.2.32 3.09.53 6.2.74 9.3.44 6.75.77 13.51 1.17 20.26.11 1.95.13 3.96.46 5.89.05.3.37.31.55.14.74 1.71 2.87 1.27 6.13 1.27 1.34 0 2.39.04 2.99-.11.02.32.48.53.63.18 3.61-8.26 7.41-16.46 12.05-24.2.03-.05.04-.1.05-.15.3.73.64 1.45.94 2.16.97 2.26 1.97 4.52 2.98 6.76 2.26 5.03 4.54 10.07 7.09 14.96.47.9.94 1.79 1.47 2.65.2.32.4.67.66.96-.18.25 0 .68.34.54.91-.38 1.82-.75 2.76-1.07 1.04-.35 2.11-.65 3.17-.95.39-.11.28-.66-.07-.68.62-.4.95-.96.87-1.91-.3-3.34.72-7.47.86-8.52l2.14-11.43c1.75-10.74 3.13-17.51 3.23-20.86.02-.49.08-2.84.13-3.24.17-1.25.48-1-4.96-1.65l.03-.02Zm-46.19 5.67c-.04-.24-.09-.48-.15-.71l.85-.15c-.34.24-.56.53-.7.86Zm1.95 25.12c-.36-6.63-.7-13.26-1.32-19.87 0 .02 0 .04.01.06.29 1.65.44 2.47.56 2.89 1 8.46 1.5 16.14 1.46 22.8-.06.99-.1 2-.11 3.02-.01.29-.03.68-.05 1.12-.01-.26-.03-.53-.04-.78-.19-3.08-.35-6.16-.52-9.23l.01-.01Zm36.4 18.66c-.11-.11-.24-.29-.37-.49.35.21.74.26 1.17.16-.27.11-.53.22-.8.32v.01Zm-.89-33.72c.12-.43.23-.86.35-1.29.71-1.77 1.41-3.55 2.08-5.33-.15.68-.26 1.22-.31 1.55-.5 2.94-2.13 7.59-3.58 13.36-.15-.35-.29-.66-.43-1 .61-2.44 1.25-4.87 1.9-7.3l-.01.01Zm3.56-12.48c.14-.44.28-.89.42-1.34-.13.7-.27 1.41-.42 2.11-.43 1.19-.86 2.38-1.31 3.57.42-1.45.85-2.9 1.31-4.34Zm-5.22 16.05c-.11.44-.23.87-.35 1.31-.12.46-.23.92-.35 1.38-.1-.22-.19-.4-.28-.61.34-.69.66-1.38.97-2.08h.01Zm-11.64 2.62c.06-.1.12-.19.17-.28.05.13.09.26.14.39a.398.398 0 0 0-.31-.11Zm2.3 2.98c-.56-1.3-1.25-2.63-1.65-3.99 0 0 .01-.02.02-.02.06.08 1.52 2.93 1.63 3.08.73 1.13 3.38 7.04 5.67 12.26 1.2 2.73 2.08 5.17 2.83 7.18-.62-1.25-1.23-2.51-1.83-3.78-2.31-4.87-4.53-9.78-6.67-14.73ZM275.92 87.03c-1.06-2.18-1.13-3.45-2.44-2.93-1.52.57-2.94 1.3-4.5 2.1-1.4.72-2.68 1.44-3.92 2.12.01-.25-.24-.5-.51-.34-4.8 2.93-12.41 4.7-17.28 1.31-1.98-1.77-3.32-4.15-3.97-5.78-.29-.95-.49-1.94-.63-2.93-.14-3.34 1.58-6.53 3.9-9.12.8-.79 1.68-1.51 2.66-2.12 3.7-2.3 8.22-3.07 12.51-2.51 2.71.35 5.32 1.24 7.71 2.55.39.22.75-.39.35-.6-.18-.1-.37-.18-.55-.27.56.27 1.03.33 1.51.19l-.48.39c-.15.11-.23.3-.13.48.09.15.33.24.48.13 1.3-.97 2.46-2.09 3.45-3.37.37-.29.64-.6.65-.97v-.02c.08-.33-.03-.7-.21-1.08-.31-.87-.98-2.01-2.19-3.26-2.43-2.52-3.79-3.45-5.68-4.26-1.14-.49-3.12-1.06-4.42-1.23-3.28-.42-10.64-1.21-18.18 4.11-7.74 5.46-11.94 12.3-12.23 20.61-.08 2.06.04 3.98.34 5.71.74 4.18 2.57 8 5.44 11.34 4.26 4.99 9.76 7.52 16.34 7.52 4.85 0 9.69-1.77 14.89-4.62.23-.12.45-.23.68-.35 2.19-1.1 4.37-2.23 6.46-3.5.49-.3 1.03-.61 1.5-.98 1.47-.87 1.11-1.12.49-2.95-.39-1.14-.76-2.7-2.06-5.36l.02-.01Zm-17.38-21.76c3.05-.42 6.31.79 9.36 2.35.51.39.94.68 1.33.87-5.61-2.86-12.72-3.39-18.44-.79 2.05-1.33 4.24-1.95 7.74-2.44l.01.01ZM443.67 72.67c-.4-2.2-1.15-4.33-2.37-6.22-1.49-2.32-3.58-4.19-5.91-5.64-6.17-3.81-13.75-5.11-20.83-6.01-3.23-.41-6.47-.69-9.72-.92l-1.39-.12c-.85-.07-1.52-.1-2.05-.1-1.08-.06-2.17-.12-3.25-.17-.08 0-.14.02-.19.05-.1.05-.18.14-.16.3.27 2.55-.01 5.12-.92 7.52-.15.38.4.56.62.28 1.32.59 2.68 1.05 4.08 1.37 0 2.78-.14 7.58-.33 12.91 0 0 0 .02-.01.03-.61 3.66-.79 7.42-1 11.12-.23 4.01-.43 8.03-.44 12.05 0 .64 0 1.28.03 1.93.02.31 0 .68.15.96.06.11.14.16.24.17-.2.17-.21.54.11.59 3.83.67 7.78.71 11.68.25 2.3-.19 4.87-.65 7.65-1.56 1.85-.54 3.67-1.18 5.43-1.91 7.2-3.02 14.31-8.07 17.35-15.53.76-1.86 1.17-3.8 1.31-5.75.3-1.93.28-3.82-.09-5.58l.01-.02Zm-19.32-15.42c5.74 1.41 11.94 3.68 15.65 8.55.25.32.47.65.69.99-2.3-2.82-5.68-5.69-12.88-8.23-2.16-.76-4.35-1.43-6.64-2.02 1.06.21 2.13.45 3.18.71Zm-25.82-3.04c.13 0 .27.01.4.02-.14.1-.26.23-.37.38 0-.13-.02-.26-.03-.4Zm34.82 22.17c-.75 3.09-3.55 5.66-5.88 7.58-3.35 2.76-7.21 5.03-11.28 6.54-1.33.49-2.71.9-4.12 1.15.06-1.38.08-2.76.07-4.13-.02-3.78-.16-7.56-.41-11.33-.09-1.37-.18-2.74-.37-4.1 0-.06-.03-.11-.06-.15.09-3.25.12-6.16.03-8.12 6.86 1.05 10.56 2.17 14.06 3.62 5.52 2.28 8.59 5.44 7.97 8.96l-.01-.02Zm-22 16.15c-.12 0-.23-.02-.34-.03l.34-.03v.06Zm-.69-.7c0-3.13.26-8.84.47-14.51.06 1.2.11 2.41.15 3.6.15 3.6.25 7.23.09 10.83-.24.03-.48.05-.71.07v.01Zm-12.33-30.94c.37.63 2.01 1.01 3.23 1.25v.15c-1.31-.31-2.59-.73-3.83-1.29.12-.36.23-.72.33-1.09.08.48.18.84.27.98Zm13.7 31.65v-.18c3.41-.56 6.71-2.02 9.69-3.68 2.31-1.28 4.59-2.78 6.63-4.53-4.69 4.53-11.61 8.24-16.33 8.38l.01.01Zm24.07-.75c-2.05 1.93-4.37 3.56-6.83 4.95 2.7-1.78 5.52-4.03 8.42-6.87.82-.82 1.56-1.69 2.23-2.59-1.08 1.65-2.38 3.16-3.81 4.51h-.01ZM187.16 92.14c-.79-2.47-2.1-7.12-3.1-6.87-.19-.01-2.09.77-4.08 1.54-3.06 1.18-5.91 2.13-10.09 2.82-2.74.42-5.87 1.01-10.61 1.06.04-3.34.05-6.01.05-7.99 7.97-.65 12.33-2.11 16.37-3.55 1.11-.39 2.69-1.01 2.63-1.8-.08-.35-.55-1.39-1.17-2.61-.47-1.16-.98-2.31-1.61-3.38-.42-.71-1.04-1.69-1.86-2.06-.11-.08-.22-.13-.29-.12-.02 0-.04 0-.07.01-.19-.04-.39-.05-.6-.01-.17.03-.24.15-.25.28-.04.02-.09.04-.14.05-4.33 1.48-8.85 2.33-13.24 3.61a499.1 499.1 0 0 0-.31-8.19c4.51-.99 8.88-1.38 13.11-1.82 3.68-.38 6.28.12 7.47.34.59.11.9.16 1.16.18h.1c-.1.37.44.66.62.28.02-.04.03-.08.05-.13.15.2.53.22.62-.1.17-.58.19-1.21.21-1.81v-.36c.03-.15.05-.3.07-.45.52-2.47.33-5.09-.64-7.44-.11-.27-.44-.28-.6-.14-.08-.21-.15-.42-.24-.62-.19-.41-.79-.05-.6.35.03.07.05.15.09.22-.98-.42-2.15-.54-3.17-.63-2.17-.19-4.37-.14-6.54 0-5.7.35-11.4 1.3-16.91 2.79-2.08.56-4.13 1.22-6.14 2-4.54 1.05-3.79 1.51-2.17 6.07.18.51.46 1.68.54 1.94.82 2.47 1.08 2.13 3.1 2.13s0 .05 0 .08h.52c-.48 2.66-.51 5.45-.62 8.13-.15 3.48-.22 6.96-.28 10.45 0 .41-.01.82-.02 1.23-.16.29-.33.57-.51.85-.05.38-.09.77-.14 1.18-.42 3.52-.59 6.48-.52 8.8v.34c.02.47.05.76.06.87.16 1.57-.26 3.47 1.35 3.79 1.61.32 3.5.55 4.85.55.11 0 .22-.02.33-.02 1.79.24 3.67.05 5.45-.12 2.85-.28 5.69-.7 8.51-1.19 3.03-.53 6.05-1.14 9.04-1.86 2.4-.58 4.82-1.19 7.13-2.06.51-.19 1.73-.57 2.46-1.14 1.81-.68 2.18-1 1.57-2.67-.23-.62-.48-1.49-.91-2.78l-.03-.02Zm-11.12-38.71c.89.05 1.93.08 2.89.3-.33 0-.68-.02-1.06-.03-8.28-.26-14.88.75-23.97 2.51 2.41-.64 4.85-1.16 7.28-1.59 4.87-.86 9.91-1.45 14.86-1.19Zm-26.53 22.13c.03 1.71.04 3.43 0 5.14-.04 1.27-.11 2.55-.24 3.82 0-.73.02-1.46.04-2.19.05-2.26.12-4.51.22-6.77h-.02Zm6.73 27.85c.2-.1.4-.21.58-.33 1.82-.17 3.82-.24 5.94-.34-.86.11-1.72.24-2.58.33-1.27.14-2.61.31-3.93.34h-.01ZM534.48 85.44c-3.52-8.38-7.07-16.75-10.5-25.17-.63-1.54-1.25-3.09-1.86-4.65-.31-.8-.65-1.6-.87-2.43-.04-.17-.17-.24-.31-.25.1-.2 0-.51-.29-.53-1.59-.08-3.18-.22-4.78-.25-1.96-.03-3.91.13-5.84.42-.31.05-.31.38-.13.56-.03.06-.05.14-.04.22.23 1.54.63 3.06 1.16 4.53.13.35.27.7.41 1.06l-2.68 6.18c-.11.03-.2.09-.25.22-.67 1.9-1.52 3.73-2.34 5.56a536.85 536.85 0 0 1-3.9 8.45c-2.64 5.64-5.34 11.25-7.91 16.93-.44.97-.88 1.94-1.29 2.93-.2.48-.47 1-.55 1.52v.05c-.02.12.02.26.16.34 1.19.73 2.41 1.41 3.66 2.05 1.2.62 2.45 1.25 3.76 1.61.43.12.62-.55.19-.67-1.13-.31-2.2-.83-3.24-1.36 1.09.36 2.1.69 2.75.93 2.82 1.01 2.38 1.1 4.3-3.75 2.1-1.09 4.34-1.96 6.53-2.79 4.35-1.64 8.8-3.03 13.27-4.29.82 2.01 1.77 3.97 2.72 5.92.35.83.62 1.45.79 1.82.22.42.45.8.69 1.15.17.33.33.67.5 1 .42.8.84 1.63 1.4 2.35.23.29.6 0 .55-.31 1.53-.02 3.06-.07 4.58-.27.92-.12 1.82-.32 2.71-.54 1.39-.27 3.85-1.11 3.74-1.42-.67-1.96-1.55-3.87-2.34-5.78-1.57-3.78-3.16-7.56-4.75-11.33v-.01Zm-11.65-26.16c1.54 3.81 3.12 7.6 4.7 11.4 2.94 7.05 5.91 14.09 8.87 21.13l-1.06-2.17c-2.71-5.51-5.2-11.19-7.41-16.87l-6.65-17.15c-.65-1.45-.55-2.19-.93-2.53.09 0 .18.01.28.02a.29.29 0 0 0-.04.26c.52 2.02 1.47 3.98 2.25 5.91h-.01Zm-6.58 13.58c.05-.15.09-.31.14-.46 1.41 3.92 2.88 7.9 4.39 11.87-3.22.52-6.38 1.25-9.46 2.14.55-1.22 1.05-2.46 1.53-3.7 1.24-3.24 2.37-6.53 3.39-9.85h.01Zm-.23-20c.36 0 .73.03 1.09.05-2.15.1-5.18.33-5.87.74-.24.15-.41.3-.53.45-.06-.29-.13-.58-.18-.88 1.82-.26 3.65-.39 5.49-.35v-.01Zm-.09 18.72c-.49 1.67-1.05 3.33-1.6 4.97-1.07 3.19-2.19 6.38-3.57 9.46-.09.21-.19.43-.29.65-.25.07-.5.14-.74.22 2.53-6.16 4.61-11.29 6.2-15.3Zm-6.34 25.16c4.97-2.38 9.37-4.1 14.02-5.27l.26.64c-4.8 1.35-9.63 2.8-14.28 4.63Zm20.17 6.76c.33.23.68.42 1.04.56h-.33c-.12 0-.21.06-.26.13-.15-.23-.31-.45-.45-.7v.01ZM226.57 91.75c-3.55-4.74-6.68-9.11-9.31-12.99 9.2-15.25 10.05-17.81 10.35-18.38.17-.34 1.09-2.27.64-2.53-1.13-.65-1.03-.65-2.97-1.71-1.19-.65-3.04-1.61-4.53-2.12-1.71-.59-1.24-.36-3 2.77-.06.1-.11.2-.17.3-.75 1.02-1.48 2.05-2.2 3.09-1.88 2.71-3.73 5.45-5.69 8.1-3.68-4.91-6.88-8.76-9.51-11.43-.15-.15-.3-.29-.46-.42-1.27-1.28-7.24 3.53-7.93 5.58-.09.09-.19.16-.28.25-.27.26.03.64.33.58.19.65.5 1.29.94 1.91 3.85 5.06 7.19 9.76 9.94 14-1.23 2.61-3.06 5-4.67 7.38l-2.28 3.33c-.5.66-.93 1.23-1.29 1.69-.67.93-2.09 2.61-2.3 3.87-.51.85-1.16 1.84-1.29 2.83-.06.44.61.63.67.19.01-.08.04-.15.06-.22 1.36 1.08 2.76 2.11 4.19 3.11 1.3.91 2.62 1.85 4.04 2.56.21.1.4 0 .48-.17.24.07.48.14.72.2.44.1.62-.57.19-.67-2.02-.48-3.77-1.57-5.23-3.02-.47-.46-.9-.96-1.32-1.46 1.74 1.35 4.2 2.89 5.89 4.14 1.39 1.03 2.85-2.27 4.22-4.2 1.86-2.64 3.96-5.86 5.52-8.29l10.39 14.51c.67.81 1.14 1.21 1.57 1.36-.05.24.12.51.41.4 1.53-.58 3.05-1.19 4.54-1.87 1.52-.69 3.06-1.45 4.36-2.5a.28.28 0 0 0 .12-.23c1.66-1.1.81-1.74-1.41-4.91-1.13-1.58-1.71-2.36-3.7-5.01l-.03-.02Zm2.41 6.54c.56 1.15 1.19 2.52 1.11 3.81-.06.04-.12.07-.17.1-.03-.88-.55-2.66-.94-3.91Zm-16.51-32.73c1.86-2.65 3.65-5.35 5.57-7.95.4-.55.81-1.13 1.26-1.66.19-.18.38-.33.56-.45.18.03.36.08.55.13l-8.05 10.11.12-.18h-.01ZM192.7 95.48c.79-1.37 1.66-2.69 2.54-4 1.19-1.79 2.4-3.56 3.61-5.33-.04.09-.09.17-.13.26-.1.22.03.41.2.49-2.47 3.42-4.89 6.73-6.4 9.28.21.24.4.48.63.75-.24.07-.4.36-.17.56.4.33.72.77 1.05 1.17.09.11.18.21.27.32-.84-.61-1.66-1.24-2.47-1.88.24-.57.58-1.11.87-1.61v-.01Zm7.46-10.32c.47-.81.98-1.59 1.49-2.37.31-.48.64-.95.96-1.43.26-.29.52-.56.75-.79-.99 1.48-2.09 3.03-3.2 4.59Zm10.03-16.22s-.03-.05-.05-.07c.22-.29.43-.59.64-.89-.2.32-.4.65-.58.96h-.01ZM371.54 87.96c-.01-.08-.01-.16-.03-.23-.06-.38-.58-.29-.66.03-.3-.05-.6-.08-.81-.11-1.14-.15-2.29-.19-3.44-.2 1.04-.09 2.09-.18 3.14-.23.45-.02.45-.72 0-.7-6.57.35-13.14 1.23-19.65 2.11-1.53.21-3.05.42-4.57.68-.01 0-.02.01-.04.01-.04-3.33-.13-6.66-.24-9.99-.19-5.7-.4-11.41-.88-17.1-.13-1.51-.23-3.07-.49-4.58 0-.25 0-.48-.02-.68-.06-1.19-.04-2.61-.68-2.78-.16-.07-.72-.16-1.5-.24.22-.17.16-.62-.2-.63-1.19-.04-2.39.09-3.57.23-1.2.14-2.41.32-3.59.6-.16-.1-.41-.06-.5.12-.06.02-.13.03-.19.05-.35.1-.29.55-.03.66-.26.6-.19 2.27-.21 3-.02.66-.66 33.73-.9 40.3-.03.65.06 1.12.04 1.45-.16 3.05.87 4.96 6.34 3.93 1.09-.08 2.75-.77 5.36-1.43 4.13-1.04 5.78-1.52 6.2-1.65 6.43-1.69 6.78-1.97 11.72-2.43.55-.05 4.8-.38 6.03-.3.64.04 1.19.07 1.65.1.09 0 .16-.03.24-.05.1.27.56.33.66-.02.39-1.32.61-2.71.78-4.08.2-1.61.29-3.24.15-4.86.24.03.52-.23.38-.53-.09-.2-.27-.33-.49-.43v-.02Zm-.63.56c.07.57.11 1.14.11 1.71-.21-.99-.53-1.71-.95-1.87.22.03.44.06.65.11.06.01.12.04.19.05Zm-25.41 1.73c1.54-.36 3.1-.64 4.66-.89-1.61.37-3.18.77-4.66 1.2v-.31Zm-.86-7.37c-.07-1.37-.16-2.75-.25-4.12-.21-3.13-.45-6.27-.79-9.4.02-2.25.08-4.31.13-6.11.16 2.08.29 4.16.4 6.24.23 4.46.38 8.93.5 13.39h.01Zm-.94-4c.16 2.41.29 4.83.39 7.24.06 1.6.14 3.22.09 4.83-.15.05-.32.09-.47.14V78.88h-.01ZM483.72 92.83c-3.05-2.28-6.22-4.4-9.38-6.51 8.86-6.49 13.49-12.95 13.73-19.23.04-.76 0-1.5-.13-2.2-.67-3.82-3.5-6.68-8.39-8.48.13.04.27.08.4.13 3.92 1.39 7.74 4.23 8.5 8.56.34 1.95-.05 3.96-.98 5.69-.21.4.39.75.6.35 1.86-3.46 1.46-7.55-.97-10.63-3.53-4.47-9.76-5.88-15.16-6.16-2.32-.12-4.64-.04-6.95.19-6 .32-12.71 1.68-17.63 3.21-.37.11-.67.23-.92.35-.2-.17-.62.02-.57.37v.03c-.64.68-.18 1.64.48 3.21.38.91.67 1.89 1.15 2.58.32.76.68 1.51 1.13 2.19.14.21.38.19.53.07.19-.02.38-.05.57-.08v1.57c-.06.06-.1.13-.11.23-.27 4.18-.34 8.38-.48 12.57l-.3 9.03c-.24 3.91-.44 6.77-.46 7.26-.05.88-.11 1.95.07 2.81-.01.22-.02.43-.04.65 0 .11-.02.23-.03.35 0 .05-.03.27-.01.16-.05.4.5.59.64.28.05.04.12.08.2.08 1.75.13 3.5.28 5.25.3 1.69.02 3.38-.12 5.06-.32.08.23.36.39.55.15.06-.08.11-.17.16-.26.18-.09.24-.32.18-.48.05-.2.1-.4.13-.6.16-.86.25-1.74.33-2.62.11-1.17.17-2.34.23-3.51.15-.01.32-.03.52-.04.36-.03 1.73-.15 2.06-.15.39 0 .7-.02.95-.04 1.76 1.11 3.45 2.35 5.14 3.55 2.83 2.01 5.64 4.04 8.47 6.04 1.42 1 2.85 2 4.29 2.97.1.06.19.07.27.04.08 0 .17-.02.25-.1 1.61-1.56 3.15-3.18 4.6-4.88.75-.88 1.49-1.78 2.15-2.73.01.01.03.02.04.03.34.3.83-.2.49-.49-2.16-1.9-4.34-3.76-6.64-5.48l.03-.01Zm-6.38-3.65a55.72 55.72 0 0 0-4-2.13c.14-.1.26-.19.4-.29 1.2.81 2.4 1.61 3.6 2.42Zm-20.1 11.78c.67-.37 1.23-.91 1.67-1.6-.11.5-.24 1-.38 1.49-.43.04-.86.08-1.29.11Zm2.38-37.24c1.34-.31 2.56-.52 3.71-.69-1.03.19-2.04.41-3.04.65-.14-.07-.34-.02-.45.11-.07.02-.15.04-.22.05v-.13.01Zm.04.84c.07-.02.14-.03.2-.05.34 1.66.41 3.41.5 5.09.17 2.9.24 5.81.28 8.71l.03 3.17c-.17.07-.34.14-.51.2-.06-4.96-.21-10.58-.51-17.12h.01Zm16.04 5.62c-1.16 2.25-3.06 4.1-5.02 5.66-2.8 2.23-5.99 3.97-9.3 5.35-.01-3.56-.09-7.12-.27-10.67-.1-2.04-.16-4.16-.57-6.18 3.3-.78 6.72-1.36 10.1-1.1 1.85.14 4.23.59 5.32 2.29.92 1.43.46 3.24-.26 4.65Zm.85-.18c.6-1.37.9-2.92.28-4.32-.67-1.52-2.2-2.32-3.76-2.74.46.1.89.21 1.29.37 1.74.67 2.69 1.88 2.93 3.21.2 1.13-.05 2.25-.74 3.47V70Zm-27.47-4.14c-.12-.19-.23-.38-.34-.57.74.42.85.36.99.41v.08c-.22.03-.43.06-.65.08Zm11.21 30.46c-.08 1.08-.16 2.17-.33 3.24-.05.35-.11.69-.2 1.03 0 .04-.02.07-.03.11-.15.02-.3.04-.45.05.45-1.64.76-3.36.79-5.07.03-.29.08-.57.1-.89-.03-.31-.03-.47.24-.57-.04.69-.07 1.39-.12 2.08v.02Zm5.6-2.47c.48.11.92.52 2.49 1.72-.46-.32-.92-.65-1.38-.97-.37-.25-.73-.5-1.1-.75h-.01Zm21.23 7.24a70.76 70.76 0 0 1-4.37 4.63c-.14-.09-.27-.19-.4-.28.19-.09.37-.24.55-.47.87-1.14 5.43-5.51 5.49-7.45.31.26.62.53.92.79-.67.97-1.42 1.88-2.19 2.77v.01Z",
@@ -45333,24 +46113,24 @@ var ExcalidrawLogo = ({
45333
46113
  size = "small",
45334
46114
  withText
45335
46115
  }) => {
45336
- return /* @__PURE__ */ jsxs70("div", { className: `ExcalidrawLogo is-${size}`, style, children: [
45337
- /* @__PURE__ */ jsx142(LogoIcon, {}),
45338
- withText && /* @__PURE__ */ jsx142(LogoText, {})
46116
+ return /* @__PURE__ */ jsxs71("div", { className: `ExcalidrawLogo is-${size}`, style, children: [
46117
+ /* @__PURE__ */ jsx143(LogoIcon, {}),
46118
+ withText && /* @__PURE__ */ jsx143(LogoText, {})
45339
46119
  ] });
45340
46120
  };
45341
46121
 
45342
46122
  // components/welcome-screen/WelcomeScreen.Center.tsx
45343
- import { Fragment as Fragment26, jsx as jsx143, jsxs as jsxs71 } from "react/jsx-runtime";
46123
+ import { Fragment as Fragment27, jsx as jsx144, jsxs as jsxs72 } from "react/jsx-runtime";
45344
46124
  var WelcomeScreenMenuItemContent = ({
45345
46125
  icon,
45346
46126
  shortcut,
45347
46127
  children
45348
46128
  }) => {
45349
46129
  const editorInterface = useEditorInterface();
45350
- return /* @__PURE__ */ jsxs71(Fragment26, { children: [
45351
- /* @__PURE__ */ jsx143("div", { className: "welcome-screen-menu-item__icon", children: icon }),
45352
- /* @__PURE__ */ jsx143("div", { className: "welcome-screen-menu-item__text", children }),
45353
- shortcut && editorInterface.formFactor !== "phone" && /* @__PURE__ */ jsx143("div", { className: "welcome-screen-menu-item__shortcut", children: shortcut })
46130
+ return /* @__PURE__ */ jsxs72(Fragment27, { children: [
46131
+ /* @__PURE__ */ jsx144("div", { className: "welcome-screen-menu-item__icon", children: icon }),
46132
+ /* @__PURE__ */ jsx144("div", { className: "welcome-screen-menu-item__text", children }),
46133
+ shortcut && editorInterface.formFactor !== "phone" && /* @__PURE__ */ jsx144("div", { className: "welcome-screen-menu-item__shortcut", children: shortcut })
45354
46134
  ] });
45355
46135
  };
45356
46136
  WelcomeScreenMenuItemContent.displayName = "WelcomeScreenMenuItemContent";
@@ -45362,14 +46142,14 @@ var WelcomeScreenMenuItem = ({
45362
46142
  className = "",
45363
46143
  ...props
45364
46144
  }) => {
45365
- return /* @__PURE__ */ jsx143(
46145
+ return /* @__PURE__ */ jsx144(
45366
46146
  "button",
45367
46147
  {
45368
46148
  ...props,
45369
46149
  type: "button",
45370
46150
  className: `welcome-screen-menu-item ${className}`,
45371
46151
  onClick: onSelect,
45372
- children: /* @__PURE__ */ jsx143(WelcomeScreenMenuItemContent, { icon, shortcut, children })
46152
+ children: /* @__PURE__ */ jsx144(WelcomeScreenMenuItemContent, { icon, shortcut, children })
45373
46153
  }
45374
46154
  );
45375
46155
  };
@@ -45382,7 +46162,7 @@ var WelcomeScreenMenuItemLink = ({
45382
46162
  className = "",
45383
46163
  ...props
45384
46164
  }) => {
45385
- return /* @__PURE__ */ jsx143(
46165
+ return /* @__PURE__ */ jsx144(
45386
46166
  "a",
45387
46167
  {
45388
46168
  ...props,
@@ -45390,38 +46170,38 @@ var WelcomeScreenMenuItemLink = ({
45390
46170
  href,
45391
46171
  target: "_blank",
45392
46172
  rel: "noopener",
45393
- children: /* @__PURE__ */ jsx143(WelcomeScreenMenuItemContent, { icon, shortcut, children })
46173
+ children: /* @__PURE__ */ jsx144(WelcomeScreenMenuItemContent, { icon, shortcut, children })
45394
46174
  }
45395
46175
  );
45396
46176
  };
45397
46177
  WelcomeScreenMenuItemLink.displayName = "WelcomeScreenMenuItemLink";
45398
46178
  var Center = ({ children }) => {
45399
46179
  const { WelcomeScreenCenterTunnel } = useTunnels();
45400
- return /* @__PURE__ */ jsx143(WelcomeScreenCenterTunnel.In, { children: /* @__PURE__ */ jsx143("div", { className: "welcome-screen-center", children: children || /* @__PURE__ */ jsxs71(Fragment26, { children: [
45401
- /* @__PURE__ */ jsx143(Logo, {}),
45402
- /* @__PURE__ */ jsx143(Heading, { children: t("welcomeScreen.defaults.center_heading") }),
45403
- /* @__PURE__ */ jsxs71(Menu, { children: [
45404
- /* @__PURE__ */ jsx143(MenuItemLoadScene, {}),
45405
- /* @__PURE__ */ jsx143(MenuItemHelp, {})
46180
+ return /* @__PURE__ */ jsx144(WelcomeScreenCenterTunnel.In, { children: /* @__PURE__ */ jsx144("div", { className: "welcome-screen-center", children: children || /* @__PURE__ */ jsxs72(Fragment27, { children: [
46181
+ /* @__PURE__ */ jsx144(Logo, {}),
46182
+ /* @__PURE__ */ jsx144(Heading, { children: t("welcomeScreen.defaults.center_heading") }),
46183
+ /* @__PURE__ */ jsxs72(Menu, { children: [
46184
+ /* @__PURE__ */ jsx144(MenuItemLoadScene, {}),
46185
+ /* @__PURE__ */ jsx144(MenuItemHelp, {})
45406
46186
  ] })
45407
46187
  ] }) }) });
45408
46188
  };
45409
46189
  Center.displayName = "Center";
45410
46190
  var Logo = ({ children }) => {
45411
- return /* @__PURE__ */ jsx143("div", { className: "welcome-screen-center__logo excalifont welcome-screen-decor", children: children || /* @__PURE__ */ jsx143(ExcalidrawLogo, { withText: true }) });
46191
+ return /* @__PURE__ */ jsx144("div", { className: "welcome-screen-center__logo excalifont welcome-screen-decor", children: children || /* @__PURE__ */ jsx144(ExcalidrawLogo, { withText: true }) });
45412
46192
  };
45413
46193
  Logo.displayName = "Logo";
45414
46194
  var Heading = ({ children }) => {
45415
- return /* @__PURE__ */ jsx143("div", { className: "welcome-screen-center__heading welcome-screen-decor excalifont", children });
46195
+ return /* @__PURE__ */ jsx144("div", { className: "welcome-screen-center__heading welcome-screen-decor excalifont", children });
45416
46196
  };
45417
46197
  Heading.displayName = "Heading";
45418
46198
  var Menu = ({ children }) => {
45419
- return /* @__PURE__ */ jsx143("div", { className: "welcome-screen-menu", children });
46199
+ return /* @__PURE__ */ jsx144("div", { className: "welcome-screen-menu", children });
45420
46200
  };
45421
46201
  Menu.displayName = "Menu";
45422
46202
  var MenuItemHelp = () => {
45423
46203
  const actionManager = useExcalidrawActionManager();
45424
- return /* @__PURE__ */ jsx143(
46204
+ return /* @__PURE__ */ jsx144(
45425
46205
  WelcomeScreenMenuItem,
45426
46206
  {
45427
46207
  onSelect: () => actionManager.executeAction(actionShortcuts),
@@ -45438,7 +46218,7 @@ var MenuItemLoadScene = () => {
45438
46218
  if (appState.viewModeEnabled) {
45439
46219
  return null;
45440
46220
  }
45441
- return /* @__PURE__ */ jsx143(
46221
+ return /* @__PURE__ */ jsx144(
45442
46222
  WelcomeScreenMenuItem,
45443
46223
  {
45444
46224
  onSelect: () => actionManager.executeAction(actionLoadScene),
@@ -45453,7 +46233,7 @@ var MenuItemLiveCollaborationTrigger = ({
45453
46233
  onSelect
45454
46234
  }) => {
45455
46235
  const { t: t2 } = useI18n();
45456
- return /* @__PURE__ */ jsx143(WelcomeScreenMenuItem, { shortcut: null, onSelect, icon: usersIcon, children: t2("labels.liveCollaboration") });
46236
+ return /* @__PURE__ */ jsx144(WelcomeScreenMenuItem, { shortcut: null, onSelect, icon: usersIcon, children: t2("labels.liveCollaboration") });
45457
46237
  };
45458
46238
  MenuItemLiveCollaborationTrigger.displayName = "MenuItemLiveCollaborationTrigger";
45459
46239
  Center.Logo = Logo;
@@ -45466,40 +46246,40 @@ Center.MenuItemLoadScene = MenuItemLoadScene;
45466
46246
  Center.MenuItemLiveCollaborationTrigger = MenuItemLiveCollaborationTrigger;
45467
46247
 
45468
46248
  // components/welcome-screen/WelcomeScreen.Hints.tsx
45469
- import { jsx as jsx144, jsxs as jsxs72 } from "react/jsx-runtime";
46249
+ import { jsx as jsx145, jsxs as jsxs73 } from "react/jsx-runtime";
45470
46250
  var MenuHint = ({ children }) => {
45471
46251
  const { WelcomeScreenMenuHintTunnel } = useTunnels();
45472
- return /* @__PURE__ */ jsx144(WelcomeScreenMenuHintTunnel.In, { children: /* @__PURE__ */ jsxs72("div", { className: "excalifont welcome-screen-decor welcome-screen-decor-hint welcome-screen-decor-hint--menu", children: [
46252
+ return /* @__PURE__ */ jsx145(WelcomeScreenMenuHintTunnel.In, { children: /* @__PURE__ */ jsxs73("div", { className: "excalifont welcome-screen-decor welcome-screen-decor-hint welcome-screen-decor-hint--menu", children: [
45473
46253
  WelcomeScreenMenuArrow,
45474
- /* @__PURE__ */ jsx144("div", { className: "welcome-screen-decor-hint__label", children: children || t("welcomeScreen.defaults.menuHint") })
46254
+ /* @__PURE__ */ jsx145("div", { className: "welcome-screen-decor-hint__label", children: children || t("welcomeScreen.defaults.menuHint") })
45475
46255
  ] }) });
45476
46256
  };
45477
46257
  MenuHint.displayName = "MenuHint";
45478
46258
  var ToolbarHint = ({ children }) => {
45479
46259
  const { WelcomeScreenToolbarHintTunnel } = useTunnels();
45480
- return /* @__PURE__ */ jsx144(WelcomeScreenToolbarHintTunnel.In, { children: /* @__PURE__ */ jsxs72("div", { className: "excalifont welcome-screen-decor welcome-screen-decor-hint welcome-screen-decor-hint--toolbar", children: [
45481
- /* @__PURE__ */ jsx144("div", { className: "welcome-screen-decor-hint__label", children: children || t("welcomeScreen.defaults.toolbarHint") }),
46260
+ return /* @__PURE__ */ jsx145(WelcomeScreenToolbarHintTunnel.In, { children: /* @__PURE__ */ jsxs73("div", { className: "excalifont welcome-screen-decor welcome-screen-decor-hint welcome-screen-decor-hint--toolbar", children: [
46261
+ /* @__PURE__ */ jsx145("div", { className: "welcome-screen-decor-hint__label", children: children || t("welcomeScreen.defaults.toolbarHint") }),
45482
46262
  WelcomeScreenTopToolbarArrow
45483
46263
  ] }) });
45484
46264
  };
45485
46265
  ToolbarHint.displayName = "ToolbarHint";
45486
46266
  var HelpHint = ({ children }) => {
45487
46267
  const { WelcomeScreenHelpHintTunnel } = useTunnels();
45488
- return /* @__PURE__ */ jsx144(WelcomeScreenHelpHintTunnel.In, { children: /* @__PURE__ */ jsxs72("div", { className: "excalifont welcome-screen-decor welcome-screen-decor-hint welcome-screen-decor-hint--help", children: [
45489
- /* @__PURE__ */ jsx144("div", { children: children || t("welcomeScreen.defaults.helpHint") }),
46268
+ return /* @__PURE__ */ jsx145(WelcomeScreenHelpHintTunnel.In, { children: /* @__PURE__ */ jsxs73("div", { className: "excalifont welcome-screen-decor welcome-screen-decor-hint welcome-screen-decor-hint--help", children: [
46269
+ /* @__PURE__ */ jsx145("div", { children: children || t("welcomeScreen.defaults.helpHint") }),
45490
46270
  WelcomeScreenHelpArrow
45491
46271
  ] }) });
45492
46272
  };
45493
46273
  HelpHint.displayName = "HelpHint";
45494
46274
 
45495
46275
  // components/welcome-screen/WelcomeScreen.tsx
45496
- import { Fragment as Fragment27, jsx as jsx145, jsxs as jsxs73 } from "react/jsx-runtime";
46276
+ import { Fragment as Fragment28, jsx as jsx146, jsxs as jsxs74 } from "react/jsx-runtime";
45497
46277
  var WelcomeScreen = (props) => {
45498
- return /* @__PURE__ */ jsx145(Fragment27, { children: props.children || /* @__PURE__ */ jsxs73(Fragment27, { children: [
45499
- /* @__PURE__ */ jsx145(Center, {}),
45500
- /* @__PURE__ */ jsx145(MenuHint, {}),
45501
- /* @__PURE__ */ jsx145(ToolbarHint, {}),
45502
- /* @__PURE__ */ jsx145(HelpHint, {})
46278
+ return /* @__PURE__ */ jsx146(Fragment28, { children: props.children || /* @__PURE__ */ jsxs74(Fragment28, { children: [
46279
+ /* @__PURE__ */ jsx146(Center, {}),
46280
+ /* @__PURE__ */ jsx146(MenuHint, {}),
46281
+ /* @__PURE__ */ jsx146(ToolbarHint, {}),
46282
+ /* @__PURE__ */ jsx146(HelpHint, {})
45503
46283
  ] }) });
45504
46284
  };
45505
46285
  WelcomeScreen.displayName = "WelcomeScreen";
@@ -45597,6 +46377,7 @@ var polyfill_default = polyfill;
45597
46377
 
45598
46378
  // index.tsx
45599
46379
  import {
46380
+ configureGifWorkerUrl,
45600
46381
  getSceneVersion,
45601
46382
  hashElementsVersion as hashElementsVersion2,
45602
46383
  hashString as hashString2,
@@ -45681,37 +46462,37 @@ import { isLinearElement as isLinearElement12 } from "@excalidraw/element";
45681
46462
  import {
45682
46463
  FONT_FAMILY as FONT_FAMILY8,
45683
46464
  THEME as THEME26,
45684
- MIME_TYPES as MIME_TYPES10,
46465
+ MIME_TYPES as MIME_TYPES12,
45685
46466
  ROUNDNESS as ROUNDNESS9,
45686
46467
  DEFAULT_LASER_COLOR as DEFAULT_LASER_COLOR2,
45687
46468
  UserIdleState as UserIdleState2,
45688
46469
  normalizeLink as normalizeLink5,
45689
- sceneCoordsToViewportCoords as sceneCoordsToViewportCoords7,
46470
+ sceneCoordsToViewportCoords as sceneCoordsToViewportCoords8,
45690
46471
  viewportCoordsToSceneCoords as viewportCoordsToSceneCoords4,
45691
46472
  getFormFactor as getFormFactor2,
45692
46473
  throttleRAF as throttleRAF3
45693
46474
  } from "@excalidraw/common";
45694
46475
  import {
45695
46476
  mutateElement as mutateElement8,
45696
- newElementWith as newElementWith11,
46477
+ newElementWith as newElementWith12,
45697
46478
  bumpVersion as bumpVersion4
45698
46479
  } from "@excalidraw/element";
45699
46480
  import { CaptureUpdateAction as CaptureUpdateAction40 } from "@excalidraw/element";
45700
46481
  import {
45701
- getCommonBounds as getCommonBounds14,
46482
+ getCommonBounds as getCommonBounds15,
45702
46483
  getVisibleSceneBounds as getVisibleSceneBounds2,
45703
46484
  convertToExcalidrawElements as convertToExcalidrawElements2
45704
46485
  } from "@excalidraw/element";
45705
46486
  import { elementsOverlappingBBox as elementsOverlappingBBox3 } from "@excalidraw/element";
45706
46487
  import { isElementLink as isElementLink4 } from "@excalidraw/element";
45707
46488
  import { setCustomTextMetricsProvider } from "@excalidraw/element";
45708
- import { jsx as jsx146 } from "react/jsx-runtime";
46489
+ import { jsx as jsx147 } from "react/jsx-runtime";
45709
46490
  polyfill_default();
45710
46491
  var ExcalidrawAPIProvider = ({
45711
46492
  children
45712
46493
  }) => {
45713
46494
  const [api, setApi] = useState36(null);
45714
- return /* @__PURE__ */ jsx146(ExcalidrawAPIContext.Provider, { value: api, children: /* @__PURE__ */ jsx146(ExcalidrawAPISetContext.Provider, { value: setApi, children }) });
46495
+ return /* @__PURE__ */ jsx147(ExcalidrawAPIContext.Provider, { value: api, children: /* @__PURE__ */ jsx147(ExcalidrawAPISetContext.Provider, { value: setApi, children }) });
45715
46496
  };
45716
46497
  var ExcalidrawBase = (props) => {
45717
46498
  const {
@@ -45793,6 +46574,7 @@ var ExcalidrawBase = (props) => {
45793
46574
  const normalizedImageOptions = {
45794
46575
  maxFileSizeBytes: imageOptions?.maxFileSizeBytes ?? DEFAULT_IMAGE_OPTIONS.maxFileSizeBytes,
45795
46576
  maxWidthOrHeight: imageOptions?.maxWidthOrHeight ?? DEFAULT_IMAGE_OPTIONS.maxWidthOrHeight,
46577
+ gifAutoDecodeMaxFileSizeBytes: imageOptions?.gifAutoDecodeMaxFileSizeBytes ?? DEFAULT_IMAGE_OPTIONS.gifAutoDecodeMaxFileSizeBytes,
45796
46578
  placeholderTransitionDuration: imageOptions?.placeholderTransitionDuration ?? DEFAULT_IMAGE_OPTIONS.placeholderTransitionDuration
45797
46579
  };
45798
46580
  const setExcalidrawAPI = useContext5(ExcalidrawAPISetContext);
@@ -45826,7 +46608,7 @@ var ExcalidrawBase = (props) => {
45826
46608
  document.removeEventListener("touchmove", handleTouchMove);
45827
46609
  };
45828
46610
  }, [browserZoomAllowed]);
45829
- return /* @__PURE__ */ jsx146(EditorJotaiProvider, { store: editorJotaiStore, children: /* @__PURE__ */ jsx146(InitializeApp, { langCode, theme, children: /* @__PURE__ */ jsx146(
46611
+ return /* @__PURE__ */ jsx147(EditorJotaiProvider, { store: editorJotaiStore, children: /* @__PURE__ */ jsx147(InitializeApp, { langCode, theme, children: /* @__PURE__ */ jsx147(
45830
46612
  App_default,
45831
46613
  {
45832
46614
  onExport,
@@ -45946,10 +46728,10 @@ var areEqual5 = (prevProps, nextProps) => {
45946
46728
  }
45947
46729
  return prevUIOptions[key] === nextUIOptions[key];
45948
46730
  });
45949
- const isImageOptionsSame = (prevImageOptions?.maxWidthOrHeight ?? DEFAULT_IMAGE_OPTIONS.maxWidthOrHeight) === (nextImageOptions?.maxWidthOrHeight ?? DEFAULT_IMAGE_OPTIONS.maxWidthOrHeight) && (prevImageOptions?.maxFileSizeBytes ?? DEFAULT_IMAGE_OPTIONS.maxFileSizeBytes) === (nextImageOptions?.maxFileSizeBytes ?? DEFAULT_IMAGE_OPTIONS.maxFileSizeBytes) && (prevImageOptions?.placeholderTransitionDuration ?? DEFAULT_IMAGE_OPTIONS.placeholderTransitionDuration) === (nextImageOptions?.placeholderTransitionDuration ?? DEFAULT_IMAGE_OPTIONS.placeholderTransitionDuration);
46731
+ const isImageOptionsSame = (prevImageOptions?.maxWidthOrHeight ?? DEFAULT_IMAGE_OPTIONS.maxWidthOrHeight) === (nextImageOptions?.maxWidthOrHeight ?? DEFAULT_IMAGE_OPTIONS.maxWidthOrHeight) && (prevImageOptions?.maxFileSizeBytes ?? DEFAULT_IMAGE_OPTIONS.maxFileSizeBytes) === (nextImageOptions?.maxFileSizeBytes ?? DEFAULT_IMAGE_OPTIONS.maxFileSizeBytes) && (prevImageOptions?.gifAutoDecodeMaxFileSizeBytes ?? DEFAULT_IMAGE_OPTIONS.gifAutoDecodeMaxFileSizeBytes) === (nextImageOptions?.gifAutoDecodeMaxFileSizeBytes ?? DEFAULT_IMAGE_OPTIONS.gifAutoDecodeMaxFileSizeBytes) && (prevImageOptions?.placeholderTransitionDuration ?? DEFAULT_IMAGE_OPTIONS.placeholderTransitionDuration) === (nextImageOptions?.placeholderTransitionDuration ?? DEFAULT_IMAGE_OPTIONS.placeholderTransitionDuration);
45950
46732
  return isUIOptionsSame && isImageOptionsSame && isShallowEqual10(prev, next);
45951
46733
  };
45952
- var Excalidraw = React42.memo(ExcalidrawBase, areEqual5);
46734
+ var Excalidraw = React43.memo(ExcalidrawBase, areEqual5);
45953
46735
  Excalidraw.displayName = "Excalidraw";
45954
46736
  function useExcalidrawStateValue(selector) {
45955
46737
  return useAppStateValue(selector, false);
@@ -45968,7 +46750,7 @@ export {
45968
46750
  Fonts,
45969
46751
  FooterCenter_default as Footer,
45970
46752
  LiveCollaborationTrigger_default as LiveCollaborationTrigger,
45971
- MIME_TYPES10 as MIME_TYPES,
46753
+ MIME_TYPES12 as MIME_TYPES,
45972
46754
  MainMenu_default as MainMenu,
45973
46755
  ROUNDNESS9 as ROUNDNESS,
45974
46756
  Sidebar,
@@ -45980,6 +46762,7 @@ export {
45980
46762
  applyDarkModeFilter11 as applyDarkModeFilter,
45981
46763
  bumpVersion4 as bumpVersion,
45982
46764
  captureDragEventData,
46765
+ configureGifWorkerUrl,
45983
46766
  convertToExcalidrawElements2 as convertToExcalidrawElements,
45984
46767
  defaultLang,
45985
46768
  elementsOverlappingBBox3 as elementsOverlappingBBox,
@@ -45987,7 +46770,7 @@ export {
45987
46770
  exportToCanvas2 as exportToCanvas,
45988
46771
  exportToClipboard,
45989
46772
  exportToSvg2 as exportToSvg,
45990
- getCommonBounds14 as getCommonBounds,
46773
+ getCommonBounds15 as getCommonBounds,
45991
46774
  getDataURL,
45992
46775
  getFormFactor2 as getFormFactor,
45993
46776
  getNonDeletedElements19 as getNonDeletedElements,
@@ -46004,7 +46787,7 @@ export {
46004
46787
  languages,
46005
46788
  loadFromBlob,
46006
46789
  mutateElement8 as mutateElement,
46007
- newElementWith11 as newElementWith,
46790
+ newElementWith12 as newElementWith,
46008
46791
  normalizeLink5 as normalizeLink,
46009
46792
  parseDataTransferEvent,
46010
46793
  parseDragImageMetadata,
@@ -46013,7 +46796,7 @@ export {
46013
46796
  restoreAppState,
46014
46797
  restoreElement,
46015
46798
  restoreElements,
46016
- sceneCoordsToViewportCoords7 as sceneCoordsToViewportCoords,
46799
+ sceneCoordsToViewportCoords8 as sceneCoordsToViewportCoords,
46017
46800
  serializeAsJSON,
46018
46801
  setCustomTextMetricsProvider,
46019
46802
  throttleRAF3 as throttleRAF,