@myoc/excalidraw 0.19.518 → 0.19.519

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 (61) hide show
  1. package/CHANGELOG.md +113 -0
  2. package/dist/dev/{chunk-2ZDXTNY7.js → chunk-MCPNWEHU.js} +2 -2
  3. package/dist/dev/{chunk-36IX6I7U.js → chunk-RIK6B6HD.js} +27 -8
  4. package/dist/dev/chunk-RIK6B6HD.js.map +7 -0
  5. package/dist/dev/data/{image-VHQDH63K.js → image-IRC25PM5.js} +3 -3
  6. package/dist/dev/index.css +2 -3
  7. package/dist/dev/index.css.map +2 -2
  8. package/dist/dev/index.js +547 -595
  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-FL5QOM6C.js +4 -0
  13. package/dist/prod/{chunk-VW4XDTQW.js → chunk-QW7MIEK6.js} +1 -1
  14. package/dist/prod/data/image-7LG744DI.js +1 -0
  15. package/dist/prod/index.css +1 -1
  16. package/dist/prod/index.js +17 -17
  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/colors.d.ts +1 -1
  20. package/dist/types/element/src/bounds.d.ts +18 -1
  21. package/dist/types/excalidraw/actions/actionBoundText.d.ts +2 -0
  22. package/dist/types/excalidraw/actions/actionCanvas.d.ts +11 -0
  23. package/dist/types/excalidraw/actions/actionClipboard.d.ts +2 -0
  24. package/dist/types/excalidraw/actions/actionCropEditor.d.ts +1 -0
  25. package/dist/types/excalidraw/actions/actionDeleteSelected.d.ts +3 -0
  26. package/dist/types/excalidraw/actions/actionDeselect.d.ts +1 -0
  27. package/dist/types/excalidraw/actions/actionElementLink.d.ts +1 -0
  28. package/dist/types/excalidraw/actions/actionElementLock.d.ts +2 -0
  29. package/dist/types/excalidraw/actions/actionEmbeddable.d.ts +1 -0
  30. package/dist/types/excalidraw/actions/actionExport.d.ts +2 -0
  31. package/dist/types/excalidraw/actions/actionFrame.d.ts +4 -0
  32. package/dist/types/excalidraw/actions/actionGroup.d.ts +2 -0
  33. package/dist/types/excalidraw/actions/actionLinearEditor.d.ts +1 -0
  34. package/dist/types/excalidraw/actions/actionLink.d.ts +1 -0
  35. package/dist/types/excalidraw/actions/actionMenu.d.ts +1 -0
  36. package/dist/types/excalidraw/actions/actionProperties.d.ts +2 -0
  37. package/dist/types/excalidraw/actions/actionSelectAll.d.ts +1 -0
  38. package/dist/types/excalidraw/actions/actionStyles.d.ts +1 -0
  39. package/dist/types/excalidraw/actions/actionToggleArrowBinding.d.ts +1 -0
  40. package/dist/types/excalidraw/actions/actionToggleGridMode.d.ts +1 -0
  41. package/dist/types/excalidraw/actions/actionToggleMidpointSnapping.d.ts +1 -0
  42. package/dist/types/excalidraw/actions/actionToggleObjectsSnapMode.d.ts +1 -0
  43. package/dist/types/excalidraw/actions/actionToggleSearchMenu.d.ts +1 -0
  44. package/dist/types/excalidraw/actions/actionToggleStats.d.ts +1 -0
  45. package/dist/types/excalidraw/actions/actionToggleViewMode.d.ts +3 -2
  46. package/dist/types/excalidraw/actions/actionToggleZenMode.d.ts +1 -0
  47. package/dist/types/excalidraw/components/App.d.ts +1 -0
  48. package/dist/types/excalidraw/components/main-menu/DefaultItems.d.ts +7 -4
  49. package/dist/types/excalidraw/data/blob.d.ts +1 -0
  50. package/dist/types/excalidraw/data/json.d.ts +1 -0
  51. package/dist/types/excalidraw/index.d.ts +3 -1
  52. package/dist/types/excalidraw/types.d.ts +8 -0
  53. package/dist/types/utils/src/index.d.ts +1 -2
  54. package/package.json +4 -4
  55. package/dist/dev/chunk-36IX6I7U.js.map +0 -7
  56. package/dist/prod/chunk-B67RJXF2.js +0 -4
  57. package/dist/prod/data/image-YRR6RGIN.js +0 -1
  58. package/dist/types/utils/src/bbox.d.ts +0 -9
  59. package/dist/types/utils/src/withinBounds.d.ts +0 -19
  60. /package/dist/dev/{chunk-2ZDXTNY7.js.map → chunk-MCPNWEHU.js.map} +0 -0
  61. /package/dist/dev/data/{image-VHQDH63K.js.map → image-IRC25PM5.js.map} +0 -0
package/dist/dev/index.js CHANGED
@@ -57,10 +57,10 @@ import {
57
57
  saveAsJSON,
58
58
  serializeAsJSON,
59
59
  strokeRectWithRotation_simple
60
- } from "./chunk-36IX6I7U.js";
60
+ } from "./chunk-RIK6B6HD.js";
61
61
  import {
62
62
  define_import_meta_env_default
63
- } from "./chunk-2ZDXTNY7.js";
63
+ } from "./chunk-MCPNWEHU.js";
64
64
  import {
65
65
  en_default
66
66
  } from "./chunk-ZGRXNVW4.js";
@@ -82,6 +82,7 @@ import React42, {
82
82
  useState as useState33
83
83
  } from "react";
84
84
  import {
85
+ applyDarkModeFilter as applyDarkModeFilter5,
85
86
  DEFAULT_IMAGE_OPTIONS,
86
87
  DEFAULT_UI_OPTIONS,
87
88
  isShallowEqual as isShallowEqual9
@@ -96,11 +97,11 @@ import rough3 from "roughjs/bin/rough";
96
97
  import { nanoid } from "nanoid";
97
98
  import {
98
99
  clamp as clamp8,
99
- pointFrom as pointFrom34,
100
+ pointFrom as pointFrom32,
100
101
  pointDistance as pointDistance9,
101
102
  vector as vector3,
102
- pointRotateRads as pointRotateRads23,
103
- vectorFromPoint as vectorFromPoint10,
103
+ pointRotateRads as pointRotateRads21,
104
+ vectorFromPoint as vectorFromPoint9,
104
105
  vectorSubtract as vectorSubtract2,
105
106
  vectorDot,
106
107
  vectorNormalize as vectorNormalize5
@@ -173,7 +174,7 @@ import {
173
174
  normalizeEOL as normalizeEOL2,
174
175
  getDateTime,
175
176
  isShallowEqual as isShallowEqual8,
176
- arrayToMap as arrayToMap30,
177
+ arrayToMap as arrayToMap29,
177
178
  applyDarkModeFilter as applyDarkModeFilter4,
178
179
  AppEventBus,
179
180
  randomInteger as randomInteger4,
@@ -220,7 +221,7 @@ import {
220
221
  deepCopyElement as deepCopyElement4,
221
222
  duplicateElements as duplicateElements2,
222
223
  hasBoundTextElement as hasBoundTextElement9,
223
- isArrowElement as isArrowElement14,
224
+ isArrowElement as isArrowElement13,
224
225
  isBindingElement as isBindingElement4,
225
226
  isBindingElementType,
226
227
  isBoundToContainer as isBoundToContainer9,
@@ -228,7 +229,7 @@ import {
228
229
  isImageElement as isImageElement9,
229
230
  isEmbeddableElement as isEmbeddableElement4,
230
231
  isInitializedImageElement as isInitializedImageElement3,
231
- isLinearElement as isLinearElement12,
232
+ isLinearElement as isLinearElement11,
232
233
  isLinearElementType as isLinearElementType2,
233
234
  isUsingAdaptiveRadius as isUsingAdaptiveRadius4,
234
235
  isIframeElement as isIframeElement2,
@@ -238,7 +239,7 @@ import {
238
239
  isElbowArrow as isElbowArrow10,
239
240
  isFlowchartNodeElement as isFlowchartNodeElement2,
240
241
  isBindableElement as isBindableElement3,
241
- isTextElement as isTextElement19,
242
+ isTextElement as isTextElement18,
242
243
  getNormalizedDimensions,
243
244
  isElementCompletelyInViewport as isElementCompletelyInViewport2,
244
245
  isElementInViewport as isElementInViewport3,
@@ -327,7 +328,7 @@ import {
327
328
  calculateFixedPointForNonElbowArrowBinding as calculateFixedPointForNonElbowArrowBinding2,
328
329
  bindOrUnbindBindingElement as bindOrUnbindBindingElement2,
329
330
  mutateElement as mutateElement6,
330
- getElementBounds as getElementBounds5,
331
+ getElementBounds as getElementBounds4,
331
332
  doBoundsIntersect as doBoundsIntersect4,
332
333
  isPointInElement as isPointInElement3,
333
334
  maxBindingDistance_simple as maxBindingDistance_simple3,
@@ -8390,16 +8391,21 @@ var actionToggleTheme = register({
8390
8391
  icon: (appState, elements) => appState.theme === THEME5.LIGHT ? MoonIcon : SunIcon,
8391
8392
  viewMode: true,
8392
8393
  trackEvent: { category: "canvas" },
8393
- perform: (_, appState, value) => {
8394
+ perform: (_, appState, value, app) => {
8395
+ const nextTheme = value || (appState.theme === THEME5.LIGHT ? THEME5.DARK : THEME5.LIGHT);
8396
+ if (app.props.onThemeChange) {
8397
+ app.props.onThemeChange(nextTheme);
8398
+ return false;
8399
+ }
8394
8400
  return {
8395
8401
  appState: {
8396
8402
  ...appState,
8397
- theme: value || (appState.theme === THEME5.LIGHT ? THEME5.DARK : THEME5.LIGHT)
8403
+ theme: nextTheme
8398
8404
  },
8399
8405
  captureUpdate: CaptureUpdateAction6.EVENTUALLY
8400
8406
  };
8401
8407
  },
8402
- keyTest: (event) => event.altKey && event.shiftKey && event.code === CODES2.D,
8408
+ keyTest: (event) => !event[KEYS12.CTRL_OR_CMD] && event.altKey && event.shiftKey && event.code === CODES2.D,
8403
8409
  predicate: (elements, appState, props, app) => {
8404
8410
  return !!app.props.UIOptions.canvasActions.toggleTheme;
8405
8411
  }
@@ -9611,7 +9617,7 @@ var exportCanvas = async (type, elements, appState, files, {
9611
9617
  let blob = canvasToBlob(tempCanvas);
9612
9618
  if (appState.exportEmbedScene) {
9613
9619
  blob = blob.then(
9614
- (blob2) => import("./data/image-VHQDH63K.js").then(
9620
+ (blob2) => import("./data/image-IRC25PM5.js").then(
9615
9621
  ({ encodePngMetadata: encodePngMetadata2 }) => encodePngMetadata2({
9616
9622
  blob: blob2,
9617
9623
  metadata: serializeAsJSON(elements, appState, files, "local")
@@ -12676,9 +12682,9 @@ var getCurvePathOps = (shape) => {
12676
12682
 
12677
12683
  // ../element/src/shape.ts
12678
12684
  import {
12679
- pointFrom as pointFrom17,
12685
+ pointFrom as pointFrom16,
12680
12686
  pointDistance as pointDistance7,
12681
- pointRotateRads as pointRotateRads13
12687
+ pointRotateRads as pointRotateRads12
12682
12688
  } from "@excalidraw/math";
12683
12689
  import {
12684
12690
  ROUGHNESS,
@@ -12695,9 +12701,9 @@ import { RoughGenerator } from "roughjs/bin/generator";
12695
12701
  import rough2 from "roughjs/bin/rough";
12696
12702
  import {
12697
12703
  isRightAngleRads,
12698
- lineSegment as lineSegment7,
12699
- pointFrom as pointFrom16,
12700
- pointRotateRads as pointRotateRads12
12704
+ lineSegment as lineSegment6,
12705
+ pointFrom as pointFrom15,
12706
+ pointRotateRads as pointRotateRads11
12701
12707
  } from "@excalidraw/math";
12702
12708
  import {
12703
12709
  BOUND_TEXT_PADDING as BOUND_TEXT_PADDING4,
@@ -12726,22 +12732,22 @@ import {
12726
12732
  } from "@excalidraw/common";
12727
12733
  import {
12728
12734
  degreesToRadians,
12729
- lineSegment as lineSegment6,
12735
+ lineSegment as lineSegment5,
12730
12736
  pointDistance as pointDistance6,
12731
- pointFrom as pointFrom14,
12737
+ pointFrom as pointFrom13,
12732
12738
  pointFromArray as pointFromArray3,
12733
- pointRotateRads as pointRotateRads10
12739
+ pointRotateRads as pointRotateRads9
12734
12740
  } from "@excalidraw/math";
12735
12741
  import { pointsOnBezierCurves as pointsOnBezierCurves2 } from "points-on-curve";
12736
12742
 
12737
12743
  // ../element/src/linearElementEditor.ts
12738
12744
  import {
12739
12745
  pointCenter,
12740
- pointFrom as pointFrom13,
12741
- pointRotateRads as pointRotateRads9,
12746
+ pointFrom as pointFrom12,
12747
+ pointRotateRads as pointRotateRads8,
12742
12748
  pointsEqual as pointsEqual7,
12743
12749
  pointDistance as pointDistance5,
12744
- vectorFromPoint as vectorFromPoint8,
12750
+ vectorFromPoint as vectorFromPoint7,
12745
12751
  curveLength,
12746
12752
  curvePointAtLength
12747
12753
  } from "@excalidraw/math";
@@ -13002,20 +13008,13 @@ import { arrayToMap as arrayToMap20, findIndex, findLastIndex } from "@excalidra
13002
13008
 
13003
13009
  // ../element/src/selection.ts
13004
13010
  import { arrayToMap as arrayToMap19, isShallowEqual } from "@excalidraw/common";
13005
- import {
13006
- lineSegment as lineSegment5,
13007
- pointFrom as pointFrom12,
13008
- pointRotateRads as pointRotateRads8
13009
- } from "@excalidraw/math";
13010
13011
 
13011
13012
  // ../element/src/frame.ts
13012
13013
  import { arrayToMap as arrayToMap18 } from "@excalidraw/common";
13013
- import { isPointWithinBounds as isPointWithinBounds2, pointFrom as pointFrom11 } from "@excalidraw/math";
13014
-
13015
- // ../utils/src/bbox.ts
13016
13014
  import {
13017
- vectorCross as vectorCross3,
13018
- vectorFromPoint as vectorFromPoint7
13015
+ isPointWithinBounds as isPointWithinBounds2,
13016
+ pointFrom as pointFrom11,
13017
+ segmentsIntersectAt as segmentsIntersectAt2
13019
13018
  } from "@excalidraw/math";
13020
13019
 
13021
13020
  // ../element/src/fractionalIndex.ts
@@ -13242,17 +13241,17 @@ var getArrowheadPoints = (element, shape, position, arrowhead, offsetMultiplier
13242
13241
  const index = position === "start" ? 1 : ops.length - 1;
13243
13242
  const data = ops[index].data;
13244
13243
  invariant12(data.length === 6, "Op data length is not 6");
13245
- const p3 = pointFrom14(data[4], data[5]);
13246
- const p2 = pointFrom14(data[2], data[3]);
13247
- const p1 = pointFrom14(data[0], data[1]);
13244
+ const p3 = pointFrom13(data[4], data[5]);
13245
+ const p2 = pointFrom13(data[2], data[3]);
13246
+ const p1 = pointFrom13(data[0], data[1]);
13248
13247
  const prevOp = ops[index - 1];
13249
- let p0 = pointFrom14(0, 0);
13248
+ let p0 = pointFrom13(0, 0);
13250
13249
  if (prevOp.op === "move") {
13251
13250
  const p = pointFromArray3(prevOp.data);
13252
13251
  invariant12(p != null, "Op data is not a point");
13253
13252
  p0 = p;
13254
13253
  } else if (prevOp.op === "bcurveTo") {
13255
- p0 = pointFrom14(prevOp.data[4], prevOp.data[5]);
13254
+ p0 = pointFrom13(prevOp.data[4], prevOp.data[5]);
13256
13255
  }
13257
13256
  const equation = (t2, idx) => Math.pow(1 - t2, 3) * p3[idx] + 3 * t2 * Math.pow(1 - t2, 2) * p2[idx] + 3 * Math.pow(t2, 2) * (1 - t2) * p1[idx] + p0[idx] * Math.pow(t2, 3);
13258
13257
  const [x2, y2] = position === "start" ? p0 : p3;
@@ -13279,26 +13278,26 @@ var getArrowheadPoints = (element, shape, position, arrowhead, offsetMultiplier
13279
13278
  }
13280
13279
  const angle = getArrowheadAngle(arrowhead);
13281
13280
  if (arrowhead === "cardinality_many" || arrowhead === "cardinality_one_or_many") {
13282
- const [x32, y32] = pointRotateRads10(
13283
- pointFrom14(tx, ty),
13284
- pointFrom14(xs, ys),
13281
+ const [x32, y32] = pointRotateRads9(
13282
+ pointFrom13(tx, ty),
13283
+ pointFrom13(xs, ys),
13285
13284
  degreesToRadians(-angle)
13286
13285
  );
13287
- const [x42, y42] = pointRotateRads10(
13288
- pointFrom14(tx, ty),
13289
- pointFrom14(xs, ys),
13286
+ const [x42, y42] = pointRotateRads9(
13287
+ pointFrom13(tx, ty),
13288
+ pointFrom13(xs, ys),
13290
13289
  degreesToRadians(angle)
13291
13290
  );
13292
13291
  return [xs, ys, x32, y32, x42, y42];
13293
13292
  }
13294
- const [x3, y3] = pointRotateRads10(
13295
- pointFrom14(xs, ys),
13296
- pointFrom14(tx, ty),
13293
+ const [x3, y3] = pointRotateRads9(
13294
+ pointFrom13(xs, ys),
13295
+ pointFrom13(tx, ty),
13297
13296
  -angle * Math.PI / 180
13298
13297
  );
13299
- const [x4, y4] = pointRotateRads10(
13300
- pointFrom14(xs, ys),
13301
- pointFrom14(tx, ty),
13298
+ const [x4, y4] = pointRotateRads9(
13299
+ pointFrom13(xs, ys),
13300
+ pointFrom13(tx, ty),
13302
13301
  degreesToRadians(angle)
13303
13302
  );
13304
13303
  if (arrowhead === "diamond" || arrowhead === "diamond_outline") {
@@ -13306,16 +13305,16 @@ var getArrowheadPoints = (element, shape, position, arrowhead, offsetMultiplier
13306
13305
  let oy;
13307
13306
  if (position === "start") {
13308
13307
  const [px, py] = element.points.length > 1 ? element.points[1] : [0, 0];
13309
- [ox, oy] = pointRotateRads10(
13310
- pointFrom14(tx + minSize * 2, ty),
13311
- pointFrom14(tx, ty),
13308
+ [ox, oy] = pointRotateRads9(
13309
+ pointFrom13(tx + minSize * 2, ty),
13310
+ pointFrom13(tx, ty),
13312
13311
  Math.atan2(py - ty, px - tx)
13313
13312
  );
13314
13313
  } else {
13315
13314
  const [px, py] = element.points.length > 1 ? element.points[element.points.length - 2] : [0, 0];
13316
- [ox, oy] = pointRotateRads10(
13317
- pointFrom14(tx - minSize * 2, ty),
13318
- pointFrom14(tx, ty),
13315
+ [ox, oy] = pointRotateRads9(
13316
+ pointFrom13(tx - minSize * 2, ty),
13317
+ pointFrom13(tx, ty),
13319
13318
  Math.atan2(ty - py, tx - px)
13320
13319
  );
13321
13320
  }
@@ -13326,10 +13325,10 @@ var getArrowheadPoints = (element, shape, position, arrowhead, offsetMultiplier
13326
13325
 
13327
13326
  // ../element/src/cropElement.ts
13328
13327
  import {
13329
- pointFrom as pointFrom15,
13328
+ pointFrom as pointFrom14,
13330
13329
  pointCenter as pointCenter2,
13331
- pointRotateRads as pointRotateRads11,
13332
- vectorFromPoint as vectorFromPoint9,
13330
+ pointRotateRads as pointRotateRads10,
13331
+ vectorFromPoint as vectorFromPoint8,
13333
13332
  vectorNormalize as vectorNormalize4,
13334
13333
  vectorSubtract,
13335
13334
  vectorAdd as vectorAdd2,
@@ -13434,7 +13433,7 @@ var generateRoughOptions = (element, continuousPath = false, isDarkMode = false)
13434
13433
  fillWeight: element.strokeWidth / 2,
13435
13434
  hachureGap: element.strokeWidth * 4,
13436
13435
  roughness: adjustRoughness(element),
13437
- stroke: isDarkMode ? applyDarkModeFilter2(element.strokeColor) : element.strokeColor,
13436
+ stroke: applyDarkModeFilter2(element.strokeColor, isDarkMode),
13438
13437
  preserveVertices: continuousPath || element.roughness < ROUGHNESS.cartoonist
13439
13438
  };
13440
13439
  switch (element.type) {
@@ -13444,7 +13443,7 @@ var generateRoughOptions = (element, continuousPath = false, isDarkMode = false)
13444
13443
  case "diamond":
13445
13444
  case "ellipse": {
13446
13445
  options.fillStyle = element.fillStyle;
13447
- options.fill = isTransparent4(element.backgroundColor) ? void 0 : isDarkMode ? applyDarkModeFilter2(element.backgroundColor) : element.backgroundColor;
13446
+ options.fill = isTransparent4(element.backgroundColor) ? void 0 : applyDarkModeFilter2(element.backgroundColor, isDarkMode);
13448
13447
  if (element.type === "ellipse") {
13449
13448
  options.curveFitting = 1;
13450
13449
  }
@@ -13454,7 +13453,7 @@ var generateRoughOptions = (element, continuousPath = false, isDarkMode = false)
13454
13453
  case "freedraw": {
13455
13454
  if (isPathALoop2(element.points)) {
13456
13455
  options.fillStyle = element.fillStyle;
13457
- options.fill = element.backgroundColor === "transparent" ? void 0 : isDarkMode ? applyDarkModeFilter2(element.backgroundColor) : element.backgroundColor;
13456
+ options.fill = element.backgroundColor === "transparent" ? void 0 : applyDarkModeFilter2(element.backgroundColor, isDarkMode);
13458
13457
  }
13459
13458
  return options;
13460
13459
  }
@@ -13529,8 +13528,11 @@ var getArrowheadShapes = (element, shape, position, arrowhead, generator, option
13529
13528
  if (arrowhead === null) {
13530
13529
  return [];
13531
13530
  }
13532
- const strokeColor = isDarkMode ? applyDarkModeFilter2(element.strokeColor) : element.strokeColor;
13533
- const backgroundFillColor = isDarkMode ? applyDarkModeFilter2(canvasBackgroundColor) : canvasBackgroundColor;
13531
+ const strokeColor = applyDarkModeFilter2(element.strokeColor, isDarkMode);
13532
+ const backgroundFillColor = applyDarkModeFilter2(
13533
+ canvasBackgroundColor,
13534
+ isDarkMode
13535
+ );
13534
13536
  const cardinalityOneOrManyOffset = -0.25;
13535
13537
  const cardinalityZeroCircleScale = 0.8;
13536
13538
  switch (arrowhead) {
@@ -13796,7 +13798,7 @@ var _generateElementShape = (element, generator, {
13796
13798
  case "arrow": {
13797
13799
  let shape;
13798
13800
  const options = generateRoughOptions(element, false, isDarkMode);
13799
- const points = element.points.length ? element.points : [pointFrom17(0, 0)];
13801
+ const points = element.points.length ? element.points : [pointFrom16(0, 0)];
13800
13802
  if (isElbowArrow4(element)) {
13801
13803
  if (!points.every(
13802
13804
  (point) => Math.abs(point[0]) <= 1e6 && Math.abs(point[1]) <= 1e6
@@ -14805,7 +14807,7 @@ var createRedoAction = (history) => ({
14805
14807
 
14806
14808
  // actions/actionTextAutoResize.ts
14807
14809
  import { getFontString as getFontString5 } from "@excalidraw/common";
14808
- import { isExcalidrawElement as isExcalidrawElement2, newElementWith as newElementWith9 } from "@excalidraw/element";
14810
+ import { isExcalidrawElement as isExcalidrawElement3, newElementWith as newElementWith9 } from "@excalidraw/element";
14809
14811
  import { measureText as measureText3 } from "@excalidraw/element";
14810
14812
  import { isTextElement as isTextElement7 } from "@excalidraw/element";
14811
14813
  import { CaptureUpdateAction as CaptureUpdateAction37 } from "@excalidraw/element";
@@ -14820,7 +14822,7 @@ var actionTextAutoResize = register({
14820
14822
  },
14821
14823
  perform: (elements, appState, targetElement) => {
14822
14824
  const selectedElements = getSelectedElements(elements, appState);
14823
- const targetTextElement = isExcalidrawElement2(targetElement) && isTextElement7(targetElement) ? targetElement : selectedElements[0];
14825
+ const targetTextElement = isExcalidrawElement3(targetElement) && isTextElement7(targetElement) ? targetElement : selectedElements[0];
14824
14826
  return {
14825
14827
  appState,
14826
14828
  elements: elements.map((element) => {
@@ -14859,6 +14861,9 @@ var actionToggleViewMode = register({
14859
14861
  predicate: (appState) => !appState.viewModeEnabled
14860
14862
  },
14861
14863
  perform(elements, appState) {
14864
+ if (appState.viewModeOnly) {
14865
+ return false;
14866
+ }
14862
14867
  return {
14863
14868
  appState: {
14864
14869
  ...appState,
@@ -14869,23 +14874,28 @@ var actionToggleViewMode = register({
14869
14874
  },
14870
14875
  checked: (appState) => appState.viewModeEnabled,
14871
14876
  predicate: (elements, appState, appProps) => {
14872
- return typeof appProps.viewModeEnabled === "undefined";
14877
+ return !appState.viewModeOnly && !appProps.viewModeOnly && typeof appProps.viewModeEnabled === "undefined";
14873
14878
  },
14874
14879
  keyTest: (event) => !event[KEYS33.CTRL_OR_CMD] && event.altKey && event.code === CODES9.R,
14875
- PanelComponent: ({ data, updateData, appState }) => /* @__PURE__ */ jsx55(
14876
- ToolButton,
14877
- {
14878
- type: "button",
14879
- icon: eyeIcon,
14880
- "aria-label": t("labels.viewMode"),
14881
- onClick: () => updateData(null),
14882
- size: data?.size || "medium",
14883
- "data-testid": "button-view-mode",
14884
- className: clsx21({
14885
- enabled: appState.viewModeEnabled
14886
- })
14880
+ PanelComponent: ({ data, updateData, appState, appProps }) => {
14881
+ if (appState.viewModeOnly || appProps.viewModeOnly) {
14882
+ return null;
14887
14883
  }
14888
- )
14884
+ return /* @__PURE__ */ jsx55(
14885
+ ToolButton,
14886
+ {
14887
+ type: "button",
14888
+ icon: eyeIcon,
14889
+ "aria-label": t("labels.viewMode"),
14890
+ onClick: () => updateData(null),
14891
+ size: data?.size || "medium",
14892
+ "data-testid": "button-view-mode",
14893
+ className: clsx21({
14894
+ enabled: appState.viewModeEnabled
14895
+ })
14896
+ }
14897
+ );
14898
+ }
14889
14899
  });
14890
14900
 
14891
14901
  // actions/manager.tsx
@@ -15027,8 +15037,8 @@ var sum = (array, mapper) => array.reduce((acc, item) => acc + mapper(item), 0);
15027
15037
 
15028
15038
  // snapping.ts
15029
15039
  import {
15030
- pointFrom as pointFrom18,
15031
- pointRotateRads as pointRotateRads14,
15040
+ pointFrom as pointFrom17,
15041
+ pointRotateRads as pointRotateRads13,
15032
15042
  rangeInclusive,
15033
15043
  rangeIntersection,
15034
15044
  rangesOverlap
@@ -15115,50 +15125,50 @@ var getElementsCorners = (elements, elementsMap, {
15115
15125
  const halfWidth = (x2 - x1) / 2;
15116
15126
  const halfHeight = (y2 - y1) / 2;
15117
15127
  if ((element.type === "diamond" || element.type === "ellipse") && !boundingBoxCorners) {
15118
- const leftMid = pointRotateRads14(
15119
- pointFrom18(x1, y1 + halfHeight),
15120
- pointFrom18(cx, cy),
15128
+ const leftMid = pointRotateRads13(
15129
+ pointFrom17(x1, y1 + halfHeight),
15130
+ pointFrom17(cx, cy),
15121
15131
  element.angle
15122
15132
  );
15123
- const topMid = pointRotateRads14(
15124
- pointFrom18(x1 + halfWidth, y1),
15125
- pointFrom18(cx, cy),
15133
+ const topMid = pointRotateRads13(
15134
+ pointFrom17(x1 + halfWidth, y1),
15135
+ pointFrom17(cx, cy),
15126
15136
  element.angle
15127
15137
  );
15128
- const rightMid = pointRotateRads14(
15129
- pointFrom18(x2, y1 + halfHeight),
15130
- pointFrom18(cx, cy),
15138
+ const rightMid = pointRotateRads13(
15139
+ pointFrom17(x2, y1 + halfHeight),
15140
+ pointFrom17(cx, cy),
15131
15141
  element.angle
15132
15142
  );
15133
- const bottomMid = pointRotateRads14(
15134
- pointFrom18(x1 + halfWidth, y2),
15135
- pointFrom18(cx, cy),
15143
+ const bottomMid = pointRotateRads13(
15144
+ pointFrom17(x1 + halfWidth, y2),
15145
+ pointFrom17(cx, cy),
15136
15146
  element.angle
15137
15147
  );
15138
- const center = pointFrom18(cx, cy);
15148
+ const center = pointFrom17(cx, cy);
15139
15149
  result = omitCenter ? [leftMid, topMid, rightMid, bottomMid] : [leftMid, topMid, rightMid, bottomMid, center];
15140
15150
  } else {
15141
- const topLeft = pointRotateRads14(
15142
- pointFrom18(x1, y1),
15143
- pointFrom18(cx, cy),
15151
+ const topLeft = pointRotateRads13(
15152
+ pointFrom17(x1, y1),
15153
+ pointFrom17(cx, cy),
15144
15154
  element.angle
15145
15155
  );
15146
- const topRight = pointRotateRads14(
15147
- pointFrom18(x2, y1),
15148
- pointFrom18(cx, cy),
15156
+ const topRight = pointRotateRads13(
15157
+ pointFrom17(x2, y1),
15158
+ pointFrom17(cx, cy),
15149
15159
  element.angle
15150
15160
  );
15151
- const bottomLeft = pointRotateRads14(
15152
- pointFrom18(x1, y2),
15153
- pointFrom18(cx, cy),
15161
+ const bottomLeft = pointRotateRads13(
15162
+ pointFrom17(x1, y2),
15163
+ pointFrom17(cx, cy),
15154
15164
  element.angle
15155
15165
  );
15156
- const bottomRight = pointRotateRads14(
15157
- pointFrom18(x2, y2),
15158
- pointFrom18(cx, cy),
15166
+ const bottomRight = pointRotateRads13(
15167
+ pointFrom17(x2, y2),
15168
+ pointFrom17(cx, cy),
15159
15169
  element.angle
15160
15170
  );
15161
- const center = pointFrom18(cx, cy);
15171
+ const center = pointFrom17(cx, cy);
15162
15172
  result = omitCenter ? [topLeft, topRight, bottomLeft, bottomRight] : [topLeft, topRight, bottomLeft, bottomRight, center];
15163
15173
  }
15164
15174
  } else if (elements.length > 1) {
@@ -15168,14 +15178,14 @@ var getElementsCorners = (elements, elementsMap, {
15168
15178
  );
15169
15179
  const width = maxX - minX;
15170
15180
  const height = maxY - minY;
15171
- const topLeft = pointFrom18(minX, minY);
15172
- const topRight = pointFrom18(maxX, minY);
15173
- const bottomLeft = pointFrom18(minX, maxY);
15174
- const bottomRight = pointFrom18(maxX, maxY);
15175
- const center = pointFrom18(minX + width / 2, minY + height / 2);
15181
+ const topLeft = pointFrom17(minX, minY);
15182
+ const topRight = pointFrom17(maxX, minY);
15183
+ const bottomLeft = pointFrom17(minX, maxY);
15184
+ const bottomRight = pointFrom17(maxX, maxY);
15185
+ const center = pointFrom17(minX + width / 2, minY + height / 2);
15176
15186
  result = omitCenter ? [topLeft, topRight, bottomLeft, bottomRight] : [topLeft, topRight, bottomLeft, bottomRight, center];
15177
15187
  }
15178
- return result.map((p) => pointFrom18(round(p[0]), round(p[1])));
15188
+ return result.map((p) => pointFrom17(round(p[0]), round(p[1])));
15179
15189
  };
15180
15190
  var getReferenceElements = (elements, selectedElements, appState, elementsMap) => getVisibleAndNonSelectedElements(
15181
15191
  elements,
@@ -15218,10 +15228,10 @@ var getVisibleGaps = (elements, selectedElements, appState, elementsMap) => {
15218
15228
  startBounds,
15219
15229
  endBounds,
15220
15230
  startSide: [
15221
- pointFrom18(startMaxX, startMinY),
15222
- pointFrom18(startMaxX, startMaxY)
15231
+ pointFrom17(startMaxX, startMinY),
15232
+ pointFrom17(startMaxX, startMaxY)
15223
15233
  ],
15224
- endSide: [pointFrom18(endMinX, endMinY), pointFrom18(endMinX, endMaxY)],
15234
+ endSide: [pointFrom17(endMinX, endMinY), pointFrom17(endMinX, endMaxY)],
15225
15235
  length: endMinX - startMaxX,
15226
15236
  overlap: rangeIntersection(
15227
15237
  rangeInclusive(startMinY, startMaxY),
@@ -15252,10 +15262,10 @@ var getVisibleGaps = (elements, selectedElements, appState, elementsMap) => {
15252
15262
  startBounds,
15253
15263
  endBounds,
15254
15264
  startSide: [
15255
- pointFrom18(startMinX, startMaxY),
15256
- pointFrom18(startMaxX, startMaxY)
15265
+ pointFrom17(startMinX, startMaxY),
15266
+ pointFrom17(startMaxX, startMaxY)
15257
15267
  ],
15258
- endSide: [pointFrom18(endMinX, endMinY), pointFrom18(endMaxX, endMinY)],
15268
+ endSide: [pointFrom17(endMinX, endMinY), pointFrom17(endMaxX, endMinY)],
15259
15269
  length: endMinY - startMaxY,
15260
15270
  overlap: rangeIntersection(
15261
15271
  rangeInclusive(startMinX, startMaxX),
@@ -15560,7 +15570,7 @@ var createPointSnapLines = (nearestSnapsX, nearestSnapsY) => {
15560
15570
  }
15561
15571
  snapsX[key].push(
15562
15572
  ...snap.points.map(
15563
- (p) => pointFrom18(round(p[0]), round(p[1]))
15573
+ (p) => pointFrom17(round(p[0]), round(p[1]))
15564
15574
  )
15565
15575
  );
15566
15576
  }
@@ -15575,7 +15585,7 @@ var createPointSnapLines = (nearestSnapsX, nearestSnapsY) => {
15575
15585
  }
15576
15586
  snapsY[key].push(
15577
15587
  ...snap.points.map(
15578
- (p) => pointFrom18(round(p[0]), round(p[1]))
15588
+ (p) => pointFrom17(round(p[0]), round(p[1]))
15579
15589
  )
15580
15590
  );
15581
15591
  }
@@ -15586,7 +15596,7 @@ var createPointSnapLines = (nearestSnapsX, nearestSnapsY) => {
15586
15596
  type: "points",
15587
15597
  points: dedupePoints(
15588
15598
  points.map((p) => {
15589
- return pointFrom18(Number(key), p[1]);
15599
+ return pointFrom17(Number(key), p[1]);
15590
15600
  }).sort((a, b) => a[1] - b[1])
15591
15601
  )
15592
15602
  };
@@ -15596,7 +15606,7 @@ var createPointSnapLines = (nearestSnapsX, nearestSnapsY) => {
15596
15606
  type: "points",
15597
15607
  points: dedupePoints(
15598
15608
  points.map((p) => {
15599
- return pointFrom18(p[0], Number(key));
15609
+ return pointFrom17(p[0], Number(key));
15600
15610
  }).sort((a, b) => a[0] - b[0])
15601
15611
  )
15602
15612
  };
@@ -15639,16 +15649,16 @@ var createGapSnapLines = (selectedElements, dragOffset, gapSnaps) => {
15639
15649
  type: "gap",
15640
15650
  direction: "horizontal",
15641
15651
  points: [
15642
- pointFrom18(gapSnap.gap.startSide[0][0], gapLineY),
15643
- pointFrom18(minX, gapLineY)
15652
+ pointFrom17(gapSnap.gap.startSide[0][0], gapLineY),
15653
+ pointFrom17(minX, gapLineY)
15644
15654
  ]
15645
15655
  },
15646
15656
  {
15647
15657
  type: "gap",
15648
15658
  direction: "horizontal",
15649
15659
  points: [
15650
- pointFrom18(maxX, gapLineY),
15651
- pointFrom18(gapSnap.gap.endSide[0][0], gapLineY)
15660
+ pointFrom17(maxX, gapLineY),
15661
+ pointFrom17(gapSnap.gap.endSide[0][0], gapLineY)
15652
15662
  ]
15653
15663
  }
15654
15664
  );
@@ -15663,16 +15673,16 @@ var createGapSnapLines = (selectedElements, dragOffset, gapSnaps) => {
15663
15673
  type: "gap",
15664
15674
  direction: "vertical",
15665
15675
  points: [
15666
- pointFrom18(gapLineX, gapSnap.gap.startSide[0][1]),
15667
- pointFrom18(gapLineX, minY)
15676
+ pointFrom17(gapLineX, gapSnap.gap.startSide[0][1]),
15677
+ pointFrom17(gapLineX, minY)
15668
15678
  ]
15669
15679
  },
15670
15680
  {
15671
15681
  type: "gap",
15672
15682
  direction: "vertical",
15673
15683
  points: [
15674
- pointFrom18(gapLineX, maxY),
15675
- pointFrom18(gapLineX, gapSnap.gap.endSide[0][1])
15684
+ pointFrom17(gapLineX, maxY),
15685
+ pointFrom17(gapLineX, gapSnap.gap.endSide[0][1])
15676
15686
  ]
15677
15687
  }
15678
15688
  );
@@ -15687,14 +15697,14 @@ var createGapSnapLines = (selectedElements, dragOffset, gapSnaps) => {
15687
15697
  type: "gap",
15688
15698
  direction: "horizontal",
15689
15699
  points: [
15690
- pointFrom18(startMaxX, gapLineY),
15691
- pointFrom18(endMinX, gapLineY)
15700
+ pointFrom17(startMaxX, gapLineY),
15701
+ pointFrom17(endMinX, gapLineY)
15692
15702
  ]
15693
15703
  },
15694
15704
  {
15695
15705
  type: "gap",
15696
15706
  direction: "horizontal",
15697
- points: [pointFrom18(endMaxX, gapLineY), pointFrom18(minX, gapLineY)]
15707
+ points: [pointFrom17(endMaxX, gapLineY), pointFrom17(minX, gapLineY)]
15698
15708
  }
15699
15709
  );
15700
15710
  }
@@ -15708,16 +15718,16 @@ var createGapSnapLines = (selectedElements, dragOffset, gapSnaps) => {
15708
15718
  type: "gap",
15709
15719
  direction: "horizontal",
15710
15720
  points: [
15711
- pointFrom18(maxX, gapLineY),
15712
- pointFrom18(startMinX, gapLineY)
15721
+ pointFrom17(maxX, gapLineY),
15722
+ pointFrom17(startMinX, gapLineY)
15713
15723
  ]
15714
15724
  },
15715
15725
  {
15716
15726
  type: "gap",
15717
15727
  direction: "horizontal",
15718
15728
  points: [
15719
- pointFrom18(startMaxX, gapLineY),
15720
- pointFrom18(endMinX, gapLineY)
15729
+ pointFrom17(startMaxX, gapLineY),
15730
+ pointFrom17(endMinX, gapLineY)
15721
15731
  ]
15722
15732
  }
15723
15733
  );
@@ -15732,16 +15742,16 @@ var createGapSnapLines = (selectedElements, dragOffset, gapSnaps) => {
15732
15742
  type: "gap",
15733
15743
  direction: "vertical",
15734
15744
  points: [
15735
- pointFrom18(gapLineX, maxY),
15736
- pointFrom18(gapLineX, startMinY)
15745
+ pointFrom17(gapLineX, maxY),
15746
+ pointFrom17(gapLineX, startMinY)
15737
15747
  ]
15738
15748
  },
15739
15749
  {
15740
15750
  type: "gap",
15741
15751
  direction: "vertical",
15742
15752
  points: [
15743
- pointFrom18(gapLineX, startMaxY),
15744
- pointFrom18(gapLineX, endMinY)
15753
+ pointFrom17(gapLineX, startMaxY),
15754
+ pointFrom17(gapLineX, endMinY)
15745
15755
  ]
15746
15756
  }
15747
15757
  );
@@ -15756,14 +15766,14 @@ var createGapSnapLines = (selectedElements, dragOffset, gapSnaps) => {
15756
15766
  type: "gap",
15757
15767
  direction: "vertical",
15758
15768
  points: [
15759
- pointFrom18(gapLineX, startMaxY),
15760
- pointFrom18(gapLineX, endMinY)
15769
+ pointFrom17(gapLineX, startMaxY),
15770
+ pointFrom17(gapLineX, endMinY)
15761
15771
  ]
15762
15772
  },
15763
15773
  {
15764
15774
  type: "gap",
15765
15775
  direction: "vertical",
15766
- points: [pointFrom18(gapLineX, endMaxY), pointFrom18(gapLineX, minY)]
15776
+ points: [pointFrom17(gapLineX, endMaxY), pointFrom17(gapLineX, minY)]
15767
15777
  }
15768
15778
  );
15769
15779
  }
@@ -15776,7 +15786,7 @@ var createGapSnapLines = (selectedElements, dragOffset, gapSnaps) => {
15776
15786
  return {
15777
15787
  ...gapSnapLine,
15778
15788
  points: gapSnapLine.points.map(
15779
- (p) => pointFrom18(round(p[0]), round(p[1]))
15789
+ (p) => pointFrom17(round(p[0]), round(p[1]))
15780
15790
  )
15781
15791
  };
15782
15792
  })
@@ -15806,35 +15816,35 @@ var snapResizingElements = (selectedElements, selectedOriginalElements, app, eve
15806
15816
  if (transformHandle) {
15807
15817
  switch (transformHandle) {
15808
15818
  case "e": {
15809
- selectionSnapPoints.push(pointFrom18(maxX, minY), pointFrom18(maxX, maxY));
15819
+ selectionSnapPoints.push(pointFrom17(maxX, minY), pointFrom17(maxX, maxY));
15810
15820
  break;
15811
15821
  }
15812
15822
  case "w": {
15813
- selectionSnapPoints.push(pointFrom18(minX, minY), pointFrom18(minX, maxY));
15823
+ selectionSnapPoints.push(pointFrom17(minX, minY), pointFrom17(minX, maxY));
15814
15824
  break;
15815
15825
  }
15816
15826
  case "n": {
15817
- selectionSnapPoints.push(pointFrom18(minX, minY), pointFrom18(maxX, minY));
15827
+ selectionSnapPoints.push(pointFrom17(minX, minY), pointFrom17(maxX, minY));
15818
15828
  break;
15819
15829
  }
15820
15830
  case "s": {
15821
- selectionSnapPoints.push(pointFrom18(minX, maxY), pointFrom18(maxX, maxY));
15831
+ selectionSnapPoints.push(pointFrom17(minX, maxY), pointFrom17(maxX, maxY));
15822
15832
  break;
15823
15833
  }
15824
15834
  case "ne": {
15825
- selectionSnapPoints.push(pointFrom18(maxX, minY));
15835
+ selectionSnapPoints.push(pointFrom17(maxX, minY));
15826
15836
  break;
15827
15837
  }
15828
15838
  case "nw": {
15829
- selectionSnapPoints.push(pointFrom18(minX, minY));
15839
+ selectionSnapPoints.push(pointFrom17(minX, minY));
15830
15840
  break;
15831
15841
  }
15832
15842
  case "se": {
15833
- selectionSnapPoints.push(pointFrom18(maxX, maxY));
15843
+ selectionSnapPoints.push(pointFrom17(maxX, maxY));
15834
15844
  break;
15835
15845
  }
15836
15846
  case "sw": {
15837
- selectionSnapPoints.push(pointFrom18(minX, maxY));
15847
+ selectionSnapPoints.push(pointFrom17(minX, maxY));
15838
15848
  break;
15839
15849
  }
15840
15850
  }
@@ -15867,10 +15877,10 @@ var snapResizingElements = (selectedElements, selectedOriginalElements, app, eve
15867
15877
  (bound) => round(bound)
15868
15878
  );
15869
15879
  const corners = [
15870
- pointFrom18(x1, y1),
15871
- pointFrom18(x1, y2),
15872
- pointFrom18(x2, y1),
15873
- pointFrom18(x2, y2)
15880
+ pointFrom17(x1, y1),
15881
+ pointFrom17(x1, y2),
15882
+ pointFrom17(x2, y1),
15883
+ pointFrom17(x2, y2)
15874
15884
  ];
15875
15885
  getPointSnaps(
15876
15886
  selectedElements,
@@ -15895,7 +15905,7 @@ var snapNewElement = (newElement7, app, event, origin, dragOffset, elementsMap)
15895
15905
  };
15896
15906
  }
15897
15907
  const selectionSnapPoints = [
15898
- pointFrom18(origin.x + dragOffset.x, origin.y + dragOffset.y)
15908
+ pointFrom17(origin.x + dragOffset.x, origin.y + dragOffset.y)
15899
15909
  ];
15900
15910
  const snapDistance = getSnapDistance(app.state.zoom.value);
15901
15911
  const minOffset = {
@@ -15970,7 +15980,7 @@ var getSnapLinesAtPointer = (elements, app, pointer, event, elementsMap) => {
15970
15980
  }
15971
15981
  verticalSnapLines.push({
15972
15982
  type: "pointer",
15973
- points: [corner, pointFrom18(corner[0], pointer.y)],
15983
+ points: [corner, pointFrom17(corner[0], pointer.y)],
15974
15984
  direction: "vertical"
15975
15985
  });
15976
15986
  minOffset.x = offsetX;
@@ -15982,7 +15992,7 @@ var getSnapLinesAtPointer = (elements, app, pointer, event, elementsMap) => {
15982
15992
  }
15983
15993
  horizontalSnapLines.push({
15984
15994
  type: "pointer",
15985
- points: [corner, pointFrom18(pointer.x, corner[1])],
15995
+ points: [corner, pointFrom17(pointer.x, corner[1])],
15986
15996
  direction: "horizontal"
15987
15997
  });
15988
15998
  minOffset.y = offsetY;
@@ -16587,8 +16597,8 @@ var LaserTrails = class {
16587
16597
  // textAutoResizeHandle.ts
16588
16598
  import { DEFAULT_TRANSFORM_HANDLE_SPACING } from "@excalidraw/common";
16589
16599
  import {
16590
- pointFrom as pointFrom19,
16591
- pointRotateRads as pointRotateRads15
16600
+ pointFrom as pointFrom18,
16601
+ pointRotateRads as pointRotateRads14
16592
16602
  } from "@excalidraw/math";
16593
16603
  var TEXT_AUTO_RESIZE_HANDLE_GAP = 12;
16594
16604
  var TEXT_AUTO_RESIZE_HANDLE_LENGTH = 16;
@@ -16603,24 +16613,24 @@ var getTextAutoResizeHandle = (textElement, zoomValue, formFactor) => {
16603
16613
  const padding = getTextBoxPadding(zoomValue);
16604
16614
  const gap = TEXT_AUTO_RESIZE_HANDLE_GAP / zoomValue;
16605
16615
  const length = TEXT_AUTO_RESIZE_HANDLE_LENGTH / zoomValue;
16606
- const center = pointFrom19(
16616
+ const center = pointFrom18(
16607
16617
  textElement.x + textElement.width / 2,
16608
16618
  textElement.y + textElement.height / 2
16609
16619
  );
16610
- const handleCenter = pointRotateRads15(
16611
- pointFrom19(center[0] + textElement.width / 2 + padding + gap, center[1]),
16620
+ const handleCenter = pointRotateRads14(
16621
+ pointFrom18(center[0] + textElement.width / 2 + padding + gap, center[1]),
16612
16622
  center,
16613
16623
  textElement.angle
16614
16624
  );
16615
16625
  return {
16616
16626
  center: handleCenter,
16617
- start: pointRotateRads15(
16618
- pointFrom19(handleCenter[0], handleCenter[1] - length / 2),
16627
+ start: pointRotateRads14(
16628
+ pointFrom18(handleCenter[0], handleCenter[1] - length / 2),
16619
16629
  handleCenter,
16620
16630
  textElement.angle
16621
16631
  ),
16622
- end: pointRotateRads15(
16623
- pointFrom19(handleCenter[0], handleCenter[1] + length / 2),
16632
+ end: pointRotateRads14(
16633
+ pointFrom18(handleCenter[0], handleCenter[1] + length / 2),
16624
16634
  handleCenter,
16625
16635
  textElement.angle
16626
16636
  ),
@@ -16633,8 +16643,8 @@ var isPointHittingTextAutoResizeHandle = (point, textElement, zoomValue, formFac
16633
16643
  if (!handle) {
16634
16644
  return false;
16635
16645
  }
16636
- const unrotatedPoint = pointRotateRads15(
16637
- pointFrom19(point.x, point.y),
16646
+ const unrotatedPoint = pointRotateRads14(
16647
+ pointFrom18(point.x, point.y),
16638
16648
  handle.center,
16639
16649
  -textElement.angle
16640
16650
  );
@@ -16656,7 +16666,7 @@ import {
16656
16666
  applyDarkModeFilter as applyDarkModeFilter3,
16657
16667
  isRTL as isRTL2
16658
16668
  } from "@excalidraw/common";
16659
- import { pointFrom as pointFrom20, pointRotateRads as pointRotateRads16 } from "@excalidraw/math";
16669
+ import { pointFrom as pointFrom19, pointRotateRads as pointRotateRads15 } from "@excalidraw/math";
16660
16670
  import {
16661
16671
  getTextFromElements as getTextFromElements2,
16662
16672
  originalContainerCache,
@@ -16915,7 +16925,10 @@ var textWysiwyg = ({
16915
16925
  ),
16916
16926
  textAlign,
16917
16927
  verticalAlign,
16918
- color: appState.theme === THEME11.DARK ? applyDarkModeFilter3(updatedTextElement.strokeColor) : updatedTextElement.strokeColor,
16928
+ color: applyDarkModeFilter3(
16929
+ updatedTextElement.strokeColor,
16930
+ appState.theme === THEME11.DARK
16931
+ ),
16919
16932
  opacity: updatedTextElement.opacity / 100,
16920
16933
  maxHeight: `${editorMaxHeight}px`
16921
16934
  });
@@ -16978,12 +16991,12 @@ var textWysiwyg = ({
16978
16991
  return null;
16979
16992
  }
16980
16993
  const layout = currentTextLayout;
16981
- const center = pointFrom20(
16994
+ const center = pointFrom19(
16982
16995
  layout.x + layout.width / 2,
16983
16996
  layout.y + layout.height / 2
16984
16997
  );
16985
- const [unrotatedX, unrotatedY] = pointRotateRads16(
16986
- pointFrom20(initialCaretSceneCoords.x, initialCaretSceneCoords.y),
16998
+ const [unrotatedX, unrotatedY] = pointRotateRads15(
16999
+ pointFrom19(initialCaretSceneCoords.x, initialCaretSceneCoords.y),
16987
17000
  center,
16988
17001
  -layout.angle
16989
17002
  );
@@ -17430,7 +17443,7 @@ var isOverScrollBars = (scrollBars, x, y) => {
17430
17443
 
17431
17444
  // lasso/index.ts
17432
17445
  import {
17433
- pointFrom as pointFrom21
17446
+ pointFrom as pointFrom20
17434
17447
  } from "@excalidraw/math";
17435
17448
  import { getElementLineSegments as getElementLineSegments2 } from "@excalidraw/element";
17436
17449
  import { LinearElementEditor as LinearElementEditor8 } from "@excalidraw/element/linearElementEditor";
@@ -17448,7 +17461,7 @@ import { arrayToMap as arrayToMap25, easeOut as easeOut2, isShallowEqual as isSh
17448
17461
  import { simplify as simplify2 } from "points-on-curve";
17449
17462
  import {
17450
17463
  polygonFromPoints as polygonFromPoints2,
17451
- lineSegment as lineSegment8,
17464
+ lineSegment as lineSegment7,
17452
17465
  polygonIncludesPointNonZero
17453
17466
  } from "@excalidraw/math";
17454
17467
  import {
@@ -17518,7 +17531,7 @@ var enclosureTest = (lassoPath, element, elementsSegments) => {
17518
17531
  });
17519
17532
  };
17520
17533
  var intersectionTest = (lassoPath, element, elementsMap) => {
17521
- const lassoSegments = lassoPath.slice(1).map((point, index) => lineSegment8(lassoPath[index], point)).concat([lineSegment8(lassoPath[lassoPath.length - 1], lassoPath[0])]);
17534
+ const lassoSegments = lassoPath.slice(1).map((point, index) => lineSegment7(lassoPath[index], point)).concat([lineSegment7(lassoPath[lassoPath.length - 1], lassoPath[0])]);
17522
17535
  const boundTextElement = getBoundTextElement6(element, elementsMap);
17523
17536
  return lassoSegments.some(
17524
17537
  (lassoSegment) => intersectElementWithLineSegment2(
@@ -17629,7 +17642,7 @@ var LassoTrail = class extends AnimatedTrail {
17629
17642
  this.updateSelection();
17630
17643
  });
17631
17644
  __publicField(this, "updateSelection", () => {
17632
- const lassoPath = super.getCurrentTrail()?.originalPoints?.map((p) => pointFrom21(p[0], p[1]));
17645
+ const lassoPath = super.getCurrentTrail()?.originalPoints?.map((p) => pointFrom20(p[0], p[1]));
17633
17646
  const currentCanvasTranslate = {
17634
17647
  scrollX: this.app.state.scrollX,
17635
17648
  scrollY: this.app.state.scrollY,
@@ -17738,9 +17751,9 @@ import {
17738
17751
  isPointInElement as isPointInElement2
17739
17752
  } from "@excalidraw/element";
17740
17753
  import {
17741
- lineSegment as lineSegment9,
17754
+ lineSegment as lineSegment8,
17742
17755
  lineSegmentsDistance,
17743
- pointFrom as pointFrom22,
17756
+ pointFrom as pointFrom21,
17744
17757
  polygon as polygon2,
17745
17758
  polygonIncludesPointNonZero as polygonIncludesPointNonZero2
17746
17759
  } from "@excalidraw/math";
@@ -17780,11 +17793,11 @@ var EraserTrail = class extends AnimatedTrail {
17780
17793
  return elementsToEraser;
17781
17794
  }
17782
17795
  updateElementsToBeErased(restoreToErase) {
17783
- const eraserPath = super.getCurrentTrail()?.originalPoints?.map((p) => pointFrom22(p[0], p[1])) || [];
17796
+ const eraserPath = super.getCurrentTrail()?.originalPoints?.map((p) => pointFrom21(p[0], p[1])) || [];
17784
17797
  if (eraserPath.length < 2) {
17785
17798
  return [];
17786
17799
  }
17787
- const pathSegment = lineSegment9(
17800
+ const pathSegment = lineSegment8(
17788
17801
  eraserPath[eraserPath.length - 1],
17789
17802
  eraserPath[eraserPath.length - 2]
17790
17803
  );
@@ -17901,7 +17914,7 @@ var eraserTest = (pathSegment, element, elementsMap, zoom) => {
17901
17914
  }
17902
17915
  const poly = polygon2(
17903
17916
  ...outlinePoints.map(
17904
- ([x, y]) => pointFrom22(element.x + x, element.y + y)
17917
+ ([x, y]) => pointFrom21(element.x + x, element.y + y)
17905
17918
  )
17906
17919
  );
17907
17920
  if (polygonIncludesPointNonZero2(pathSegment[0], poly)) {
@@ -17988,7 +18001,7 @@ var commonProps = {
17988
18001
  };
17989
18002
 
17990
18003
  // charts/charts.helpers.ts
17991
- import { pointFrom as pointFrom23 } from "@excalidraw/math";
18004
+ import { pointFrom as pointFrom22 } from "@excalidraw/math";
17992
18005
  import {
17993
18006
  COLOR_PALETTE as COLOR_PALETTE5,
17994
18007
  DEFAULT_CHART_COLOR_INDEX,
@@ -18478,7 +18491,7 @@ var chartLines = (spreadsheet, x, y, backgroundColor, layout) => {
18478
18491
  x,
18479
18492
  y,
18480
18493
  width: chartWidth,
18481
- points: [pointFrom23(0, 0), pointFrom23(chartWidth, 0)]
18494
+ points: [pointFrom22(0, 0), pointFrom22(chartWidth, 0)]
18482
18495
  });
18483
18496
  const yLine = newLinearElement({
18484
18497
  backgroundColor,
@@ -18487,7 +18500,7 @@ var chartLines = (spreadsheet, x, y, backgroundColor, layout) => {
18487
18500
  x,
18488
18501
  y,
18489
18502
  height: chartHeight,
18490
- points: [pointFrom23(0, 0), pointFrom23(0, -chartHeight)]
18503
+ points: [pointFrom22(0, 0), pointFrom22(0, -chartHeight)]
18491
18504
  });
18492
18505
  const maxLine = newLinearElement({
18493
18506
  backgroundColor,
@@ -18498,7 +18511,7 @@ var chartLines = (spreadsheet, x, y, backgroundColor, layout) => {
18498
18511
  strokeStyle: "dotted",
18499
18512
  width: chartWidth,
18500
18513
  opacity: GRID_OPACITY,
18501
- points: [pointFrom23(0, 0), pointFrom23(chartWidth, 0)]
18514
+ points: [pointFrom22(0, 0), pointFrom22(chartWidth, 0)]
18502
18515
  });
18503
18516
  return [xLine, yLine, maxLine];
18504
18517
  };
@@ -18601,7 +18614,7 @@ var renderBarChart = (spreadsheet, x, y, colorSeed) => {
18601
18614
  };
18602
18615
 
18603
18616
  // charts/charts.line.ts
18604
- import { pointFrom as pointFrom24 } from "@excalidraw/math";
18617
+ import { pointFrom as pointFrom23 } from "@excalidraw/math";
18605
18618
  import { isDevEnv as isDevEnv7 } from "@excalidraw/common";
18606
18619
  import { newElement as newElement4, newLinearElement as newLinearElement2 } from "@excalidraw/element";
18607
18620
  var renderLineChart = (spreadsheet, x, y, colorSeed) => {
@@ -18613,7 +18626,7 @@ var renderLineChart = (spreadsheet, x, y, colorSeed) => {
18613
18626
  const seriesColors = getSeriesColors(series.length, colorOffset);
18614
18627
  const lines = series.map((seriesData, seriesIndex) => {
18615
18628
  const points = seriesData.values.map(
18616
- (value, valueIndex) => pointFrom24(
18629
+ (value, valueIndex) => pointFrom23(
18617
18630
  valueIndex * (layout.slotWidth + layout.gap),
18618
18631
  -(value / max) * layout.chartHeight
18619
18632
  )
@@ -18671,7 +18684,7 @@ var renderLineChart = (spreadsheet, x, y, colorSeed) => {
18671
18684
  height: cy,
18672
18685
  strokeStyle: "dotted",
18673
18686
  opacity: GRID_OPACITY,
18674
- points: [pointFrom24(0, 0), pointFrom24(0, cy)]
18687
+ points: [pointFrom23(0, 0), pointFrom23(0, cy)]
18675
18688
  });
18676
18689
  });
18677
18690
  const baseElements = chartBaseElements(
@@ -18820,7 +18833,7 @@ var tryParseSpreadsheet = (text) => {
18820
18833
  };
18821
18834
 
18822
18835
  // charts/charts.radar.ts
18823
- import { pointFrom as pointFrom25 } from "@excalidraw/math";
18836
+ import { pointFrom as pointFrom24 } from "@excalidraw/math";
18824
18837
  import {
18825
18838
  FONT_FAMILY as FONT_FAMILY5,
18826
18839
  FONT_SIZES as FONT_SIZES3,
@@ -18887,12 +18900,12 @@ var renderRadarChart = (spreadsheet, x, y, colorSeed) => {
18887
18900
  const levelRatio = (levelIndex + 1) / RADAR_GRID_LEVELS;
18888
18901
  const levelRadius = radius * levelRatio;
18889
18902
  const points = angles.map(
18890
- (angle) => pointFrom25(
18903
+ (angle) => pointFrom24(
18891
18904
  Math.cos(angle) * levelRadius,
18892
18905
  Math.sin(angle) * levelRadius
18893
18906
  )
18894
18907
  );
18895
- points.push(pointFrom25(points[0][0], points[0][1]));
18908
+ points.push(pointFrom24(points[0][0], points[0][1]));
18896
18909
  return newLinearElement3({
18897
18910
  backgroundColor: "transparent",
18898
18911
  ...commonProps,
@@ -18922,19 +18935,19 @@ var renderRadarChart = (spreadsheet, x, y, colorSeed) => {
18922
18935
  strokeStyle: "solid",
18923
18936
  roughness: ROUGHNESS3.architect,
18924
18937
  opacity: GRID_OPACITY,
18925
- points: [pointFrom25(0, 0), pointFrom25(px, py)]
18938
+ points: [pointFrom24(0, 0), pointFrom24(px, py)]
18926
18939
  });
18927
18940
  });
18928
18941
  const seriesPolygons = series.map((seriesData, index) => {
18929
18942
  const points = angles.map((angle, axisIndex) => {
18930
18943
  const value = seriesData.values[axisIndex] ?? 0;
18931
18944
  const pointRadius = normalize(value, axisIndex) * radius;
18932
- return pointFrom25(
18945
+ return pointFrom24(
18933
18946
  Math.cos(angle) * pointRadius,
18934
18947
  Math.sin(angle) * pointRadius
18935
18948
  );
18936
18949
  });
18937
- points.push(pointFrom25(points[0][0], points[0][1]));
18950
+ points.push(pointFrom24(points[0][0], points[0][1]));
18938
18951
  return newLinearElement3({
18939
18952
  backgroundColor: "transparent",
18940
18953
  ...commonProps,
@@ -18986,7 +18999,7 @@ import {
18986
18999
  mutateElement as mutateElement4,
18987
19000
  updateElbowArrowPoints as updateElbowArrowPoints3
18988
19001
  } from "@excalidraw/element";
18989
- import { pointFrom as pointFrom26, pointRotateRads as pointRotateRads17 } from "@excalidraw/math";
19002
+ import { pointFrom as pointFrom25, pointRotateRads as pointRotateRads16 } from "@excalidraw/math";
18990
19003
  import {
18991
19004
  hasBoundTextElement as hasBoundTextElement5,
18992
19005
  isArrowBoundToElement,
@@ -19106,14 +19119,14 @@ var Panel = ({
19106
19119
  elements2[0],
19107
19120
  app.scene.getNonDeletedElementsMap()
19108
19121
  );
19109
- bottomLeft = pointRotateRads17(
19110
- pointFrom26(x1, y2),
19111
- pointFrom26(cx, cy),
19122
+ bottomLeft = pointRotateRads16(
19123
+ pointFrom25(x1, y2),
19124
+ pointFrom25(cx, cy),
19112
19125
  elements2[0].angle
19113
19126
  );
19114
19127
  } else {
19115
19128
  const { minX, maxY } = getCommonBoundingBox2(elements2);
19116
- bottomLeft = pointFrom26(minX, maxY);
19129
+ bottomLeft = pointFrom25(minX, maxY);
19117
19130
  }
19118
19131
  const { x, y } = sceneCoordsToViewportCoords4(
19119
19132
  { sceneX: bottomLeft[0], sceneY: bottomLeft[1] },
@@ -19432,7 +19445,7 @@ var convertLineToElbow = (line) => {
19432
19445
  if (isVert(start2, end) || isHorz(start2, end)) {
19433
19446
  ortho.push(end);
19434
19447
  } else {
19435
- ortho.push(pointFrom26(start2[0], end[1]));
19448
+ ortho.push(pointFrom25(start2[0], end[1]));
19436
19449
  ortho.push(end);
19437
19450
  }
19438
19451
  }
@@ -20042,7 +20055,7 @@ import {
20042
20055
  CLASSES as CLASSES9,
20043
20056
  DEFAULT_SIDEBAR as DEFAULT_SIDEBAR4,
20044
20057
  TOOL_TYPE as TOOL_TYPE2,
20045
- arrayToMap as arrayToMap28,
20058
+ arrayToMap as arrayToMap27,
20046
20059
  capitalizeString as capitalizeString4,
20047
20060
  isShallowEqual as isShallowEqual5
20048
20061
  } from "@excalidraw/common";
@@ -21921,7 +21934,7 @@ var MobileMenu = ({
21921
21934
  },
21922
21935
  children: [
21923
21936
  /* @__PURE__ */ jsx79("div", { className: "App-bottom-bar-item", children: /* @__PURE__ */ jsx79(Island, { children: /* @__PURE__ */ jsxs38("div", { className: "mobile-toolbar", children: [
21924
- actionManager.renderAction("viewMode"),
21937
+ !appState.viewModeOnly && actionManager.renderAction("viewMode"),
21925
21938
  actionManager.renderAction("smartZoom")
21926
21939
  ] }) }) }),
21927
21940
  !appState.viewModeEnabled && /* @__PURE__ */ jsxs38("div", { className: "App-bottom-bar-item", children: [
@@ -22630,7 +22643,7 @@ var Footer = ({
22630
22643
  "layer-ui__wrapper__footer-left--transition-left": appState.zenModeEnabled
22631
22644
  }),
22632
22645
  children: /* @__PURE__ */ jsx87(Stack_default.Col, { gap: 2, children: /* @__PURE__ */ jsxs45(Section, { heading: "canvasActions", children: [
22633
- /* @__PURE__ */ jsx87(Tooltip, { label: t("labels.viewMode"), children: /* @__PURE__ */ jsx87("div", { className: clsx37("view-mode-button"), children: actionManager.renderAction("viewMode") }) }),
22646
+ !appState.viewModeOnly && /* @__PURE__ */ jsx87(Tooltip, { label: t("labels.viewMode"), children: /* @__PURE__ */ jsx87("div", { className: clsx37("view-mode-button"), children: actionManager.renderAction("viewMode") }) }),
22634
22647
  /* @__PURE__ */ jsx87(Tooltip, { label: t("buttons.smartZoom"), children: /* @__PURE__ */ jsx87("div", { className: clsx37("smart-zoom-button"), children: actionManager.renderAction("smartZoom") }) }),
22635
22648
  /* @__PURE__ */ jsx87(
22636
22649
  ZoomActions,
@@ -23309,6 +23322,7 @@ var ToggleTheme = (props) => {
23309
23322
  const appState = useUIAppState();
23310
23323
  const actionManager = useExcalidrawActionManager();
23311
23324
  const shortcut = getShortcutFromShortcutName("toggleTheme");
23325
+ const appProps = useAppProps();
23312
23326
  if (!actionManager.isActionEnabled(actionToggleTheme)) {
23313
23327
  return null;
23314
23328
  }
@@ -23318,7 +23332,15 @@ var ToggleTheme = (props) => {
23318
23332
  {
23319
23333
  name: "theme",
23320
23334
  value: props.theme,
23321
- onChange: (value) => props.onSelect(value),
23335
+ onChange: (value) => {
23336
+ if (appProps.onThemeChange) {
23337
+ appProps.onThemeChange(value);
23338
+ return;
23339
+ }
23340
+ console.warn(
23341
+ "MainMenu.DefaultItems.ToggleTheme: `<Excalidraw/> props.onThemeChange` must be defined to use system theme selection."
23342
+ );
23343
+ },
23322
23344
  choices: [
23323
23345
  {
23324
23346
  value: THEME14.LIGHT,
@@ -23345,13 +23367,7 @@ var ToggleTheme = (props) => {
23345
23367
  {
23346
23368
  onSelect: (event) => {
23347
23369
  event.preventDefault();
23348
- if (props?.onSelect) {
23349
- props.onSelect(
23350
- appState.theme === THEME14.DARK ? THEME14.LIGHT : THEME14.DARK
23351
- );
23352
- } else {
23353
- return actionManager.executeAction(actionToggleTheme);
23354
- }
23370
+ actionManager.executeAction(actionToggleTheme);
23355
23371
  },
23356
23372
  icon: appState.theme === THEME14.DARK ? SunIcon : MoonIcon,
23357
23373
  "data-testid": "toggle-dark-mode",
@@ -23591,6 +23607,9 @@ var PreferencesToggleViewModeItem = () => {
23591
23607
  const { t: t2 } = useI18n();
23592
23608
  const actionManager = useExcalidrawActionManager();
23593
23609
  const appState = useUIAppState();
23610
+ if (appState.viewModeOnly) {
23611
+ return null;
23612
+ }
23594
23613
  return /* @__PURE__ */ jsx99(
23595
23614
  DropdownMenuItemCheckbox_default,
23596
23615
  {
@@ -24722,7 +24741,7 @@ import { deepCopyElement as deepCopyElement3 } from "@excalidraw/element";
24722
24741
  import { CaptureUpdateAction as CaptureUpdateAction40 } from "@excalidraw/element";
24723
24742
 
24724
24743
  // components/Stats/utils.ts
24725
- import { pointFrom as pointFrom27, pointRotateRads as pointRotateRads18 } from "@excalidraw/math";
24744
+ import { pointFrom as pointFrom26, pointRotateRads as pointRotateRads17 } from "@excalidraw/math";
24726
24745
  import {
24727
24746
  getBoundTextElement as getBoundTextElement9,
24728
24747
  isBindingElement as isBindingElement3,
@@ -24772,16 +24791,16 @@ var moveElement = (newTopLeftX, newTopLeftY, originalElement, scene, appState, o
24772
24791
  originalElement.x + originalElement.width / 2,
24773
24792
  originalElement.y + originalElement.height / 2
24774
24793
  ];
24775
- const [topLeftX, topLeftY] = pointRotateRads18(
24776
- pointFrom27(originalElement.x, originalElement.y),
24777
- pointFrom27(cx, cy),
24794
+ const [topLeftX, topLeftY] = pointRotateRads17(
24795
+ pointFrom26(originalElement.x, originalElement.y),
24796
+ pointFrom26(cx, cy),
24778
24797
  originalElement.angle
24779
24798
  );
24780
24799
  const changeInX = newTopLeftX - topLeftX;
24781
24800
  const changeInY = newTopLeftY - topLeftY;
24782
- const [x, y] = pointRotateRads18(
24783
- pointFrom27(newTopLeftX, newTopLeftY),
24784
- pointFrom27(cx + changeInX, cy + changeInY),
24801
+ const [x, y] = pointRotateRads17(
24802
+ pointFrom26(newTopLeftX, newTopLeftY),
24803
+ pointFrom26(cx + changeInX, cy + changeInY),
24785
24804
  -originalElement.angle
24786
24805
  );
24787
24806
  scene.mutateElement(
@@ -24822,16 +24841,16 @@ var moveElement = (newTopLeftX, newTopLeftY, originalElement, scene, appState, o
24822
24841
  child.x + child.width / 2,
24823
24842
  child.y + child.height / 2
24824
24843
  ];
24825
- const [childTopLeftX, childTopLeftY] = pointRotateRads18(
24826
- pointFrom27(child.x, child.y),
24827
- pointFrom27(childCX, childCY),
24844
+ const [childTopLeftX, childTopLeftY] = pointRotateRads17(
24845
+ pointFrom26(child.x, child.y),
24846
+ pointFrom26(childCX, childCY),
24828
24847
  child.angle
24829
24848
  );
24830
24849
  const childNewTopLeftX = Math.round(childTopLeftX + changeInX);
24831
24850
  const childNewTopLeftY = Math.round(childTopLeftY + changeInY);
24832
- const [childX, childY] = pointRotateRads18(
24833
- pointFrom27(childNewTopLeftX, childNewTopLeftY),
24834
- pointFrom27(childCX + changeInX, childCY + changeInY),
24851
+ const [childX, childY] = pointRotateRads17(
24852
+ pointFrom26(childNewTopLeftX, childNewTopLeftY),
24853
+ pointFrom26(childCX + changeInX, childCY + changeInY),
24835
24854
  -child.angle
24836
24855
  );
24837
24856
  scene.mutateElement(
@@ -25660,7 +25679,7 @@ var MultiAngle = ({
25660
25679
  var MultiAngle_default = MultiAngle;
25661
25680
 
25662
25681
  // components/Stats/MultiDimension.tsx
25663
- import { pointFrom as pointFrom29 } from "@excalidraw/math";
25682
+ import { pointFrom as pointFrom27 } from "@excalidraw/math";
25664
25683
  import { useMemo as useMemo8 } from "react";
25665
25684
  import { MIN_WIDTH_OR_HEIGHT as MIN_WIDTH_OR_HEIGHT2 } from "@excalidraw/common";
25666
25685
  import {
@@ -25674,7 +25693,7 @@ import {
25674
25693
  resizeSingleElement as resizeSingleElement2
25675
25694
  } from "@excalidraw/element";
25676
25695
  import { getBoundTextElement as getBoundTextElement13, handleBindTextResize as handleBindTextResize2 } from "@excalidraw/element";
25677
- import { isTextElement as isTextElement14 } from "@excalidraw/element";
25696
+ import { isTextElement as isTextElement13 } from "@excalidraw/element";
25678
25697
 
25679
25698
  // ../utils/src/export.ts
25680
25699
  import { MIME_TYPES as MIME_TYPES6 } from "@excalidraw/common";
@@ -25808,147 +25827,8 @@ var exportToClipboard = async (opts) => {
25808
25827
  }
25809
25828
  };
25810
25829
 
25811
- // ../utils/src/withinBounds.ts
25812
- import { arrayToMap as arrayToMap27 } from "@excalidraw/common";
25813
- import { getElementBounds as getElementBounds4 } from "@excalidraw/element";
25814
- import {
25815
- isArrowElement as isArrowElement12,
25816
- isExcalidrawElement as isExcalidrawElement3,
25817
- isFreeDrawElement as isFreeDrawElement4,
25818
- isLinearElement as isLinearElement9,
25819
- isTextElement as isTextElement13
25820
- } from "@excalidraw/element";
25821
- import {
25822
- rangeIncludesValue,
25823
- pointFrom as pointFrom28,
25824
- pointRotateRads as pointRotateRads19,
25825
- rangeInclusive as rangeInclusive2
25826
- } from "@excalidraw/math";
25827
- var getNonLinearElementRelativePoints = (element) => {
25828
- if (element.type === "diamond") {
25829
- return [
25830
- pointFrom28(element.width / 2, 0),
25831
- pointFrom28(element.width, element.height / 2),
25832
- pointFrom28(element.width / 2, element.height),
25833
- pointFrom28(0, element.height / 2)
25834
- ];
25835
- }
25836
- return [
25837
- pointFrom28(0, 0),
25838
- pointFrom28(0 + element.width, 0),
25839
- pointFrom28(0 + element.width, element.height),
25840
- pointFrom28(0, element.height)
25841
- ];
25842
- };
25843
- var getElementRelativePoints = (element) => {
25844
- if (isLinearElement9(element) || isFreeDrawElement4(element)) {
25845
- return element.points;
25846
- }
25847
- return getNonLinearElementRelativePoints(element);
25848
- };
25849
- var getMinMaxPoints = (points) => {
25850
- const ret = points.reduce(
25851
- (limits, [x, y]) => {
25852
- limits.minY = Math.min(limits.minY, y);
25853
- limits.minX = Math.min(limits.minX, x);
25854
- limits.maxX = Math.max(limits.maxX, x);
25855
- limits.maxY = Math.max(limits.maxY, y);
25856
- return limits;
25857
- },
25858
- {
25859
- minX: Infinity,
25860
- minY: Infinity,
25861
- maxX: -Infinity,
25862
- maxY: -Infinity,
25863
- cx: 0,
25864
- cy: 0
25865
- }
25866
- );
25867
- ret.cx = (ret.maxX + ret.minX) / 2;
25868
- ret.cy = (ret.maxY + ret.minY) / 2;
25869
- return ret;
25870
- };
25871
- var getRotatedBBox = (element) => {
25872
- const points = getElementRelativePoints(element);
25873
- const { cx, cy } = getMinMaxPoints(points);
25874
- const centerPoint = pointFrom28(cx, cy);
25875
- const rotatedPoints = points.map(
25876
- (p) => pointRotateRads19(p, centerPoint, element.angle)
25877
- );
25878
- const { minX, minY, maxX, maxY } = getMinMaxPoints(rotatedPoints);
25879
- return [
25880
- minX + element.x,
25881
- minY + element.y,
25882
- maxX + element.x,
25883
- maxY + element.y
25884
- ];
25885
- };
25886
- var isElementInsideBBox = (element, bbox, eitherDirection = false) => {
25887
- const elementBBox = getRotatedBBox(element);
25888
- const elementInsideBbox = bbox[0] <= elementBBox[0] && bbox[2] >= elementBBox[2] && bbox[1] <= elementBBox[1] && bbox[3] >= elementBBox[3];
25889
- if (!eitherDirection) {
25890
- return elementInsideBbox;
25891
- }
25892
- if (elementInsideBbox) {
25893
- return true;
25894
- }
25895
- return elementBBox[0] <= bbox[0] && elementBBox[2] >= bbox[2] && elementBBox[1] <= bbox[1] && elementBBox[3] >= bbox[3];
25896
- };
25897
- var elementPartiallyOverlapsWithOrContainsBBox = (element, bbox) => {
25898
- const elementBBox = getRotatedBBox(element);
25899
- return (rangeIncludesValue(elementBBox[0], rangeInclusive2(bbox[0], bbox[2])) || rangeIncludesValue(
25900
- bbox[0],
25901
- rangeInclusive2(elementBBox[0], elementBBox[2])
25902
- )) && (rangeIncludesValue(elementBBox[1], rangeInclusive2(bbox[1], bbox[3])) || rangeIncludesValue(
25903
- bbox[1],
25904
- rangeInclusive2(elementBBox[1], elementBBox[3])
25905
- ));
25906
- };
25907
- var elementsOverlappingBBox = ({
25908
- elements,
25909
- bounds,
25910
- type,
25911
- errorMargin = 0
25912
- }) => {
25913
- if (isExcalidrawElement3(bounds)) {
25914
- bounds = getElementBounds4(bounds, arrayToMap27(elements));
25915
- }
25916
- const adjustedBBox = [
25917
- bounds[0] - errorMargin,
25918
- bounds[1] - errorMargin,
25919
- bounds[2] + errorMargin,
25920
- bounds[3] + errorMargin
25921
- ];
25922
- const includedElementSet = /* @__PURE__ */ new Set();
25923
- for (const element of elements) {
25924
- if (includedElementSet.has(element.id)) {
25925
- continue;
25926
- }
25927
- const isOverlaping = type === "overlap" ? elementPartiallyOverlapsWithOrContainsBBox(element, adjustedBBox) : type === "inside" ? isElementInsideBBox(element, adjustedBBox) : isElementInsideBBox(element, adjustedBBox, true);
25928
- if (isOverlaping) {
25929
- includedElementSet.add(element.id);
25930
- if (element.boundElements) {
25931
- for (const boundElement of element.boundElements) {
25932
- includedElementSet.add(boundElement.id);
25933
- }
25934
- }
25935
- if (isTextElement13(element) && element.containerId) {
25936
- includedElementSet.add(element.containerId);
25937
- }
25938
- if (isArrowElement12(element)) {
25939
- if (element.startBinding) {
25940
- includedElementSet.add(element.startBinding.elementId);
25941
- }
25942
- if (element.endBinding) {
25943
- includedElementSet.add(element.endBinding?.elementId);
25944
- }
25945
- }
25946
- }
25947
- }
25948
- return elements.filter((element) => includedElementSet.has(element.id));
25949
- };
25950
-
25951
25830
  // ../utils/src/index.ts
25831
+ import { elementsOverlappingBBox as elementsOverlappingBBox2 } from "@excalidraw/element";
25952
25832
  import { getCommonBounds as getCommonBounds6 } from "@excalidraw/element";
25953
25833
 
25954
25834
  // components/Stats/MultiDimension.tsx
@@ -25967,7 +25847,7 @@ var getResizedUpdates = (anchorX, anchorY, scale, origElement) => {
25967
25847
  x,
25968
25848
  y,
25969
25849
  ...rescalePointsInElement(origElement, nextWidth, nextHeight, false),
25970
- ...isTextElement14(origElement) ? { fontSize: origElement.fontSize * scale } : {}
25850
+ ...isTextElement13(origElement) ? { fontSize: origElement.fontSize * scale } : {}
25971
25851
  };
25972
25852
  };
25973
25853
  var resizeElementInGroup = (anchorX, anchorY, property, scale, latestElement, origElement, originalElementsMap, scene) => {
@@ -25982,7 +25862,7 @@ var resizeElementInGroup = (anchorX, anchorY, property, scale, latestElement, or
25982
25862
  const newFontSize = boundTextElement.fontSize * scale;
25983
25863
  updateBoundElements3(latestElement, scene);
25984
25864
  const latestBoundTextElement = elementsMap.get(boundTextElement.id);
25985
- if (latestBoundTextElement && isTextElement14(latestBoundTextElement)) {
25865
+ if (latestBoundTextElement && isTextElement13(latestBoundTextElement)) {
25986
25866
  scene.mutateElement(latestBoundTextElement, {
25987
25867
  fontSize: newFontSize
25988
25868
  });
@@ -26058,7 +25938,7 @@ var handleDimensionChange2 = ({
26058
25938
  nextHeight,
26059
25939
  initialHeight,
26060
25940
  aspectRatio,
26061
- pointFrom29(x1, y1),
25941
+ pointFrom27(x1, y1),
26062
25942
  property,
26063
25943
  latestElements,
26064
25944
  originalElements2,
@@ -26159,7 +26039,7 @@ var handleDimensionChange2 = ({
26159
26039
  nextHeight,
26160
26040
  initialHeight,
26161
26041
  aspectRatio,
26162
- pointFrom29(x1, y1),
26042
+ pointFrom27(x1, y1),
26163
26043
  property,
26164
26044
  latestElements,
26165
26045
  originalElements2,
@@ -26293,7 +26173,7 @@ import {
26293
26173
  getBoundTextElement as getBoundTextElement14,
26294
26174
  redrawTextBoundingBox as redrawTextBoundingBox7
26295
26175
  } from "@excalidraw/element";
26296
- import { hasBoundTextElement as hasBoundTextElement8, isTextElement as isTextElement15 } from "@excalidraw/element";
26176
+ import { hasBoundTextElement as hasBoundTextElement8, isTextElement as isTextElement14 } from "@excalidraw/element";
26297
26177
  import { isInGroup as isInGroup3 } from "@excalidraw/element";
26298
26178
  import { jsx as jsx114 } from "react/jsx-runtime";
26299
26179
  var MIN_FONT_SIZE2 = 4;
@@ -26303,7 +26183,7 @@ var getApplicableTextElements = (elements, elementsMap) => elements.reduce(
26303
26183
  if (!el || isInGroup3(el)) {
26304
26184
  return acc;
26305
26185
  }
26306
- if (isTextElement15(el)) {
26186
+ if (isTextElement14(el)) {
26307
26187
  acc.push(el);
26308
26188
  return acc;
26309
26189
  }
@@ -26403,9 +26283,9 @@ var MultiFontSize = ({
26403
26283
  var MultiFontSize_default = MultiFontSize;
26404
26284
 
26405
26285
  // components/Stats/MultiPosition.tsx
26406
- import { pointFrom as pointFrom30, pointRotateRads as pointRotateRads20 } from "@excalidraw/math";
26286
+ import { pointFrom as pointFrom28, pointRotateRads as pointRotateRads18 } from "@excalidraw/math";
26407
26287
  import { useMemo as useMemo9 } from "react";
26408
- import { isTextElement as isTextElement16 } from "@excalidraw/element";
26288
+ import { isTextElement as isTextElement15 } from "@excalidraw/element";
26409
26289
  import { getCommonBounds as getCommonBounds7 } from "@excalidraw/element";
26410
26290
  import { jsx as jsx115 } from "react/jsx-runtime";
26411
26291
  var moveElements = (property, changeInTopX, changeInTopY, originalElements, originalElementsMap, scene, appState) => {
@@ -26415,9 +26295,9 @@ var moveElements = (property, changeInTopX, changeInTopY, originalElements, orig
26415
26295
  origElement.x + origElement.width / 2,
26416
26296
  origElement.y + origElement.height / 2
26417
26297
  ];
26418
- const [topLeftX, topLeftY] = pointRotateRads20(
26419
- pointFrom30(origElement.x, origElement.y),
26420
- pointFrom30(cx, cy),
26298
+ const [topLeftX, topLeftY] = pointRotateRads18(
26299
+ pointFrom28(origElement.x, origElement.y),
26300
+ pointFrom28(cx, cy),
26421
26301
  origElement.angle
26422
26302
  );
26423
26303
  const newTopLeftX = property === "x" ? Math.round(topLeftX + changeInTopX) : topLeftX;
@@ -26444,14 +26324,14 @@ var moveGroupTo = (nextX, nextY, originalElements, originalElementsMap, scene, a
26444
26324
  if (!latestElement) {
26445
26325
  continue;
26446
26326
  }
26447
- if (!isTextElement16(latestElement) || !latestElement.containerId) {
26327
+ if (!isTextElement15(latestElement) || !latestElement.containerId) {
26448
26328
  const [cx, cy] = [
26449
26329
  latestElement.x + latestElement.width / 2,
26450
26330
  latestElement.y + latestElement.height / 2
26451
26331
  ];
26452
- const [topLeftX, topLeftY] = pointRotateRads20(
26453
- pointFrom30(latestElement.x, latestElement.y),
26454
- pointFrom30(cx, cy),
26332
+ const [topLeftX, topLeftY] = pointRotateRads18(
26333
+ pointFrom28(latestElement.x, latestElement.y),
26334
+ pointFrom28(cx, cy),
26455
26335
  latestElement.angle
26456
26336
  );
26457
26337
  moveElement(
@@ -26510,9 +26390,9 @@ var handlePositionChange = ({
26510
26390
  origElement.x + origElement.width / 2,
26511
26391
  origElement.y + origElement.height / 2
26512
26392
  ];
26513
- const [topLeftX, topLeftY] = pointRotateRads20(
26514
- pointFrom30(origElement.x, origElement.y),
26515
- pointFrom30(cx, cy),
26393
+ const [topLeftX, topLeftY] = pointRotateRads18(
26394
+ pointFrom28(origElement.x, origElement.y),
26395
+ pointFrom28(cx, cy),
26516
26396
  origElement.angle
26517
26397
  );
26518
26398
  const newTopLeftX = property === "x" ? nextValue : topLeftX;
@@ -26563,9 +26443,9 @@ var MultiPosition = ({
26563
26443
  }
26564
26444
  const [el] = elementsInUnit;
26565
26445
  const [cx, cy] = [el.x + el.width / 2, el.y + el.height / 2];
26566
- const [topLeftX, topLeftY] = pointRotateRads20(
26567
- pointFrom30(el.x, el.y),
26568
- pointFrom30(cx, cy),
26446
+ const [topLeftX, topLeftY] = pointRotateRads18(
26447
+ pointFrom28(el.x, el.y),
26448
+ pointFrom28(cx, cy),
26569
26449
  el.angle
26570
26450
  );
26571
26451
  return Math.round((property === "x" ? topLeftX : topLeftY) * 100) / 100;
@@ -26589,7 +26469,7 @@ var MultiPosition = ({
26589
26469
  var MultiPosition_default = MultiPosition;
26590
26470
 
26591
26471
  // components/Stats/Position.tsx
26592
- import { clamp as clamp6, pointFrom as pointFrom31, pointRotateRads as pointRotateRads21, round as round4 } from "@excalidraw/math";
26472
+ import { clamp as clamp6, pointFrom as pointFrom29, pointRotateRads as pointRotateRads19, round as round4 } from "@excalidraw/math";
26593
26473
  import {
26594
26474
  getFlipAdjustedCropPosition,
26595
26475
  getUncroppedWidthAndHeight as getUncroppedWidthAndHeight2
@@ -26614,9 +26494,9 @@ var handlePositionChange2 = ({
26614
26494
  origElement.x + origElement.width / 2,
26615
26495
  origElement.y + origElement.height / 2
26616
26496
  ];
26617
- const [topLeftX, topLeftY] = pointRotateRads21(
26618
- pointFrom31(origElement.x, origElement.y),
26619
- pointFrom31(cx, cy),
26497
+ const [topLeftX, topLeftY] = pointRotateRads19(
26498
+ pointFrom29(origElement.x, origElement.y),
26499
+ pointFrom29(cx, cy),
26620
26500
  origElement.angle
26621
26501
  );
26622
26502
  if (originalAppState.croppingElementId === origElement.id) {
@@ -26716,9 +26596,9 @@ var Position = ({
26716
26596
  scene,
26717
26597
  appState
26718
26598
  }) => {
26719
- const [topLeftX, topLeftY] = pointRotateRads21(
26720
- pointFrom31(element.x, element.y),
26721
- pointFrom31(element.x + element.width / 2, element.y + element.height / 2),
26599
+ const [topLeftX, topLeftY] = pointRotateRads19(
26600
+ pointFrom29(element.x, element.y),
26601
+ pointFrom29(element.x + element.width / 2, element.y + element.height / 2),
26722
26602
  element.angle
26723
26603
  );
26724
26604
  let value = round4(property === "x" ? topLeftX : topLeftY, 2);
@@ -28047,10 +27927,10 @@ import { CANVAS_SEARCH_TAB as CANVAS_SEARCH_TAB3, DEFAULT_SIDEBAR as DEFAULT_SID
28047
27927
  import {
28048
27928
  isFlowchartNodeElement,
28049
27929
  isImageElement as isImageElement7,
28050
- isLinearElement as isLinearElement10,
27930
+ isLinearElement as isLinearElement9,
28051
27931
  isLineElement as isLineElement6,
28052
27932
  isTextBindableContainer as isTextBindableContainer2,
28053
- isTextElement as isTextElement17
27933
+ isTextElement as isTextElement16
28054
27934
  } from "@excalidraw/element";
28055
27935
  import { isNodeInFlowchart } from "@excalidraw/element";
28056
27936
  import { jsx as jsx124 } from "react/jsx-runtime";
@@ -28108,7 +27988,7 @@ var getHints = ({
28108
27988
  }
28109
27989
  if (isResizing && lastPointerDownWith === "mouse" && selectedElements.length === 1) {
28110
27990
  const targetElement = selectedElements[0];
28111
- if (isLinearElement10(targetElement) && targetElement.points.length === 2) {
27991
+ if (isLinearElement9(targetElement) && targetElement.points.length === 2) {
28112
27992
  return t("hints.lockAngle", {
28113
27993
  shortcut: getTaggedShortcutKey("Shift")
28114
27994
  });
@@ -28126,7 +28006,7 @@ var getHints = ({
28126
28006
  shortcut: getTaggedShortcutKey("Shift")
28127
28007
  });
28128
28008
  }
28129
- if (selectedElements.length === 1 && isTextElement17(selectedElements[0])) {
28009
+ if (selectedElements.length === 1 && isTextElement16(selectedElements[0])) {
28130
28010
  return t("hints.text_selected", {
28131
28011
  shortcut: getTaggedShortcutKey("Enter")
28132
28012
  });
@@ -28166,7 +28046,7 @@ var getHints = ({
28166
28046
  });
28167
28047
  }
28168
28048
  if (selectedElements.length === 1) {
28169
- if (isLinearElement10(selectedElements[0])) {
28049
+ if (isLinearElement9(selectedElements[0])) {
28170
28050
  if (appState.selectedLinearElement?.isEditing) {
28171
28051
  return appState.selectedLinearElement.selectedPointsIndices ? t("hints.lineEditor_pointSelected", {
28172
28052
  shortcut_1: getTaggedShortcutKey("Delete"),
@@ -28822,7 +28702,7 @@ var DefaultMainMenu = ({ UIOptions }) => {
28822
28702
  /* @__PURE__ */ jsx130(MainMenu_default.Separator, {}),
28823
28703
  /* @__PURE__ */ jsx130(MainMenu_default.Group, { title: "Excalidraw links", children: /* @__PURE__ */ jsx130(MainMenu_default.DefaultItems.Socials, {}) }),
28824
28704
  /* @__PURE__ */ jsx130(MainMenu_default.Separator, {}),
28825
- /* @__PURE__ */ jsx130(MainMenu_default.DefaultItems.ToggleTheme, {}),
28705
+ /* @__PURE__ */ jsx130(MainMenu_default.DefaultItems.ToggleTheme, { allowSystemTheme: false }),
28826
28706
  /* @__PURE__ */ jsx130(MainMenu_default.DefaultItems.ChangeCanvasBackground, {})
28827
28707
  ] });
28828
28708
  };
@@ -29202,7 +29082,7 @@ var LayerUI = ({
29202
29082
  }
29203
29083
  if (selectedElements.length) {
29204
29084
  for (const element of selectedElements) {
29205
- mutateElement5(element, arrayToMap28(elements), {
29085
+ mutateElement5(element, arrayToMap27(elements), {
29206
29086
  [altKey && eyeDropperState.swapPreviewOnAlt ? colorPickerType === "elementBackground" ? "strokeColor" : "backgroundColor" : colorPickerType === "elementBackground" ? "backgroundColor" : "strokeColor"]: color
29207
29087
  });
29208
29088
  ShapeCache3.delete(element);
@@ -29416,14 +29296,14 @@ import {
29416
29296
  // renderer/interactiveScene.ts
29417
29297
  import {
29418
29298
  clamp as clamp7,
29419
- pointFrom as pointFrom33,
29299
+ pointFrom as pointFrom31,
29420
29300
  pointsEqual as pointsEqual8,
29421
29301
  bezierEquation as bezierEquation2,
29422
- pointRotateRads as pointRotateRads22,
29302
+ pointRotateRads as pointRotateRads20,
29423
29303
  pointDistance as pointDistance8
29424
29304
  } from "@excalidraw/math";
29425
29305
  import {
29426
- arrayToMap as arrayToMap29,
29306
+ arrayToMap as arrayToMap28,
29427
29307
  BIND_MODE_TIMEOUT,
29428
29308
  DEFAULT_TRANSFORM_HANDLE_SPACING as DEFAULT_TRANSFORM_HANDLE_SPACING2,
29429
29309
  FRAME_STYLE as FRAME_STYLE3,
@@ -29442,15 +29322,15 @@ import {
29442
29322
  getTransformHandlesFromCoords,
29443
29323
  hasBoundingBox,
29444
29324
  hitElementItself as hitElementItself2,
29445
- isArrowElement as isArrowElement13,
29325
+ isArrowElement as isArrowElement12,
29446
29326
  isBindableElement as isBindableElement2,
29447
29327
  isElbowArrow as isElbowArrow9,
29448
29328
  isFrameLikeElement as isFrameLikeElement14,
29449
29329
  isImageElement as isImageElement8,
29450
- isLinearElement as isLinearElement11,
29330
+ isLinearElement as isLinearElement10,
29451
29331
  isLineElement as isLineElement7,
29452
29332
  maxBindingDistance_simple as maxBindingDistance_simple2,
29453
- isTextElement as isTextElement18,
29333
+ isTextElement as isTextElement17,
29454
29334
  getActiveTextElement
29455
29335
  } from "@excalidraw/element";
29456
29336
  import { LinearElementEditor as LinearElementEditor10 } from "@excalidraw/element/linearElementEditor";
@@ -29468,7 +29348,7 @@ import {
29468
29348
  } from "@excalidraw/element";
29469
29349
 
29470
29350
  // renderer/renderSnaps.ts
29471
- import { pointFrom as pointFrom32 } from "@excalidraw/math";
29351
+ import { pointFrom as pointFrom30 } from "@excalidraw/math";
29472
29352
  import { THEME as THEME15 } from "@excalidraw/common";
29473
29353
  var SNAP_COLOR_LIGHT = "#ff6b6b";
29474
29354
  var SNAP_COLOR_DARK = "#ff0000";
@@ -29546,25 +29426,25 @@ var drawGapLine = (from, to, direction, appState, context) => {
29546
29426
  const halfPoint = [(from[0] + to[0]) / 2, from[1]];
29547
29427
  if (!appState.zenModeEnabled) {
29548
29428
  drawLine(
29549
- pointFrom32(from[0], from[1] - FULL),
29550
- pointFrom32(from[0], from[1] + FULL),
29429
+ pointFrom30(from[0], from[1] - FULL),
29430
+ pointFrom30(from[0], from[1] + FULL),
29551
29431
  context
29552
29432
  );
29553
29433
  }
29554
29434
  drawLine(
29555
- pointFrom32(halfPoint[0] - QUARTER, halfPoint[1] - HALF),
29556
- pointFrom32(halfPoint[0] - QUARTER, halfPoint[1] + HALF),
29435
+ pointFrom30(halfPoint[0] - QUARTER, halfPoint[1] - HALF),
29436
+ pointFrom30(halfPoint[0] - QUARTER, halfPoint[1] + HALF),
29557
29437
  context
29558
29438
  );
29559
29439
  drawLine(
29560
- pointFrom32(halfPoint[0] + QUARTER, halfPoint[1] - HALF),
29561
- pointFrom32(halfPoint[0] + QUARTER, halfPoint[1] + HALF),
29440
+ pointFrom30(halfPoint[0] + QUARTER, halfPoint[1] - HALF),
29441
+ pointFrom30(halfPoint[0] + QUARTER, halfPoint[1] + HALF),
29562
29442
  context
29563
29443
  );
29564
29444
  if (!appState.zenModeEnabled) {
29565
29445
  drawLine(
29566
- pointFrom32(to[0], to[1] - FULL),
29567
- pointFrom32(to[0], to[1] + FULL),
29446
+ pointFrom30(to[0], to[1] - FULL),
29447
+ pointFrom30(to[0], to[1] + FULL),
29568
29448
  context
29569
29449
  );
29570
29450
  drawLine(from, to, context);
@@ -29573,25 +29453,25 @@ var drawGapLine = (from, to, direction, appState, context) => {
29573
29453
  const halfPoint = [from[0], (from[1] + to[1]) / 2];
29574
29454
  if (!appState.zenModeEnabled) {
29575
29455
  drawLine(
29576
- pointFrom32(from[0] - FULL, from[1]),
29577
- pointFrom32(from[0] + FULL, from[1]),
29456
+ pointFrom30(from[0] - FULL, from[1]),
29457
+ pointFrom30(from[0] + FULL, from[1]),
29578
29458
  context
29579
29459
  );
29580
29460
  }
29581
29461
  drawLine(
29582
- pointFrom32(halfPoint[0] - HALF, halfPoint[1] - QUARTER),
29583
- pointFrom32(halfPoint[0] + HALF, halfPoint[1] - QUARTER),
29462
+ pointFrom30(halfPoint[0] - HALF, halfPoint[1] - QUARTER),
29463
+ pointFrom30(halfPoint[0] + HALF, halfPoint[1] - QUARTER),
29584
29464
  context
29585
29465
  );
29586
29466
  drawLine(
29587
- pointFrom32(halfPoint[0] - HALF, halfPoint[1] + QUARTER),
29588
- pointFrom32(halfPoint[0] + HALF, halfPoint[1] + QUARTER),
29467
+ pointFrom30(halfPoint[0] - HALF, halfPoint[1] + QUARTER),
29468
+ pointFrom30(halfPoint[0] + HALF, halfPoint[1] + QUARTER),
29589
29469
  context
29590
29470
  );
29591
29471
  if (!appState.zenModeEnabled) {
29592
29472
  drawLine(
29593
- pointFrom32(to[0] - FULL, to[1]),
29594
- pointFrom32(to[0] + FULL, to[1]),
29473
+ pointFrom30(to[0] - FULL, to[1]),
29474
+ pointFrom30(to[0] + FULL, to[1]),
29595
29475
  context
29596
29476
  );
29597
29477
  drawLine(from, to, context);
@@ -29837,12 +29717,12 @@ var renderBindingHighlightForBindableElement_simple = (context, suggestedBinding
29837
29717
  midpoints = getDiamondBaseCorners(suggestedBinding.element).map(
29838
29718
  (curve3) => {
29839
29719
  const point = bezierEquation2(curve3, 0.5);
29840
- const rotatedPoint = pointRotateRads22(
29720
+ const rotatedPoint = pointRotateRads20(
29841
29721
  point,
29842
29722
  center2,
29843
29723
  suggestedBinding.element.angle
29844
29724
  );
29845
- return pointFrom33(rotatedPoint[0], rotatedPoint[1]);
29725
+ return pointFrom31(rotatedPoint[0], rotatedPoint[1]);
29846
29726
  }
29847
29727
  );
29848
29728
  } else {
@@ -29863,16 +29743,16 @@ var renderBindingHighlightForBindableElement_simple = (context, suggestedBinding
29863
29743
  // TOP
29864
29744
  ];
29865
29745
  midpoints = basePoints.map((point) => {
29866
- const globalPoint = pointFrom33(
29746
+ const globalPoint = pointFrom31(
29867
29747
  point.x + suggestedBinding.element.x,
29868
29748
  point.y + suggestedBinding.element.y
29869
29749
  );
29870
- const rotatedPoint = pointRotateRads22(
29750
+ const rotatedPoint = pointRotateRads20(
29871
29751
  globalPoint,
29872
29752
  center,
29873
29753
  suggestedBinding.element.angle
29874
29754
  );
29875
- return pointFrom33(rotatedPoint[0], rotatedPoint[1]);
29755
+ return pointFrom31(rotatedPoint[0], rotatedPoint[1]);
29876
29756
  });
29877
29757
  }
29878
29758
  const hoveredMidpoint = pointerCoords && midpoints.reduce(
@@ -30116,7 +29996,7 @@ var renderBindingHighlightForBindableElement_complex = (app, context, element, a
30116
29996
  const center = elementCenterPoint2(element, allElementsMap);
30117
29997
  midpoints = curves.map((curve3) => {
30118
29998
  const point = bezierEquation2(curve3, 0.5);
30119
- const rotatedPoint = pointRotateRads22(point, center, element.angle);
29999
+ const rotatedPoint = pointRotateRads20(point, center, element.angle);
30120
30000
  return {
30121
30001
  x: rotatedPoint[0] - element.x,
30122
30002
  y: rotatedPoint[1] - element.y
@@ -30135,11 +30015,11 @@ var renderBindingHighlightForBindableElement_complex = (app, context, element, a
30135
30015
  // LEFT
30136
30016
  ];
30137
30017
  midpoints = basePoints.map((point) => {
30138
- const globalPoint = pointFrom33(
30018
+ const globalPoint = pointFrom31(
30139
30019
  point.x + element.x,
30140
30020
  point.y + element.y
30141
30021
  );
30142
- const rotatedPoint = pointRotateRads22(
30022
+ const rotatedPoint = pointRotateRads20(
30143
30023
  globalPoint,
30144
30024
  center,
30145
30025
  element.angle
@@ -30188,7 +30068,7 @@ var renderBindingHighlightForBindableElement = (app, context, suggestedBinding,
30188
30068
  }
30189
30069
  context.save();
30190
30070
  context.translate(appState.scrollX, appState.scrollY);
30191
- const pointerCoords = app.lastPointerMoveCoords ? pointFrom33(
30071
+ const pointerCoords = app.lastPointerMoveCoords ? pointFrom31(
30192
30072
  app.lastPointerMoveCoords.x,
30193
30073
  app.lastPointerMoveCoords.y
30194
30074
  ) : null;
@@ -30353,7 +30233,7 @@ var renderLinearPointHandles = (context, appState, element, elementsMap) => {
30353
30233
  renderSingleLinearPoint(
30354
30234
  context,
30355
30235
  appState,
30356
- pointFrom33(
30236
+ pointFrom31(
30357
30237
  (p[0] + points[idx + 1][0]) / 2,
30358
30238
  (p[1] + points[idx + 1][1]) / 2
30359
30239
  ),
@@ -30769,7 +30649,7 @@ var _renderInteractiveScene = ({
30769
30649
  renderLinearElementPointHighlight(context, appState, elementsMap);
30770
30650
  }
30771
30651
  }
30772
- if (isArrowElement13(selectedLinearElement)) {
30652
+ if (isArrowElement12(selectedLinearElement)) {
30773
30653
  renderFocusPointIndicator({
30774
30654
  arrow: selectedLinearElement,
30775
30655
  elementsMap: allElementsMap,
@@ -30792,7 +30672,7 @@ var _renderInteractiveScene = ({
30792
30672
  appState,
30793
30673
  editorInterface
30794
30674
  );
30795
- const isSingleLinearElementSelected = selectedElements.length === 1 && isLinearElement11(selectedElements[0]);
30675
+ const isSingleLinearElementSelected = selectedElements.length === 1 && isLinearElement10(selectedElements[0]);
30796
30676
  if (isSingleLinearElementSelected && appState.selectedLinearElement?.elementId === selectedElements[0].id && !selectedElements[0].locked) {
30797
30677
  renderLinearPointHandles(
30798
30678
  context,
@@ -30803,7 +30683,7 @@ var _renderInteractiveScene = ({
30803
30683
  }
30804
30684
  const selectionColor = renderConfig.selectionColor || "#000";
30805
30685
  if (showBoundingBox) {
30806
- const locallySelectedIds = arrayToMap29(selectedElements);
30686
+ const locallySelectedIds = arrayToMap28(selectedElements);
30807
30687
  const selections = [];
30808
30688
  for (const element of elementsMap.values()) {
30809
30689
  const selectionColors = [];
@@ -30887,7 +30767,7 @@ var _renderInteractiveScene = ({
30887
30767
  getOmitSidesForEditorInterface(editorInterface)
30888
30768
  );
30889
30769
  if (!appState.viewModeEnabled && showBoundingBox && // do not show transform handles when text is being edited
30890
- !isTextElement18(appState.editingTextElement) && // do not show transform handles when image is being cropped
30770
+ !isTextElement17(appState.editingTextElement) && // do not show transform handles when image is being cropped
30891
30771
  !appState.croppingElementId) {
30892
30772
  renderTransformHandles(
30893
30773
  context,
@@ -31930,7 +31810,10 @@ var App = class _App extends React40.Component {
31930
31810
  }
31931
31811
  },
31932
31812
  style: {
31933
- background: isDarkTheme ? applyDarkModeFilter4(this.state.viewBackgroundColor) : this.state.viewBackgroundColor,
31813
+ background: applyDarkModeFilter4(
31814
+ this.state.viewBackgroundColor,
31815
+ isDarkTheme
31816
+ ),
31934
31817
  zIndex: 2,
31935
31818
  border: "none",
31936
31819
  display: "block",
@@ -32164,6 +32047,7 @@ var App = class _App extends React40.Component {
32164
32047
  this.addNewImagesToImageCache();
32165
32048
  }
32166
32049
  if (actionResult.appState || editingTextElement || this.state.contextMenu) {
32050
+ const viewModeOnly = this.props.viewModeOnly ?? actionResult?.appState?.viewModeOnly ?? this.state.viewModeOnly;
32167
32051
  let viewModeEnabled = actionResult?.appState?.viewModeEnabled || false;
32168
32052
  let zenModeEnabled = actionResult?.appState?.zenModeEnabled || false;
32169
32053
  const theme = actionResult?.appState?.theme || this.props.theme || THEME17.LIGHT;
@@ -32172,13 +32056,16 @@ var App = class _App extends React40.Component {
32172
32056
  if (typeof this.props.viewModeEnabled !== "undefined") {
32173
32057
  viewModeEnabled = this.props.viewModeEnabled;
32174
32058
  }
32059
+ if (this.props.viewModeOnly ?? viewModeOnly) {
32060
+ viewModeEnabled = true;
32061
+ }
32175
32062
  if (typeof this.props.zenModeEnabled !== "undefined") {
32176
32063
  zenModeEnabled = this.props.zenModeEnabled;
32177
32064
  }
32178
32065
  editingTextElement = actionResult.appState?.editingTextElement || null;
32179
32066
  if (actionResult.elements && editingTextElement) {
32180
32067
  actionResult.elements.forEach((element) => {
32181
- if (editingTextElement?.id === element.id && editingTextElement !== element && isNonDeletedElement(element) && isTextElement19(element)) {
32068
+ if (editingTextElement?.id === element.id && editingTextElement !== element && isNonDeletedElement(element) && isTextElement18(element)) {
32182
32069
  editingTextElement = element;
32183
32070
  }
32184
32071
  });
@@ -32197,6 +32084,7 @@ var App = class _App extends React40.Component {
32197
32084
  contextMenu: null,
32198
32085
  editingTextElement,
32199
32086
  viewModeEnabled,
32087
+ viewModeOnly,
32200
32088
  zenModeEnabled,
32201
32089
  theme,
32202
32090
  name,
@@ -32471,8 +32359,8 @@ var App = class _App extends React40.Component {
32471
32359
  if (didTapTwice && event.touches.length === 1 && firstTapPosition) {
32472
32360
  const touch = event.touches[0];
32473
32361
  const distance3 = pointDistance9(
32474
- pointFrom34(touch.clientX, touch.clientY),
32475
- pointFrom34(firstTapPosition.x, firstTapPosition.y)
32362
+ pointFrom32(touch.clientX, touch.clientY),
32363
+ pointFrom32(firstTapPosition.x, firstTapPosition.y)
32476
32364
  );
32477
32365
  if (distance3 <= DOUBLE_TAP_POSITION_THRESHOLD) {
32478
32366
  this.lassoTrail.endPath();
@@ -32580,7 +32468,7 @@ var App = class _App extends React40.Component {
32580
32468
  prevElements
32581
32469
  );
32582
32470
  nextElements = mappedNewSceneElements || nextElements;
32583
- syncMovedIndices5(nextElements, arrayToMap30(duplicatedElements));
32471
+ syncMovedIndices5(nextElements, arrayToMap29(duplicatedElements));
32584
32472
  const topLayerFrame = this.getTopLayerFrameAtSceneCoords({ x, y });
32585
32473
  if (topLayerFrame) {
32586
32474
  const eligibleElements = filterElementsEligibleAsFrameChildren(
@@ -32595,7 +32483,7 @@ var App = class _App extends React40.Component {
32595
32483
  }
32596
32484
  this.scene.replaceAllElements(nextElements);
32597
32485
  duplicatedElements.forEach((newElement7) => {
32598
- if (isTextElement19(newElement7) && isBoundToContainer9(newElement7)) {
32486
+ if (isTextElement18(newElement7) && isBoundToContainer9(newElement7)) {
32599
32487
  const container = getContainerElement5(
32600
32488
  newElement7,
32601
32489
  this.scene.getElementsMapIncludingDeleted()
@@ -32650,7 +32538,33 @@ var App = class _App extends React40.Component {
32650
32538
  }
32651
32539
  });
32652
32540
  __publicField(this, "setAppState", (state, callback) => {
32653
- this.setState(state, callback);
32541
+ const normalizeViewModeOnlyState = (nextState, prevState) => {
32542
+ if (!nextState) {
32543
+ return nextState;
32544
+ }
32545
+ const nextAppState = nextState;
32546
+ const viewModeOnly = this.props.viewModeOnly ?? nextAppState.viewModeOnly ?? prevState.viewModeOnly;
32547
+ if (viewModeOnly) {
32548
+ return {
32549
+ ...nextState,
32550
+ viewModeEnabled: true
32551
+ };
32552
+ }
32553
+ return nextState;
32554
+ };
32555
+ if (typeof state === "function") {
32556
+ this.setState((prevState, props) => {
32557
+ return normalizeViewModeOnlyState(
32558
+ state(prevState, props),
32559
+ prevState
32560
+ );
32561
+ }, callback);
32562
+ return;
32563
+ }
32564
+ this.setState(
32565
+ normalizeViewModeOnlyState(state, this.state),
32566
+ callback
32567
+ );
32654
32568
  });
32655
32569
  __publicField(this, "removePointer", (event) => {
32656
32570
  if (touchTimeout) {
@@ -32925,7 +32839,7 @@ var App = class _App extends React40.Component {
32925
32839
  });
32926
32840
  }
32927
32841
  if (appState) {
32928
- this.setState(appState);
32842
+ this.setAppState(appState);
32929
32843
  }
32930
32844
  if (elements) {
32931
32845
  this.scene.replaceAllElements(elements);
@@ -33219,7 +33133,7 @@ var App = class _App extends React40.Component {
33219
33133
  event.preventDefault();
33220
33134
  return;
33221
33135
  }
33222
- const shouldPreventToolSwitching = this.props.viewModeEnabled === true;
33136
+ const shouldPreventToolSwitching = this.props.viewModeEnabled === true || this.props.viewModeOnly === true || this.state.viewModeOnly;
33223
33137
  if (!shouldPreventToolSwitching && this.state.viewModeEnabled && event.key === KEYS50.ESCAPE) {
33224
33138
  this.setActiveTool({ type: "selection" });
33225
33139
  return;
@@ -33324,7 +33238,7 @@ var App = class _App extends React40.Component {
33324
33238
  if (selectedElements.length === 1) {
33325
33239
  const selectedElement = selectedElements[0];
33326
33240
  if (event[KEYS50.CTRL_OR_CMD] || isLineElement8(selectedElement)) {
33327
- if (isLinearElement12(selectedElement)) {
33241
+ if (isLinearElement11(selectedElement)) {
33328
33242
  if (!this.state.selectedLinearElement?.isEditing || this.state.selectedLinearElement.elementId !== selectedElement.id) {
33329
33243
  this.store.scheduleCapture();
33330
33244
  if (!isElbowArrow10(selectedElement)) {
@@ -33332,9 +33246,9 @@ var App = class _App extends React40.Component {
33332
33246
  }
33333
33247
  }
33334
33248
  }
33335
- } else if (isTextElement19(selectedElement) || isValidTextContainer(selectedElement)) {
33249
+ } else if (isTextElement18(selectedElement) || isValidTextContainer(selectedElement)) {
33336
33250
  let container;
33337
- if (!isTextElement19(selectedElement)) {
33251
+ if (!isTextElement18(selectedElement)) {
33338
33252
  container = selectedElement;
33339
33253
  }
33340
33254
  const midPoint = getContainerCenter(
@@ -33383,7 +33297,7 @@ var App = class _App extends React40.Component {
33383
33297
  return;
33384
33298
  }
33385
33299
  if (this.state.activeTool.type === "text" || selectedElements.find(
33386
- (element) => isTextElement19(element) || getBoundTextElement15(
33300
+ (element) => isTextElement18(element) || getBoundTextElement15(
33387
33301
  element,
33388
33302
  this.scene.getNonDeletedElementsMap()
33389
33303
  )
@@ -33439,7 +33353,7 @@ var App = class _App extends React40.Component {
33439
33353
  this.state
33440
33354
  );
33441
33355
  const hoveredElement = getHoveredElementForBinding2(
33442
- pointFrom34(scenePointer.x, scenePointer.y),
33356
+ pointFrom32(scenePointer.x, scenePointer.y),
33443
33357
  this.scene.getNonDeletedElements(),
33444
33358
  this.scene.getNonDeletedElementsMap()
33445
33359
  );
@@ -33465,7 +33379,7 @@ var App = class _App extends React40.Component {
33465
33379
  }
33466
33380
  if (isArrowKey2(event.key)) {
33467
33381
  bindOrUnbindBindingElements2(
33468
- this.scene.getSelectedElements(this.state).filter(isArrowElement14),
33382
+ this.scene.getSelectedElements(this.state).filter(isArrowElement13),
33469
33383
  this.scene,
33470
33384
  this.state
33471
33385
  );
@@ -33753,7 +33667,7 @@ var App = class _App extends React40.Component {
33753
33667
  const fontFamily = existingTextElement?.fontFamily || this.state.currentItemFontFamily;
33754
33668
  const lineHeight = existingTextElement?.lineHeight || getLineHeight6(fontFamily);
33755
33669
  const fontSize = this.state.currentItemFontSize;
33756
- if (!existingTextElement && shouldBindToContainer && container && !isArrowElement14(container)) {
33670
+ if (!existingTextElement && shouldBindToContainer && container && !isArrowElement13(container)) {
33757
33671
  const fontString = {
33758
33672
  fontSize,
33759
33673
  fontFamily
@@ -33817,7 +33731,7 @@ var App = class _App extends React40.Component {
33817
33731
  containerId: shouldBindToContainer ? container?.id : void 0,
33818
33732
  groupIds: container?.groupIds ?? [],
33819
33733
  lineHeight,
33820
- angle: container ? isArrowElement14(container) ? 0 : container.angle : 0,
33734
+ angle: container ? isArrowElement13(container) ? 0 : container.angle : 0,
33821
33735
  frameId
33822
33736
  });
33823
33737
  if (!existingTextElement && shouldBindToContainer && container) {
@@ -33875,8 +33789,8 @@ var App = class _App extends React40.Component {
33875
33789
  }
33876
33790
  const [firstClick, secondClick] = this.lastCompletedCanvasClicks;
33877
33791
  return pointDistance9(
33878
- pointFrom34(firstClick.x, firstClick.y),
33879
- pointFrom34(secondClick.x, secondClick.y)
33792
+ pointFrom32(firstClick.x, firstClick.y),
33793
+ pointFrom32(secondClick.x, secondClick.y)
33880
33794
  ) <= DOUBLE_TAP_POSITION_THRESHOLD;
33881
33795
  });
33882
33796
  __publicField(this, "handleCanvasDoubleClick", (event) => {
@@ -33894,7 +33808,7 @@ var App = class _App extends React40.Component {
33894
33808
  event,
33895
33809
  this.state
33896
33810
  );
33897
- if (selectedElements.length === 1 && isLinearElement12(selectedElements[0])) {
33811
+ if (selectedElements.length === 1 && isLinearElement11(selectedElements[0])) {
33898
33812
  const selectedLinearElement = selectedElements[0];
33899
33813
  if ((event[KEYS50.CTRL_OR_CMD] && isSimpleArrow(selectedLinearElement) || isLineElement8(selectedLinearElement)) && (!this.state.selectedLinearElement?.isEditing || this.state.selectedLinearElement.elementId !== selectedLinearElement.id)) {
33900
33814
  this.actionManager.executeAction(actionToggleLinearEditor);
@@ -33996,7 +33910,7 @@ var App = class _App extends React40.Component {
33996
33910
  );
33997
33911
  if (container) {
33998
33912
  if (hasBoundTextElement9(container) || !isTransparent6(container.backgroundColor) || hitElementItself3({
33999
- point: pointFrom34(sceneX, sceneY),
33913
+ point: pointFrom32(sceneX, sceneY),
34000
33914
  element: container,
34001
33915
  elementsMap: this.scene.getNonDeletedElementsMap(),
34002
33916
  threshold: this.getElementHitThreshold(container)
@@ -34047,7 +33961,7 @@ var App = class _App extends React40.Component {
34047
33961
  element,
34048
33962
  this.scene.getNonDeletedElementsMap(),
34049
33963
  this.state,
34050
- pointFrom34(scenePointer.x, scenePointer.y),
33964
+ pointFrom32(scenePointer.x, scenePointer.y),
34051
33965
  this.editorInterface.formFactor === "phone"
34052
33966
  )) {
34053
33967
  return element;
@@ -34055,12 +33969,15 @@ var App = class _App extends React40.Component {
34055
33969
  }
34056
33970
  });
34057
33971
  __publicField(this, "handleElementLinkClick", (event) => {
33972
+ if (event.button !== POINTER_BUTTON2.MAIN) {
33973
+ return;
33974
+ }
34058
33975
  const draggedDistance = pointDistance9(
34059
- pointFrom34(
33976
+ pointFrom32(
34060
33977
  this.lastPointerDownEvent.clientX,
34061
33978
  this.lastPointerDownEvent.clientY
34062
33979
  ),
34063
- pointFrom34(
33980
+ pointFrom32(
34064
33981
  this.lastPointerUpEvent.clientX,
34065
33982
  this.lastPointerUpEvent.clientY
34066
33983
  )
@@ -34077,7 +33994,7 @@ var App = class _App extends React40.Component {
34077
33994
  this.hitLinkElement,
34078
33995
  elementsMap,
34079
33996
  this.state,
34080
- pointFrom34(lastPointerDownCoords.x, lastPointerDownCoords.y),
33997
+ pointFrom32(lastPointerDownCoords.x, lastPointerDownCoords.y),
34081
33998
  this.editorInterface.formFactor === "phone"
34082
33999
  );
34083
34000
  const lastPointerUpCoords = viewportCoordsToSceneCoords3(
@@ -34088,33 +34005,37 @@ var App = class _App extends React40.Component {
34088
34005
  this.hitLinkElement,
34089
34006
  elementsMap,
34090
34007
  this.state,
34091
- pointFrom34(lastPointerUpCoords.x, lastPointerUpCoords.y),
34008
+ pointFrom32(lastPointerUpCoords.x, lastPointerUpCoords.y),
34092
34009
  this.editorInterface.formFactor === "phone"
34093
34010
  );
34094
34011
  if (lastPointerDownHittingLinkIcon && lastPointerUpHittingLinkIcon) {
34095
34012
  hideHyperlinkToolip();
34096
- let url = this.hitLinkElement.link;
34097
- if (url) {
34098
- url = normalizeLink3(url);
34099
- let customEvent;
34100
- if (this.props.onLinkOpen) {
34101
- customEvent = wrapEvent2(EVENT10.EXCALIDRAW_LINK, event.nativeEvent);
34102
- this.props.onLinkOpen(
34103
- {
34104
- ...this.hitLinkElement,
34105
- link: url
34106
- },
34107
- customEvent
34108
- );
34109
- }
34110
- if (!customEvent?.defaultPrevented) {
34111
- const target = isLocalLink2(url) ? "_self" : "_blank";
34112
- const newWindow = window.open(void 0, target);
34113
- if (newWindow) {
34114
- newWindow.opener = null;
34115
- newWindow.location = url;
34116
- }
34117
- }
34013
+ this.openElementLink(this.hitLinkElement, event.nativeEvent);
34014
+ }
34015
+ });
34016
+ __publicField(this, "openElementLink", (element, nativeEvent = new MouseEvent("click")) => {
34017
+ let url = element.link;
34018
+ if (!url) {
34019
+ return;
34020
+ }
34021
+ url = normalizeLink3(url);
34022
+ let customEvent;
34023
+ if (this.props.onLinkOpen) {
34024
+ customEvent = wrapEvent2(EVENT10.EXCALIDRAW_LINK, nativeEvent);
34025
+ this.props.onLinkOpen(
34026
+ {
34027
+ ...element,
34028
+ link: url
34029
+ },
34030
+ customEvent
34031
+ );
34032
+ }
34033
+ if (!customEvent?.defaultPrevented) {
34034
+ const target = isLocalLink2(url) ? "_self" : "_blank";
34035
+ const newWindow = window.open(void 0, target);
34036
+ if (newWindow) {
34037
+ newWindow.opener = null;
34038
+ newWindow.location = url;
34118
34039
  }
34119
34040
  }
34120
34041
  });
@@ -34320,7 +34241,7 @@ var App = class _App extends React40.Component {
34320
34241
  if (isBindingElementType(this.state.activeTool.type)) {
34321
34242
  const { newElement: newElement7 } = this.state;
34322
34243
  if (!newElement7 && isBindingEnabled2(this.state)) {
34323
- const globalPoint = pointFrom34(
34244
+ const globalPoint = pointFrom32(
34324
34245
  scenePointerX,
34325
34246
  scenePointerY
34326
34247
  );
@@ -34357,8 +34278,8 @@ var App = class _App extends React40.Component {
34357
34278
  const { lastCommittedPoint } = selectedLinearElement;
34358
34279
  setCursorForShape(this.interactiveCanvas, this.state);
34359
34280
  if (lastPoint === lastCommittedPoint) {
34360
- const hoveredElement = isArrowElement14(this.state.newElement) && isBindingEnabled2(this.state) && getHoveredElementForBinding2(
34361
- pointFrom34(scenePointerX, scenePointerY),
34281
+ const hoveredElement = isArrowElement13(this.state.newElement) && isBindingEnabled2(this.state) && getHoveredElementForBinding2(
34282
+ pointFrom32(scenePointerX, scenePointerY),
34362
34283
  this.scene.getNonDeletedElements(),
34363
34284
  this.scene.getNonDeletedElementsMap(),
34364
34285
  maxBindingDistance_simple3(this.state.zoom)
@@ -34396,7 +34317,7 @@ var App = class _App extends React40.Component {
34396
34317
  // if we haven't yet created a temp point and we're beyond commit-zone
34397
34318
  // threshold, add a point
34398
34319
  pointDistance9(
34399
- pointFrom34(scenePointerX - rx, scenePointerY - ry),
34320
+ pointFrom32(scenePointerX - rx, scenePointerY - ry),
34400
34321
  lastPoint
34401
34322
  ) >= LINE_CONFIRM_THRESHOLD2
34402
34323
  ) {
@@ -34405,7 +34326,7 @@ var App = class _App extends React40.Component {
34405
34326
  {
34406
34327
  points: [
34407
34328
  ...points,
34408
- pointFrom34(scenePointerX - rx, scenePointerY - ry)
34329
+ pointFrom32(scenePointerX - rx, scenePointerY - ry)
34409
34330
  ]
34410
34331
  },
34411
34332
  { informMutation: false, isDragging: false }
@@ -34429,7 +34350,7 @@ var App = class _App extends React40.Component {
34429
34350
  setCursor(this.interactiveCanvas, CURSOR_TYPE4.POINTER);
34430
34351
  }
34431
34352
  } else if (points.length > 2 && lastCommittedPoint && pointDistance9(
34432
- pointFrom34(scenePointerX - rx, scenePointerY - ry),
34353
+ pointFrom32(scenePointerX - rx, scenePointerY - ry),
34433
34354
  lastCommittedPoint
34434
34355
  ) < LINE_CONFIRM_THRESHOLD2) {
34435
34356
  setCursor(this.interactiveCanvas, CURSOR_TYPE4.POINTER);
@@ -34465,7 +34386,7 @@ var App = class _App extends React40.Component {
34465
34386
  const elementsMap = this.scene.getNonDeletedElementsMap();
34466
34387
  if (isSimpleArrow(multiElement)) {
34467
34388
  const hoveredElement = getHoveredElementForBinding2(
34468
- pointFrom34(scenePointerX, scenePointerY),
34389
+ pointFrom32(scenePointerX, scenePointerY),
34469
34390
  this.scene.getNonDeletedElements(),
34470
34391
  elementsMap
34471
34392
  );
@@ -34492,12 +34413,12 @@ var App = class _App extends React40.Component {
34492
34413
  }
34493
34414
  if (this.state.activeTool.type === "arrow") {
34494
34415
  const hit = getHoveredElementForBinding2(
34495
- pointFrom34(scenePointerX, scenePointerY),
34416
+ pointFrom32(scenePointerX, scenePointerY),
34496
34417
  this.scene.getNonDeletedElements(),
34497
34418
  this.scene.getNonDeletedElementsMap(),
34498
34419
  maxBindingDistance_simple3(this.state.zoom)
34499
34420
  );
34500
- const scenePointer2 = pointFrom34(scenePointerX, scenePointerY);
34421
+ const scenePointer2 = pointFrom32(scenePointerX, scenePointerY);
34501
34422
  const elementsMap = this.scene.getNonDeletedElementsMap();
34502
34423
  if (hit && !isPointInElement3(scenePointer2, hit, elementsMap)) {
34503
34424
  this.setState({
@@ -34536,7 +34457,7 @@ var App = class _App extends React40.Component {
34536
34457
  }
34537
34458
  if ((!this.state.selectedLinearElement || this.state.selectedLinearElement.hoverPointIndex === -1) && this.state.openDialog?.name !== "elementLinkSelector" && !(selectedElements.length === 1 && isElbowArrow10(selectedElements[0])) && // HACK: Disable transform handles for linear elements on mobile until a
34538
34459
  // better way of showing them is found
34539
- !(isLinearElement12(selectedElements[0]) && (this.editorInterface.userAgent.isMobileDevice || selectedElements[0].points.length === 2))) {
34460
+ !(isLinearElement11(selectedElements[0]) && (this.editorInterface.userAgent.isMobileDevice || selectedElements[0].points.length === 2))) {
34540
34461
  const elementWithTransformHandleType = getElementWithTransformHandleType(
34541
34462
  elements,
34542
34463
  this.state,
@@ -34618,7 +34539,7 @@ var App = class _App extends React40.Component {
34618
34539
  } else if (this.state.activeTool.type === "text") {
34619
34540
  setCursor(
34620
34541
  this.interactiveCanvas,
34621
- isTextElement19(hitElement) ? CURSOR_TYPE4.TEXT : CURSOR_TYPE4.CROSSHAIR
34542
+ isTextElement18(hitElement) ? CURSOR_TYPE4.TEXT : CURSOR_TYPE4.CROSSHAIR
34622
34543
  );
34623
34544
  } else if (!event[KEYS50.CTRL_OR_CMD] && this.isHittingCommonBoundingBoxOfSelectedElements(
34624
34545
  scenePointer,
@@ -35218,7 +35139,7 @@ var App = class _App extends React40.Component {
35218
35139
  const elements = this.scene.getNonDeletedElements();
35219
35140
  const elementsMap = this.scene.getNonDeletedElementsMap();
35220
35141
  const selectedElements = this.scene.getSelectedElements(this.state);
35221
- if (selectedElements.length === 1 && !this.state.selectedLinearElement?.isEditing && !isElbowArrow10(selectedElements[0]) && !(isLinearElement12(selectedElements[0]) && (this.editorInterface.userAgent.isMobileDevice || selectedElements[0].points.length === 2)) && !(this.state.selectedLinearElement && this.state.selectedLinearElement.hoverPointIndex !== -1)) {
35142
+ if (selectedElements.length === 1 && !this.state.selectedLinearElement?.isEditing && !isElbowArrow10(selectedElements[0]) && !(isLinearElement11(selectedElements[0]) && (this.editorInterface.userAgent.isMobileDevice || selectedElements[0].points.length === 2)) && !(this.state.selectedLinearElement && this.state.selectedLinearElement.hoverPointIndex !== -1)) {
35222
35143
  const elementWithTransformHandleType = getElementWithTransformHandleType(
35223
35144
  elements,
35224
35145
  this.state,
@@ -35265,7 +35186,7 @@ var App = class _App extends React40.Component {
35265
35186
  pointerDownState.origin.y
35266
35187
  )
35267
35188
  );
35268
- if (selectedElements.length === 1 && isLinearElement12(selectedElements[0]) && selectedElements[0].points.length === 2) {
35189
+ if (selectedElements.length === 1 && isLinearElement11(selectedElements[0]) && selectedElements[0].points.length === 2) {
35269
35190
  pointerDownState.resize.arrowDirection = getResizeArrowDirection(
35270
35191
  pointerDownState.resize.handleType,
35271
35192
  selectedElements[0]
@@ -35560,7 +35481,7 @@ var App = class _App extends React40.Component {
35560
35481
  simulatePressure,
35561
35482
  locked: false,
35562
35483
  frameId: topLayerFrame ? topLayerFrame.id : null,
35563
- points: [pointFrom34(0, 0)],
35484
+ points: [pointFrom32(0, 0)],
35564
35485
  pressures: simulatePressure ? [] : [event.pressure]
35565
35486
  });
35566
35487
  this.insertNewElement(element);
@@ -35731,7 +35652,7 @@ var App = class _App extends React40.Component {
35731
35652
  const { x: rx, y: ry } = multiElement;
35732
35653
  const { lastCommittedPoint } = selectedLinearElement;
35733
35654
  const hoveredElementForBinding = isBindingEnabled2(this.state) && getHoveredElementForBinding2(
35734
- pointFrom34(
35655
+ pointFrom32(
35735
35656
  this.lastPointerMoveCoords?.x ?? rx + multiElement.points[multiElement.points.length - 1][0],
35736
35657
  this.lastPointerMoveCoords?.y ?? ry + multiElement.points[multiElement.points.length - 1][1]
35737
35658
  ),
@@ -35739,7 +35660,7 @@ var App = class _App extends React40.Component {
35739
35660
  this.scene.getNonDeletedElementsMap()
35740
35661
  );
35741
35662
  if (isBindingElement4(multiElement) && hoveredElementForBinding || multiElement.points.length > 1 && lastCommittedPoint && pointDistance9(
35742
- pointFrom34(
35663
+ pointFrom32(
35743
35664
  pointerDownState.origin.x - rx,
35744
35665
  pointerDownState.origin.y - ry
35745
35666
  ),
@@ -35813,7 +35734,7 @@ var App = class _App extends React40.Component {
35813
35734
  locked: false,
35814
35735
  frameId: topLayerFrame ? topLayerFrame.id : null
35815
35736
  });
35816
- const point = pointFrom34(
35737
+ const point = pointFrom32(
35817
35738
  pointerDownState.origin.x,
35818
35739
  pointerDownState.origin.y
35819
35740
  );
@@ -35824,7 +35745,7 @@ var App = class _App extends React40.Component {
35824
35745
  elementsMap
35825
35746
  ) : null;
35826
35747
  this.scene.mutateElement(element, {
35827
- points: [pointFrom34(0, 0), pointFrom34(0, 0)]
35748
+ points: [pointFrom32(0, 0), pointFrom32(0, 0)]
35828
35749
  });
35829
35750
  this.insertNewElement(element);
35830
35751
  if (isBindingElement4(element)) {
@@ -35834,7 +35755,7 @@ var App = class _App extends React40.Component {
35834
35755
  [
35835
35756
  0,
35836
35757
  {
35837
- point: pointFrom34(0, 0),
35758
+ point: pointFrom32(0, 0),
35838
35759
  isDragging: false
35839
35760
  }
35840
35761
  ]
@@ -35855,7 +35776,7 @@ var App = class _App extends React40.Component {
35855
35776
  this.setState((prevState) => {
35856
35777
  let linearElementEditor = null;
35857
35778
  let nextSelectedElementIds = prevState.selectedElementIds;
35858
- if (isLinearElement12(element)) {
35779
+ if (isLinearElement11(element)) {
35859
35780
  linearElementEditor = new LinearElementEditor11(
35860
35781
  element,
35861
35782
  this.scene.getNonDeletedElementsMap()
@@ -35868,7 +35789,7 @@ var App = class _App extends React40.Component {
35868
35789
  ...linearElementEditor.initialState,
35869
35790
  arrowStartIsInside: event.altKey,
35870
35791
  lastClickedPoint: endIdx,
35871
- origin: pointFrom34(
35792
+ origin: pointFrom32(
35872
35793
  pointerDownState.origin.x,
35873
35794
  pointerDownState.origin.y
35874
35795
  )
@@ -36311,14 +36232,14 @@ var App = class _App extends React40.Component {
36311
36232
  }
36312
36233
  })
36313
36234
  );
36314
- const initializedMap = arrayToMap30(initialized);
36235
+ const initializedMap = arrayToMap29(initialized);
36315
36236
  const positioned = positionElementsOnGrid(
36316
36237
  initialized.filter((el) => !el.isDeleted),
36317
36238
  sceneX,
36318
36239
  sceneY,
36319
36240
  gridPadding
36320
36241
  );
36321
- const positionedMap = arrayToMap30(positioned);
36242
+ const positionedMap = arrayToMap29(positioned);
36322
36243
  const nextElements = this.scene.getElementsIncludingDeleted().map((el) => positionedMap.get(el.id) ?? initializedMap.get(el.id) ?? el);
36323
36244
  this.updateScene({
36324
36245
  appState: {
@@ -36544,7 +36465,7 @@ var App = class _App extends React40.Component {
36544
36465
  this.state,
36545
36466
  this
36546
36467
  ),
36547
- selectedLinearElement: isLinearElement12(element) ? new LinearElementEditor11(
36468
+ selectedLinearElement: isLinearElement11(element) ? new LinearElementEditor11(
36548
36469
  element,
36549
36470
  this.scene.getNonDeletedElementsMap()
36550
36471
  ) : null
@@ -36553,7 +36474,11 @@ var App = class _App extends React40.Component {
36553
36474
  },
36554
36475
  () => {
36555
36476
  this.setState({
36556
- contextMenu: { top, left, items: this.getContextMenuItems(type) }
36477
+ contextMenu: {
36478
+ top,
36479
+ left,
36480
+ items: this.getContextMenuItems(type, element)
36481
+ }
36557
36482
  });
36558
36483
  }
36559
36484
  );
@@ -36798,13 +36723,17 @@ var App = class _App extends React40.Component {
36798
36723
  }
36799
36724
  return false;
36800
36725
  });
36801
- __publicField(this, "getContextMenuItems", (type) => {
36726
+ __publicField(this, "getContextMenuItems", (type, contextMenuElement) => {
36802
36727
  const options = [];
36803
- const imageContextMenuItems = this.getImageContextMenuItems();
36728
+ const imageContextMenuItems = this.getImageContextMenuItems(contextMenuElement);
36804
36729
  const imageContextMenuSection = imageContextMenuItems.length > 0 ? [CONTEXT_MENU_SEPARATOR, ...imageContextMenuItems] : [];
36805
36730
  if (type === "canvas") {
36806
36731
  if (this.state.viewModeEnabled) {
36807
- return [actionToggleGridMode, actionToggleViewMode, actionToggleStats];
36732
+ return [
36733
+ actionToggleGridMode,
36734
+ !this.state.viewModeOnly && actionToggleViewMode,
36735
+ actionToggleStats
36736
+ ];
36808
36737
  }
36809
36738
  return [
36810
36739
  actionPaste,
@@ -36818,13 +36747,22 @@ var App = class _App extends React40.Component {
36818
36747
  actionToggleObjectsSnapMode,
36819
36748
  actionToggleArrowBinding,
36820
36749
  actionToggleMidpointSnapping,
36821
- actionToggleViewMode,
36750
+ !this.state.viewModeOnly && actionToggleViewMode,
36822
36751
  actionToggleStats
36823
36752
  ];
36824
36753
  }
36825
36754
  options.push(copyText);
36826
36755
  if (this.state.viewModeEnabled) {
36827
36756
  const viewModeItems = [actionCopy];
36757
+ const selectedElements = this.scene.getSelectedElements(this.state);
36758
+ const linkedElement = contextMenuElement?.link && !contextMenuElement.locked ? contextMenuElement : selectedElements.length === 1 && selectedElements[0].link ? selectedElements[0] : null;
36759
+ if (linkedElement) {
36760
+ viewModeItems.push({
36761
+ key: "openLink",
36762
+ label: "Open link",
36763
+ onSelect: () => this.openElementLink(linkedElement)
36764
+ });
36765
+ }
36828
36766
  viewModeItems.push(...imageContextMenuSection, ...options);
36829
36767
  return viewModeItems;
36830
36768
  }
@@ -36881,19 +36819,22 @@ var App = class _App extends React40.Component {
36881
36819
  );
36882
36820
  return elementItems;
36883
36821
  });
36884
- __publicField(this, "getImageContextMenuItems", () => {
36822
+ __publicField(this, "getImageContextMenuItems", (contextMenuElement) => {
36885
36823
  if (!this.props.imageContextMenuItems) {
36886
36824
  return [];
36887
36825
  }
36888
36826
  const selectedElements = this.scene.getSelectedElements(this.state);
36889
- if (selectedElements.length === 0 || !selectedElements.every((element) => isImageElement9(element))) {
36827
+ const selectedElementsAreImages = selectedElements.length > 0 && selectedElements.every((element) => isImageElement9(element));
36828
+ const selectionContainsGroupedElement = selectedElements.some(
36829
+ (element) => element.groupIds.length > 0
36830
+ );
36831
+ const imageIds = contextMenuElement && isImageElement9(contextMenuElement) ? !selectedElementsAreImages || selectionContainsGroupedElement || !selectedElements.some(
36832
+ (element) => element.id === contextMenuElement.id
36833
+ ) ? [contextMenuElement.id] : selectedElements.map((element) => element.id) : selectedElementsAreImages ? selectedElements.map((element) => element.id) : [];
36834
+ if (imageIds.length === 0) {
36890
36835
  return [];
36891
36836
  }
36892
- return [
36893
- ...this.props.imageContextMenuItems(
36894
- selectedElements.map((element) => element.id)
36895
- )
36896
- ];
36837
+ return [...this.props.imageContextMenuItems(imageIds)];
36897
36838
  });
36898
36839
  __publicField(this, "handleWheel", withBatchedUpdates(
36899
36840
  (event) => {
@@ -37014,6 +36955,7 @@ var App = class _App extends React40.Component {
37014
36955
  const defaultAppState = getDefaultAppState();
37015
36956
  const {
37016
36957
  viewModeEnabled = false,
36958
+ viewModeOnly = false,
37017
36959
  zenModeEnabled = false,
37018
36960
  gridModeEnabled = false,
37019
36961
  objectsSnapModeEnabled = false,
@@ -37027,7 +36969,8 @@ var App = class _App extends React40.Component {
37027
36969
  exportWithDarkMode: theme === THEME17.DARK,
37028
36970
  isLoading: true,
37029
36971
  ...this.getCanvasOffsets(),
37030
- viewModeEnabled,
36972
+ viewModeEnabled: viewModeOnly || viewModeEnabled,
36973
+ viewModeOnly,
37031
36974
  zenModeEnabled,
37032
36975
  objectsSnapModeEnabled,
37033
36976
  gridModeEnabled: gridModeEnabled ?? defaultAppState.gridModeEnabled,
@@ -37164,7 +37107,7 @@ var App = class _App extends React40.Component {
37164
37107
  );
37165
37108
  const elementsMap = this.scene.getNonDeletedElementsMap();
37166
37109
  const hoveredElement = getHoveredElementForBinding2(
37167
- pointFrom34(
37110
+ pointFrom32(
37168
37111
  this.lastPointerMoveCoords.x,
37169
37112
  this.lastPointerMoveCoords.y
37170
37113
  ),
@@ -37259,7 +37202,7 @@ var App = class _App extends React40.Component {
37259
37202
  }
37260
37203
  const { x, y } = this.lastPointerMoveCoords;
37261
37204
  const hoveredElement2 = getHoveredElementForBinding2(
37262
- pointFrom34(x, y),
37205
+ pointFrom32(x, y),
37263
37206
  this.scene.getNonDeletedElements(),
37264
37207
  this.scene.getNonDeletedElementsMap()
37265
37208
  );
@@ -37316,8 +37259,8 @@ var App = class _App extends React40.Component {
37316
37259
  );
37317
37260
  const startElement = startDragged2 ? hoveredElement : arrow.startBinding && elementsMap.get(arrow.startBinding.elementId);
37318
37261
  const endElement = endDragged2 ? hoveredElement : arrow.endBinding && elementsMap.get(arrow.endBinding.elementId);
37319
- const startBounds = startElement && getElementBounds5(startElement, elementsMap);
37320
- const endBounds = endElement && getElementBounds5(endElement, elementsMap);
37262
+ const startBounds = startElement && getElementBounds4(startElement, elementsMap);
37263
+ const endBounds = endElement && getElementBounds4(endElement, elementsMap);
37321
37264
  isOverlapping = !!(startBounds && endBounds && startElement.id !== endElement.id && doBoundsIntersect4(startBounds, endBounds));
37322
37265
  }
37323
37266
  const startDragged = this.state.selectedLinearElement?.selectedPointsIndices?.includes(0);
@@ -37376,7 +37319,7 @@ var App = class _App extends React40.Component {
37376
37319
  !oneOf(this.state.activeTool.type, ["laser", "selection", "lasso"])) {
37377
37320
  return false;
37378
37321
  }
37379
- const viewportClickStart_scenePoint = pointFrom34(
37322
+ const viewportClickStart_scenePoint = pointFrom32(
37380
37323
  viewportCoordsToSceneCoords3(
37381
37324
  {
37382
37325
  clientX: this.lastPointerDownEvent.clientX,
@@ -37385,7 +37328,7 @@ var App = class _App extends React40.Component {
37385
37328
  this.state
37386
37329
  )
37387
37330
  );
37388
- const viewportClickEnd_scenePoint = pointFrom34(
37331
+ const viewportClickEnd_scenePoint = pointFrom32(
37389
37332
  viewportCoordsToSceneCoords3(
37390
37333
  {
37391
37334
  clientX: this.lastPointerUpEvent.clientX,
@@ -38432,8 +38375,13 @@ var App = class _App extends React40.Component {
38432
38375
  if (isEraserActive(prevState) && !isEraserActive(this.state)) {
38433
38376
  this.eraserTrail.endPath();
38434
38377
  }
38435
- if (prevProps.viewModeEnabled !== this.props.viewModeEnabled) {
38436
- this.setState({ viewModeEnabled: !!this.props.viewModeEnabled });
38378
+ if (prevProps.viewModeEnabled !== this.props.viewModeEnabled || prevProps.viewModeOnly !== this.props.viewModeOnly) {
38379
+ const viewModeOnly = this.props.viewModeOnly ?? this.state.viewModeOnly;
38380
+ const viewModeEnabled = viewModeOnly ? true : typeof this.props.viewModeEnabled !== "undefined" ? !!this.props.viewModeEnabled : this.state.viewModeEnabled;
38381
+ this.setState({
38382
+ viewModeEnabled,
38383
+ viewModeOnly
38384
+ });
38437
38385
  }
38438
38386
  if (prevState.viewModeEnabled !== this.state.viewModeEnabled) {
38439
38387
  this.addEventListeners();
@@ -38721,7 +38669,7 @@ var App = class _App extends React40.Component {
38721
38669
  this.scene.replaceAllElements([
38722
38670
  // Not sure why we include deleted elements as well hence using deleted elements map
38723
38671
  ...this.scene.getElementsIncludingDeleted().map((_element) => {
38724
- if (_element.id === element.id && isTextElement19(_element)) {
38672
+ if (_element.id === element.id && isTextElement18(_element)) {
38725
38673
  return newElementWith10(_element, {
38726
38674
  originalText: nextOriginalText,
38727
38675
  isDeleted: isDeleted ?? _element.isDeleted,
@@ -38823,7 +38771,7 @@ var App = class _App extends React40.Component {
38823
38771
  return null;
38824
38772
  }
38825
38773
  const selectedElement = selectedElements[0];
38826
- if (isTextElement19(selectedElement)) {
38774
+ if (isTextElement18(selectedElement)) {
38827
38775
  return selectedElement;
38828
38776
  }
38829
38777
  if (!container) {
@@ -38840,7 +38788,7 @@ var App = class _App extends React40.Component {
38840
38788
  return null;
38841
38789
  }
38842
38790
  const selectedElement = selectedElements[0];
38843
- if (isTextElement19(selectedElement)) {
38791
+ if (isTextElement18(selectedElement)) {
38844
38792
  return null;
38845
38793
  }
38846
38794
  if (!isValidTextContainer(selectedElement)) {
@@ -38860,7 +38808,7 @@ var App = class _App extends React40.Component {
38860
38808
  const element = this.getElementAtPosition(x, y, {
38861
38809
  includeBoundTextElement: true
38862
38810
  });
38863
- if (element && isTextElement19(element) && !element.isDeleted) {
38811
+ if (element && isTextElement18(element) && !element.isDeleted) {
38864
38812
  return element;
38865
38813
  }
38866
38814
  return null;
@@ -38886,7 +38834,7 @@ var App = class _App extends React40.Component {
38886
38834
  }
38887
38835
  const elementWithHighestZIndex = allHitElements[allHitElements.length - 1];
38888
38836
  return hitElementItself3({
38889
- point: pointFrom34(x, y),
38837
+ point: pointFrom32(x, y),
38890
38838
  element: elementWithHighestZIndex,
38891
38839
  // when overlapping, we would like to be more precise
38892
38840
  // this also avoids the need to update past tests
@@ -38905,7 +38853,7 @@ var App = class _App extends React40.Component {
38905
38853
  const iframeLikes = [];
38906
38854
  const elementsMap = this.scene.getNonDeletedElementsMap();
38907
38855
  const elements = (opts?.includeBoundTextElement && opts?.includeLockedElements ? this.scene.getNonDeletedElements() : this.scene.getNonDeletedElements().filter(
38908
- (element) => (opts?.includeLockedElements || !element.locked) && (opts?.includeBoundTextElement || !(isTextElement19(element) && element.containerId))
38856
+ (element) => (opts?.includeLockedElements || !element.locked) && (opts?.includeBoundTextElement || !(isTextElement18(element) && element.containerId))
38909
38857
  )).filter((el) => this.hitElement(x, y, el)).filter((element) => {
38910
38858
  const containingFrame = getContainingFrame3(element, elementsMap);
38911
38859
  return containingFrame && this.state.frameRendering.enabled && this.state.frameRendering.clip ? isCursorInFrame({ x, y }, containingFrame, elementsMap) : true;
@@ -38930,7 +38878,7 @@ var App = class _App extends React40.Component {
38930
38878
  hitElement(x, y, element, considerBoundingBox = true) {
38931
38879
  if (considerBoundingBox && this.state.selectedElementIds[element.id] && hasBoundingBox2([element], this.state, this.editorInterface)) {
38932
38880
  if (hitElementBoundingBox2(
38933
- pointFrom34(x, y),
38881
+ pointFrom32(x, y),
38934
38882
  element,
38935
38883
  this.scene.getNonDeletedElementsMap(),
38936
38884
  this.getElementHitThreshold(element)
@@ -38939,7 +38887,7 @@ var App = class _App extends React40.Component {
38939
38887
  }
38940
38888
  }
38941
38889
  const hitBoundTextOfElement = hitElementBoundText(
38942
- pointFrom34(x, y),
38890
+ pointFrom32(x, y),
38943
38891
  element,
38944
38892
  this.scene.getNonDeletedElementsMap()
38945
38893
  );
@@ -38947,7 +38895,7 @@ var App = class _App extends React40.Component {
38947
38895
  return true;
38948
38896
  }
38949
38897
  return hitElementItself3({
38950
- point: pointFrom34(x, y),
38898
+ point: pointFrom32(x, y),
38951
38899
  element,
38952
38900
  threshold: this.getElementHitThreshold(element),
38953
38901
  elementsMap: this.scene.getNonDeletedElementsMap(),
@@ -38969,8 +38917,8 @@ var App = class _App extends React40.Component {
38969
38917
  elements[index],
38970
38918
  this.scene.getNonDeletedElementsMap()
38971
38919
  );
38972
- if (isArrowElement14(elements[index]) && hitElementItself3({
38973
- point: pointFrom34(x, y),
38920
+ if (isArrowElement13(elements[index]) && hitElementItself3({
38921
+ point: pointFrom32(x, y),
38974
38922
  element: elements[index],
38975
38923
  elementsMap: this.scene.getNonDeletedElementsMap(),
38976
38924
  threshold: this.getElementHitThreshold(elements[index])
@@ -39000,7 +38948,7 @@ var App = class _App extends React40.Component {
39000
38948
  let hoverPointIndex = -1;
39001
38949
  let segmentMidPointHoveredCoords = null;
39002
38950
  if (hitElementItself3({
39003
- point: pointFrom34(scenePointerX, scenePointerY),
38951
+ point: pointFrom32(scenePointerX, scenePointerY),
39004
38952
  element,
39005
38953
  elementsMap,
39006
38954
  threshold: this.getElementHitThreshold(element)
@@ -39420,7 +39368,7 @@ var App = class _App extends React40.Component {
39420
39368
  }
39421
39369
  if (isBindingElement4(element)) {
39422
39370
  const hoveredElement = getHoveredElementForBinding2(
39423
- pointFrom34(pointerCoords.x, pointerCoords.y),
39371
+ pointFrom32(pointerCoords.x, pointerCoords.y),
39424
39372
  this.scene.getNonDeletedElements(),
39425
39373
  elementsMap
39426
39374
  );
@@ -39517,24 +39465,24 @@ var App = class _App extends React40.Component {
39517
39465
  croppingElement,
39518
39466
  elementsMap
39519
39467
  );
39520
- const topLeft = vectorFromPoint10(
39521
- pointRotateRads23(
39522
- pointFrom34(x1, y1),
39523
- pointFrom34(cx, cy),
39468
+ const topLeft = vectorFromPoint9(
39469
+ pointRotateRads21(
39470
+ pointFrom32(x1, y1),
39471
+ pointFrom32(cx, cy),
39524
39472
  croppingElement.angle
39525
39473
  )
39526
39474
  );
39527
- const topRight = vectorFromPoint10(
39528
- pointRotateRads23(
39529
- pointFrom34(x2, y1),
39530
- pointFrom34(cx, cy),
39475
+ const topRight = vectorFromPoint9(
39476
+ pointRotateRads21(
39477
+ pointFrom32(x2, y1),
39478
+ pointFrom32(cx, cy),
39531
39479
  croppingElement.angle
39532
39480
  )
39533
39481
  );
39534
- const bottomLeft = vectorFromPoint10(
39535
- pointRotateRads23(
39536
- pointFrom34(x1, y2),
39537
- pointFrom34(cx, cy),
39482
+ const bottomLeft = vectorFromPoint9(
39483
+ pointRotateRads21(
39484
+ pointFrom32(x1, y2),
39485
+ pointFrom32(cx, cy),
39538
39486
  croppingElement.angle
39539
39487
  )
39540
39488
  );
@@ -39660,7 +39608,7 @@ var App = class _App extends React40.Component {
39660
39608
  );
39661
39609
  const elementsWithIndices = syncMovedIndices5(
39662
39610
  mappedNewSceneElements || mappedClonedElements,
39663
- arrayToMap30(duplicatedElements)
39611
+ arrayToMap29(duplicatedElements)
39664
39612
  );
39665
39613
  flushSync2(() => {
39666
39614
  if (pointerDownState.hit.element) {
@@ -39755,7 +39703,7 @@ var App = class _App extends React40.Component {
39755
39703
  this.scene.mutateElement(
39756
39704
  newElement7,
39757
39705
  {
39758
- points: [...points, pointFrom34(dx, dy)],
39706
+ points: [...points, pointFrom32(dx, dy)],
39759
39707
  pressures
39760
39708
  },
39761
39709
  {
@@ -39767,7 +39715,7 @@ var App = class _App extends React40.Component {
39767
39715
  newElement: newElement7
39768
39716
  });
39769
39717
  }
39770
- } else if (isLinearElement12(newElement7) && !newElement7.isDeleted) {
39718
+ } else if (isLinearElement11(newElement7) && !newElement7.isDeleted) {
39771
39719
  pointerDownState.drag.hasOccurred = true;
39772
39720
  const points = newElement7.points;
39773
39721
  invariant16(
@@ -39881,7 +39829,7 @@ var App = class _App extends React40.Component {
39881
39829
  this
39882
39830
  ),
39883
39831
  // select linear element only when we haven't box-selected anything else
39884
- selectedLinearElement: elementsWithinSelection.length === 1 && isLinearElement12(elementsWithinSelection[0]) ? new LinearElementEditor11(
39832
+ selectedLinearElement: elementsWithinSelection.length === 1 && isLinearElement11(elementsWithinSelection[0]) ? new LinearElementEditor11(
39885
39833
  elementsWithinSelection[0],
39886
39834
  this.scene.getNonDeletedElementsMap()
39887
39835
  ) : null,
@@ -40054,7 +40002,7 @@ var App = class _App extends React40.Component {
40054
40002
  sceneCoords
40055
40003
  });
40056
40004
  }
40057
- if (this.state.newElement && this.state.multiElement && isLinearElement12(this.state.newElement) && this.state.selectedLinearElement) {
40005
+ if (this.state.newElement && this.state.multiElement && isLinearElement11(this.state.newElement) && this.state.selectedLinearElement) {
40058
40006
  const { multiElement: multiElement2 } = this.state;
40059
40007
  this.setState({
40060
40008
  selectedLinearElement: {
@@ -40101,13 +40049,13 @@ var App = class _App extends React40.Component {
40101
40049
  }
40102
40050
  const pressures = newElement7.simulatePressure ? [] : [...newElement7.pressures, childEvent.pressure];
40103
40051
  this.scene.mutateElement(newElement7, {
40104
- points: [...points, pointFrom34(dx, dy)],
40052
+ points: [...points, pointFrom32(dx, dy)],
40105
40053
  pressures
40106
40054
  });
40107
40055
  this.actionManager.executeAction(actionFinalize);
40108
40056
  return;
40109
40057
  }
40110
- if (isLinearElement12(newElement7)) {
40058
+ if (isLinearElement11(newElement7)) {
40111
40059
  if (newElement7.points.length > 1 && newElement7.points[1][0] !== 0 && newElement7.points[1][1] !== 0) {
40112
40060
  this.store.scheduleCapture();
40113
40061
  }
@@ -40116,8 +40064,8 @@ var App = class _App extends React40.Component {
40116
40064
  this.state
40117
40065
  );
40118
40066
  const dragDistance = pointDistance9(
40119
- pointFrom34(pointerCoords.x, pointerCoords.y),
40120
- pointFrom34(pointerDownState.origin.x, pointerDownState.origin.y)
40067
+ pointFrom32(pointerCoords.x, pointerCoords.y),
40068
+ pointFrom32(pointerDownState.origin.x, pointerDownState.origin.y)
40121
40069
  ) * this.state.zoom.value;
40122
40070
  if ((!pointerDownState.drag.hasOccurred || dragDistance < MINIMUM_ARROW_SIZE) && newElement7 && !multiElement) {
40123
40071
  if (this.editorInterface.isTouchScreen) {
@@ -40130,8 +40078,8 @@ var App = class _App extends React40.Component {
40130
40078
  {
40131
40079
  x: newElement7.x - FIXED_DELTA_X / 2,
40132
40080
  points: [
40133
- pointFrom34(0, 0),
40134
- pointFrom34(FIXED_DELTA_X, 0)
40081
+ pointFrom32(0, 0),
40082
+ pointFrom32(FIXED_DELTA_X, 0)
40135
40083
  ]
40136
40084
  },
40137
40085
  { informMutation: false, isDragging: false }
@@ -40143,7 +40091,7 @@ var App = class _App extends React40.Component {
40143
40091
  this.scene.mutateElement(
40144
40092
  newElement7,
40145
40093
  {
40146
- points: [newElement7.points[0], pointFrom34(dx, dy)]
40094
+ points: [newElement7.points[0], pointFrom32(dx, dy)]
40147
40095
  },
40148
40096
  { informMutation: false, isDragging: false }
40149
40097
  );
@@ -40153,7 +40101,7 @@ var App = class _App extends React40.Component {
40153
40101
  });
40154
40102
  }
40155
40103
  } else if (pointerDownState.drag.hasOccurred && !multiElement) {
40156
- if (isLinearElement12(newElement7)) {
40104
+ if (isLinearElement11(newElement7)) {
40157
40105
  this.actionManager.executeAction(actionFinalize, "ui", {
40158
40106
  event: childEvent,
40159
40107
  sceneCoords
@@ -40188,7 +40136,7 @@ var App = class _App extends React40.Component {
40188
40136
  }
40189
40137
  return;
40190
40138
  }
40191
- if (isTextElement19(newElement7)) {
40139
+ if (isTextElement18(newElement7)) {
40192
40140
  const minWidth = getMinTextElementWidth(
40193
40141
  getFontString11({
40194
40142
  fontSize: newElement7.fontSize,
@@ -40370,7 +40318,7 @@ var App = class _App extends React40.Component {
40370
40318
  this.scene.replaceAllElements(nextElements);
40371
40319
  }
40372
40320
  const hitElement = pointerDownState.hit.element;
40373
- if (this.state.selectedLinearElement?.elementId !== hitElement?.id && isLinearElement12(hitElement)) {
40321
+ if (this.state.selectedLinearElement?.elementId !== hitElement?.id && isLinearElement11(hitElement)) {
40374
40322
  const selectedElements = this.scene.getSelectedElements(this.state);
40375
40323
  if (selectedElements.length === 1) {
40376
40324
  this.setState({
@@ -40395,8 +40343,8 @@ var App = class _App extends React40.Component {
40395
40343
  if (isEraserActive(this.state) && pointerStart && pointerEnd) {
40396
40344
  this.eraserTrail.endPath();
40397
40345
  const draggedDistance = pointDistance9(
40398
- pointFrom34(pointerStart.clientX, pointerStart.clientY),
40399
- pointFrom34(pointerEnd.clientX, pointerEnd.clientY)
40346
+ pointFrom32(pointerStart.clientX, pointerStart.clientY),
40347
+ pointFrom32(pointerEnd.clientX, pointerEnd.clientY)
40400
40348
  );
40401
40349
  if (draggedDistance === 0) {
40402
40350
  const scenePointer = viewportCoordsToSceneCoords3(
@@ -40471,7 +40419,7 @@ var App = class _App extends React40.Component {
40471
40419
  this
40472
40420
  ),
40473
40421
  // set selectedLinearElement only if thats the only element selected
40474
- selectedLinearElement: newSelectedElements.length === 1 && isLinearElement12(newSelectedElements[0]) ? new LinearElementEditor11(
40422
+ selectedLinearElement: newSelectedElements.length === 1 && isLinearElement11(newSelectedElements[0]) ? new LinearElementEditor11(
40475
40423
  newSelectedElements[0],
40476
40424
  this.scene.getNonDeletedElementsMap()
40477
40425
  ) : prevState.selectedLinearElement
@@ -40525,7 +40473,7 @@ var App = class _App extends React40.Component {
40525
40473
  prevState,
40526
40474
  this
40527
40475
  ),
40528
- selectedLinearElement: isLinearElement12(hitElement) && // Don't set `selectedLinearElement` if its same as the hitElement, this is mainly to prevent resetting the `hoverPointIndex` to -1.
40476
+ selectedLinearElement: isLinearElement11(hitElement) && // Don't set `selectedLinearElement` if its same as the hitElement, this is mainly to prevent resetting the `hoverPointIndex` to -1.
40529
40477
  // Future we should update the API to take care of setting the correct `hoverPointIndex` when initialized
40530
40478
  prevState.selectedLinearElement?.elementId !== hitElement.id ? new LinearElementEditor11(
40531
40479
  hitElement,
@@ -40542,7 +40490,7 @@ var App = class _App extends React40.Component {
40542
40490
  !this.state.isResizing && // only hitting the bounding box of the previous hit element
40543
40491
  (hitElement && hitElementBoundingBoxOnly(
40544
40492
  {
40545
- point: pointFrom34(
40493
+ point: pointFrom32(
40546
40494
  pointerDownState.origin.x,
40547
40495
  pointerDownState.origin.y
40548
40496
  ),
@@ -40568,7 +40516,7 @@ var App = class _App extends React40.Component {
40568
40516
  return;
40569
40517
  }
40570
40518
  const selectedTextEditingContainer = this.getSelectedTextEditingContainerAtPosition(hitElement, sceneCoords);
40571
- if (activeTool.type === this.state.preferredSelectionTool.type && !this.state.editingTextElement && !pointerDownState.drag.hasOccurred && !pointerDownState.hit.wasAddedToSelection && !childEvent.shiftKey && !childEvent[KEYS50.CTRL_OR_CMD] && !childEvent.altKey && childEvent.pointerType !== "touch" && hitElement && (isTextElement19(hitElement) && this.state.selectedElementIds[hitElement.id] && this.scene.getSelectedElements(this.state).length === 1 || selectedTextEditingContainer)) {
40519
+ if (activeTool.type === this.state.preferredSelectionTool.type && !this.state.editingTextElement && !pointerDownState.drag.hasOccurred && !pointerDownState.hit.wasAddedToSelection && !childEvent.shiftKey && !childEvent[KEYS50.CTRL_OR_CMD] && !childEvent.altKey && childEvent.pointerType !== "touch" && hitElement && (isTextElement18(hitElement) && this.state.selectedElementIds[hitElement.id] && this.scene.getSelectedElements(this.state).length === 1 || selectedTextEditingContainer)) {
40572
40520
  this.startTextEditing({
40573
40521
  sceneX: sceneCoords.x,
40574
40522
  sceneY: sceneCoords.y,
@@ -40596,7 +40544,7 @@ var App = class _App extends React40.Component {
40596
40544
  this.store.scheduleCapture();
40597
40545
  }
40598
40546
  if (pointerDownState.drag.hasOccurred && !this.state.selectedLinearElement || isResizing || isRotating || isCropping) {
40599
- const linearElements = this.scene.getSelectedElements(this.state).filter(isArrowElement14);
40547
+ const linearElements = this.scene.getSelectedElements(this.state).filter(isArrowElement13);
40600
40548
  bindOrUnbindBindingElements2(linearElements, this.scene, this.state);
40601
40549
  }
40602
40550
  if (activeTool.type === "laser") {
@@ -41198,7 +41146,7 @@ import { isInvisiblySmallElement as isInvisiblySmallElement4 } from "@excalidraw
41198
41146
 
41199
41147
  // data/reconcile.ts
41200
41148
  import throttle3 from "lodash.throttle";
41201
- import { arrayToMap as arrayToMap31, isDevEnv as isDevEnv10, isTestEnv as isTestEnv6 } from "@excalidraw/common";
41149
+ import { arrayToMap as arrayToMap30, isDevEnv as isDevEnv10, isTestEnv as isTestEnv6 } from "@excalidraw/common";
41202
41150
  import {
41203
41151
  orderByFractionalIndex as orderByFractionalIndex2,
41204
41152
  syncInvalidIndices as syncInvalidIndices2,
@@ -41235,7 +41183,7 @@ var validateIndicesThrottled = throttle3(
41235
41183
  { leading: true, trailing: false }
41236
41184
  );
41237
41185
  var reconcileElements = (localElements, remoteElements, localAppState) => {
41238
- const localElementsMap = arrayToMap31(localElements);
41186
+ const localElementsMap = arrayToMap30(localElements);
41239
41187
  const reconciledElements = [];
41240
41188
  const added = /* @__PURE__ */ new Set();
41241
41189
  for (const remoteElement of remoteElements) {
@@ -41268,7 +41216,7 @@ var reconcileElements = (localElements, remoteElements, localAppState) => {
41268
41216
  };
41269
41217
 
41270
41218
  // index.tsx
41271
- import { isLinearElement as isLinearElement13 } from "@excalidraw/element";
41219
+ import { isLinearElement as isLinearElement12 } from "@excalidraw/element";
41272
41220
  import {
41273
41221
  FONT_FAMILY as FONT_FAMILY7,
41274
41222
  THEME as THEME18,
@@ -41293,6 +41241,7 @@ import {
41293
41241
  getVisibleSceneBounds as getVisibleSceneBounds2,
41294
41242
  convertToExcalidrawElements as convertToExcalidrawElements2
41295
41243
  } from "@excalidraw/element";
41244
+ import { elementsOverlappingBBox as elementsOverlappingBBox3 } from "@excalidraw/element";
41296
41245
 
41297
41246
  // components/DiagramToCodePlugin/DiagramToCodePlugin.tsx
41298
41247
  import { useLayoutEffect as useLayoutEffect9 } from "react";
@@ -41321,6 +41270,7 @@ var ExcalidrawBase = (props) => {
41321
41270
  const {
41322
41271
  onExport,
41323
41272
  onChange,
41273
+ onThemeChange,
41324
41274
  onIncrement,
41325
41275
  initialData,
41326
41276
  onExcalidrawAPI,
@@ -41333,6 +41283,7 @@ var ExcalidrawBase = (props) => {
41333
41283
  renderTopRightUI,
41334
41284
  langCode = defaultLang.code,
41335
41285
  viewModeEnabled,
41286
+ viewModeOnly,
41336
41287
  zenModeEnabled,
41337
41288
  gridModeEnabled,
41338
41289
  theme,
@@ -41377,7 +41328,7 @@ var ExcalidrawBase = (props) => {
41377
41328
  if (canvasActions?.export) {
41378
41329
  UIOptions.canvasActions.export.saveFileToDisk = canvasActions.export?.saveFileToDisk ?? DEFAULT_UI_OPTIONS.canvasActions.export.saveFileToDisk;
41379
41330
  }
41380
- if (UIOptions.canvasActions.toggleTheme === null && typeof theme === "undefined") {
41331
+ if (UIOptions.canvasActions.toggleTheme === null && (theme == null || onThemeChange)) {
41381
41332
  UIOptions.canvasActions.toggleTheme = true;
41382
41333
  }
41383
41334
  const normalizedImageOptions = {
@@ -41416,6 +41367,7 @@ var ExcalidrawBase = (props) => {
41416
41367
  {
41417
41368
  onExport,
41418
41369
  onChange,
41370
+ onThemeChange,
41419
41371
  onIncrement,
41420
41372
  initialData,
41421
41373
  onExcalidrawAPI: handleExcalidrawAPI,
@@ -41428,6 +41380,7 @@ var ExcalidrawBase = (props) => {
41428
41380
  renderTopRightUI,
41429
41381
  langCode,
41430
41382
  viewModeEnabled,
41383
+ viewModeOnly,
41431
41384
  zenModeEnabled,
41432
41385
  gridModeEnabled,
41433
41386
  theme,
@@ -41529,11 +41482,11 @@ export {
41529
41482
  THEME18 as THEME,
41530
41483
  UserIdleState2 as UserIdleState,
41531
41484
  WelcomeScreen_default as WelcomeScreen,
41485
+ applyDarkModeFilter5 as applyDarkModeFilter,
41532
41486
  bumpVersion3 as bumpVersion,
41533
41487
  convertToExcalidrawElements2 as convertToExcalidrawElements,
41534
41488
  defaultLang,
41535
- elementPartiallyOverlapsWithOrContainsBBox,
41536
- elementsOverlappingBBox,
41489
+ elementsOverlappingBBox3 as elementsOverlappingBBox,
41537
41490
  exportToBlob,
41538
41491
  exportToCanvas2 as exportToCanvas,
41539
41492
  exportToClipboard,
@@ -41547,10 +41500,9 @@ export {
41547
41500
  getVisibleSceneBounds2 as getVisibleSceneBounds,
41548
41501
  hashElementsVersion,
41549
41502
  hashString,
41550
- isElementInsideBBox,
41551
41503
  isElementLink3 as isElementLink,
41552
41504
  isInvisiblySmallElement4 as isInvisiblySmallElement,
41553
- isLinearElement13 as isLinearElement,
41505
+ isLinearElement12 as isLinearElement,
41554
41506
  isSpreadsheetValidForChartType,
41555
41507
  languages,
41556
41508
  loadFromBlob,