@excalidraw/element 0.18.0-0457ac9 → 0.18.0-063e025

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 (123) hide show
  1. package/dist/dev/index.js +1305 -895
  2. package/dist/dev/index.js.map +4 -4
  3. package/dist/prod/index.js +18 -18
  4. package/dist/types/common/src/colors.d.ts +1 -1
  5. package/dist/types/common/src/constants.d.ts +9 -7
  6. package/dist/types/common/src/utils.d.ts +0 -42
  7. package/dist/types/element/src/Scene.d.ts +1 -1
  8. package/dist/types/element/src/align.d.ts +2 -2
  9. package/dist/types/element/src/binding.d.ts +6 -6
  10. package/dist/types/element/src/bounds.d.ts +19 -6
  11. package/dist/types/element/src/collision.d.ts +1 -1
  12. package/dist/types/element/src/comparisons.d.ts +1 -0
  13. package/dist/types/element/src/distribute.d.ts +2 -2
  14. package/dist/types/element/src/duplicate.d.ts +3 -3
  15. package/dist/types/element/src/embeddable.d.ts +2 -2
  16. package/dist/types/element/src/flowchart.d.ts +3 -3
  17. package/dist/types/element/src/fractionalIndex.d.ts +2 -2
  18. package/dist/types/element/src/frame.d.ts +4 -4
  19. package/dist/types/element/src/groups.d.ts +9 -9
  20. package/dist/types/element/src/index.d.ts +1 -1
  21. package/dist/types/element/src/linearElementEditor.d.ts +10 -10
  22. package/dist/types/element/src/newElement.d.ts +1 -0
  23. package/dist/types/element/src/renderElement.d.ts +0 -3
  24. package/dist/types/element/src/resizeElements.d.ts +2 -2
  25. package/dist/types/element/src/selection.d.ts +5 -5
  26. package/dist/types/element/src/textElement.d.ts +7 -7
  27. package/dist/types/element/src/transform.d.ts +2 -2
  28. package/dist/types/element/src/typeChecks.d.ts +25 -25
  29. package/dist/types/element/src/types.d.ts +8 -1
  30. package/dist/types/element/src/visualdebug.d.ts +1 -2
  31. package/dist/types/element/src/zindex.d.ts +2 -2
  32. package/dist/types/excalidraw/actions/actionAddToLibrary.d.ts +12 -6
  33. package/dist/types/excalidraw/actions/actionAlign.d.ts +6 -6
  34. package/dist/types/excalidraw/actions/actionBoundText.d.ts +8 -4
  35. package/dist/types/excalidraw/actions/actionCanvas.d.ts +61 -389
  36. package/dist/types/excalidraw/actions/actionClipboard.d.ts +8 -4
  37. package/dist/types/excalidraw/actions/actionCropEditor.d.ts +4 -2
  38. package/dist/types/excalidraw/actions/actionDeleteSelected.d.ts +13 -7
  39. package/dist/types/excalidraw/actions/actionDeselect.d.ts +4 -2
  40. package/dist/types/excalidraw/actions/actionDistribute.d.ts +2 -3
  41. package/dist/types/excalidraw/actions/actionElementLink.d.ts +4 -2
  42. package/dist/types/excalidraw/actions/actionElementLock.d.ts +9 -5
  43. package/dist/types/excalidraw/actions/actionEmbeddable.d.ts +4 -2
  44. package/dist/types/excalidraw/actions/actionExport.d.ts +8 -4
  45. package/dist/types/excalidraw/actions/actionFrame.d.ts +29 -20
  46. package/dist/types/excalidraw/actions/actionGroup.d.ts +23 -19
  47. package/dist/types/excalidraw/actions/actionLinearEditor.d.ts +7 -4
  48. package/dist/types/excalidraw/actions/actionLink.d.ts +5 -3
  49. package/dist/types/excalidraw/actions/actionMenu.d.ts +4 -2
  50. package/dist/types/excalidraw/actions/actionProperties.d.ts +35 -22
  51. package/dist/types/excalidraw/actions/actionSelectAll.d.ts +9 -7
  52. package/dist/types/excalidraw/actions/actionStyles.d.ts +4 -2
  53. package/dist/types/excalidraw/actions/actionToggleArrowBinding.d.ts +5 -3
  54. package/dist/types/excalidraw/actions/actionToggleGridMode.d.ts +8 -7
  55. package/dist/types/excalidraw/actions/actionToggleMidpointSnapping.d.ts +5 -3
  56. package/dist/types/excalidraw/actions/actionToggleObjectsSnapMode.d.ts +5 -3
  57. package/dist/types/excalidraw/actions/actionToggleSearchMenu.d.ts +8 -7
  58. package/dist/types/excalidraw/actions/actionToggleShapeSwitch.d.ts +1 -1
  59. package/dist/types/excalidraw/actions/actionToggleStats.d.ts +5 -3
  60. package/dist/types/excalidraw/actions/actionToggleViewMode.d.ts +5 -3
  61. package/dist/types/excalidraw/actions/actionToggleZenMode.d.ts +5 -3
  62. package/dist/types/excalidraw/actions/index.d.ts +1 -1
  63. package/dist/types/excalidraw/actions/types.d.ts +4 -4
  64. package/dist/types/excalidraw/{animated-trail.d.ts → animatedTrail.d.ts} +4 -3
  65. package/dist/types/excalidraw/appState.d.ts +2 -1
  66. package/dist/types/excalidraw/components/Actions.d.ts +2 -3
  67. package/dist/types/excalidraw/components/ActiveConfirmDialog.d.ts +1 -1
  68. package/dist/types/excalidraw/components/App.d.ts +61 -32
  69. package/dist/types/excalidraw/components/ColorPicker/ColorPicker.d.ts +2 -2
  70. package/dist/types/excalidraw/components/ColorPicker/colorPickerUtils.d.ts +1 -1
  71. package/dist/types/excalidraw/components/CommandPalette/defaultCommandPaletteItems.d.ts +1 -2
  72. package/dist/types/excalidraw/components/ConvertElementTypePopup.d.ts +2 -2
  73. package/dist/types/excalidraw/components/CursorHint.d.ts +46 -0
  74. package/dist/types/excalidraw/components/EyeDropper.d.ts +1 -1
  75. package/dist/types/excalidraw/components/Island.d.ts +7 -0
  76. package/dist/types/excalidraw/components/LibraryMenu.d.ts +1 -1
  77. package/dist/types/excalidraw/components/OverwriteConfirm/OverwriteConfirmState.d.ts +1 -1
  78. package/dist/types/excalidraw/components/SVGLayer.d.ts +1 -1
  79. package/dist/types/excalidraw/components/SearchMenu.d.ts +1 -1
  80. package/dist/types/excalidraw/components/Sidebar/Sidebar.d.ts +1 -1
  81. package/dist/types/excalidraw/components/Stats/Angle.d.ts +2 -2
  82. package/dist/types/excalidraw/components/Stats/Dimension.d.ts +2 -2
  83. package/dist/types/excalidraw/components/Stats/DragInput.d.ts +2 -2
  84. package/dist/types/excalidraw/components/Stats/MultiAngle.d.ts +2 -2
  85. package/dist/types/excalidraw/components/Stats/MultiDimension.d.ts +2 -2
  86. package/dist/types/excalidraw/components/Stats/MultiPosition.d.ts +2 -2
  87. package/dist/types/excalidraw/components/Stats/Position.d.ts +3 -3
  88. package/dist/types/excalidraw/components/Stats/utils.d.ts +1 -1
  89. package/dist/types/excalidraw/components/TTDDialog/TTDContext.d.ts +4 -4
  90. package/dist/types/excalidraw/components/TTDDialog/useTTDChatStorage.d.ts +3 -3
  91. package/dist/types/excalidraw/components/hyperlink/helpers.d.ts +2 -2
  92. package/dist/types/excalidraw/components/icons.d.ts +2 -0
  93. package/dist/types/excalidraw/components/main-menu/DefaultItems.d.ts +6 -3
  94. package/dist/types/excalidraw/data/blob.d.ts +8 -4
  95. package/dist/types/excalidraw/data/index.d.ts +4 -4
  96. package/dist/types/excalidraw/data/json.d.ts +10 -8
  97. package/dist/types/excalidraw/data/library.d.ts +1 -1
  98. package/dist/types/excalidraw/eraser/index.d.ts +2 -3
  99. package/dist/types/excalidraw/hooks/useAppStateValue.d.ts +29 -0
  100. package/dist/types/excalidraw/hooks/useLibraryItemSvg.d.ts +1 -1
  101. package/dist/types/excalidraw/{laser-trails.d.ts → laserTrails.d.ts} +5 -7
  102. package/dist/types/excalidraw/lasso/index.d.ts +2 -3
  103. package/dist/types/excalidraw/renderer/animation.d.ts +5 -1
  104. package/dist/types/excalidraw/renderer/interactiveScene.d.ts +1 -3
  105. package/dist/types/excalidraw/scene/Renderer.d.ts +12 -11
  106. package/dist/types/excalidraw/scene/export.d.ts +3 -3
  107. package/dist/types/excalidraw/scene/index.d.ts +2 -2
  108. package/dist/types/excalidraw/scene/types.d.ts +1 -3
  109. package/dist/types/excalidraw/snapping.d.ts +7 -7
  110. package/dist/types/excalidraw/types.d.ts +168 -11
  111. package/dist/types/excalidraw/viewport.d.ts +316 -0
  112. package/dist/types/excalidraw/wysiwyg/textWysiwyg.d.ts +2 -3
  113. package/dist/types/laser-pointer/src/index.d.ts +2 -0
  114. package/dist/types/laser-pointer/src/math.d.ts +16 -0
  115. package/dist/types/laser-pointer/src/simplify.d.ts +2 -0
  116. package/dist/types/laser-pointer/src/state.d.ts +35 -0
  117. package/dist/types/utils/src/export.d.ts +3 -3
  118. package/dist/types/utils/src/index.d.ts +1 -2
  119. package/package.json +4 -4
  120. package/dist/types/excalidraw/animation-frame-handler.d.ts +0 -16
  121. package/dist/types/excalidraw/scene/scroll.d.ts +0 -18
  122. package/dist/types/utils/src/bbox.d.ts +0 -9
  123. package/dist/types/utils/src/withinBounds.d.ts +0 -19
package/dist/dev/index.js CHANGED
@@ -230,9 +230,9 @@ init_define_import_meta_env();
230
230
  function rotatePoints(points, center, degrees) {
231
231
  if (points && points.length) {
232
232
  const [cx, cy] = center;
233
- const angle = Math.PI / 180 * degrees;
234
- const cos = Math.cos(angle);
235
- const sin = Math.sin(angle);
233
+ const angle2 = Math.PI / 180 * degrees;
234
+ const cos = Math.cos(angle2);
235
+ const sin = Math.sin(angle2);
236
236
  for (const p of points) {
237
237
  const [x, y] = p;
238
238
  p[0] = (x - cx) * cos - (y - cy) * sin + cx;
@@ -249,21 +249,21 @@ function areSamePoints(p1, p2) {
249
249
  return p1[0] === p2[0] && p1[1] === p2[1];
250
250
  }
251
251
  function hachureLines(polygons, hachureGap, hachureAngle, hachureStepOffset = 1) {
252
- const angle = hachureAngle;
252
+ const angle2 = hachureAngle;
253
253
  const gap = Math.max(hachureGap, 0.1);
254
254
  const polygonList = polygons[0] && polygons[0][0] && typeof polygons[0][0] === "number" ? [polygons] : polygons;
255
255
  const rotationCenter = [0, 0];
256
- if (angle) {
256
+ if (angle2) {
257
257
  for (const polygon3 of polygonList) {
258
- rotatePoints(polygon3, rotationCenter, angle);
258
+ rotatePoints(polygon3, rotationCenter, angle2);
259
259
  }
260
260
  }
261
261
  const lines = straightHachureLines(polygonList, gap, hachureStepOffset);
262
- if (angle) {
262
+ if (angle2) {
263
263
  for (const polygon3 of polygonList) {
264
- rotatePoints(polygon3, rotationCenter, -angle);
264
+ rotatePoints(polygon3, rotationCenter, -angle2);
265
265
  }
266
- rotateLines(lines, rotationCenter, -angle);
266
+ rotateLines(lines, rotationCenter, -angle2);
267
267
  }
268
268
  return lines;
269
269
  }
@@ -374,7 +374,7 @@ function straightHachureLines(polygons, gap, hachureStepOffset) {
374
374
  // ../../node_modules/roughjs/bin/fillers/scan-line-hachure.js
375
375
  function polygonHachureLines(polygonList, o) {
376
376
  var _a;
377
- const angle = o.hachureAngle + 90;
377
+ const angle2 = o.hachureAngle + 90;
378
378
  let gap = o.hachureGap;
379
379
  if (gap < 0) {
380
380
  gap = o.strokeWidth * 4;
@@ -386,7 +386,7 @@ function polygonHachureLines(polygonList, o) {
386
386
  skipOffset = gap;
387
387
  }
388
388
  }
389
- return hachureLines(polygonList, gap, angle, skipOffset || 1);
389
+ return hachureLines(polygonList, gap, angle2, skipOffset || 1);
390
390
  }
391
391
 
392
392
  // ../../node_modules/roughjs/bin/fillers/hachure-filler.js
@@ -924,7 +924,7 @@ function normalize(segments) {
924
924
  case "A": {
925
925
  const r1 = Math.abs(data[0]);
926
926
  const r2 = Math.abs(data[1]);
927
- const angle = data[2];
927
+ const angle2 = data[2];
928
928
  const largeArcFlag = data[3];
929
929
  const sweepFlag = data[4];
930
930
  const x = data[5];
@@ -935,7 +935,7 @@ function normalize(segments) {
935
935
  cy = y;
936
936
  } else {
937
937
  if (cx !== x || cy !== y) {
938
- const curves = arcToCubicCurves(cx, cy, x, y, r1, r2, angle, largeArcFlag, sweepFlag);
938
+ const curves = arcToCubicCurves(cx, cy, x, y, r1, r2, angle2, largeArcFlag, sweepFlag);
939
939
  curves.forEach(function(curve4) {
940
940
  out.push({ key: "C", data: curve4 });
941
941
  });
@@ -963,8 +963,8 @@ function rotate(x, y, angleRad) {
963
963
  const Y = x * Math.sin(angleRad) + y * Math.cos(angleRad);
964
964
  return [X, Y];
965
965
  }
966
- function arcToCubicCurves(x1, y1, x2, y2, r1, r2, angle, largeArcFlag, sweepFlag, recursive) {
967
- const angleRad = degToRad(angle);
966
+ function arcToCubicCurves(x1, y1, x2, y2, r1, r2, angle2, largeArcFlag, sweepFlag, recursive) {
967
+ const angleRad = degToRad(angle2);
968
968
  let params = [];
969
969
  let f1 = 0, f2 = 0, cx = 0, cy = 0;
970
970
  if (recursive) {
@@ -1021,7 +1021,7 @@ function arcToCubicCurves(x1, y1, x2, y2, r1, r2, angle, largeArcFlag, sweepFlag
1021
1021
  }
1022
1022
  x2 = cx + r1 * Math.cos(f2);
1023
1023
  y2 = cy + r2 * Math.sin(f2);
1024
- params = arcToCubicCurves(x2, y2, x2old, y2old, r1, r2, angle, 0, sweepFlag, [f2, f2old, cx, cy]);
1024
+ params = arcToCubicCurves(x2, y2, x2old, y2old, r1, r2, angle2, 0, sweepFlag, [f2, f2old, cx, cy]);
1025
1025
  }
1026
1026
  df = f2 - f1;
1027
1027
  const c1 = Math.cos(f1);
@@ -1227,8 +1227,8 @@ function patternFillArc(x, y, width, height, start, stop, o) {
1227
1227
  }
1228
1228
  const increment = (stp - strt) / o.curveStepCount;
1229
1229
  const points = [];
1230
- for (let angle = strt; angle <= stp; angle = angle + increment) {
1231
- points.push([cx + rx * Math.cos(angle), cy + ry * Math.sin(angle)]);
1230
+ for (let angle2 = strt; angle2 <= stp; angle2 = angle2 + increment) {
1231
+ points.push([cx + rx * Math.cos(angle2), cy + ry * Math.sin(angle2)]);
1232
1232
  }
1233
1233
  points.push([cx + rx * Math.cos(stp), cy + ry * Math.sin(stp)]);
1234
1234
  points.push([cx, cy]);
@@ -1414,10 +1414,10 @@ function _computeEllipsePoints(increment, cx, cy, rx, ry, offset, overlap, o) {
1414
1414
  cx + rx * Math.cos(-increment),
1415
1415
  cy + ry * Math.sin(-increment)
1416
1416
  ]);
1417
- for (let angle = 0; angle <= Math.PI * 2; angle = angle + increment) {
1417
+ for (let angle2 = 0; angle2 <= Math.PI * 2; angle2 = angle2 + increment) {
1418
1418
  const p = [
1419
- cx + rx * Math.cos(angle),
1420
- cy + ry * Math.sin(angle)
1419
+ cx + rx * Math.cos(angle2),
1420
+ cy + ry * Math.sin(angle2)
1421
1421
  ];
1422
1422
  corePoints.push(p);
1423
1423
  allPoints.push(p);
@@ -1437,10 +1437,10 @@ function _computeEllipsePoints(increment, cx, cy, rx, ry, offset, overlap, o) {
1437
1437
  _offsetOpt(offset, o) + cy + 0.9 * ry * Math.sin(radOffset - increment)
1438
1438
  ]);
1439
1439
  const endAngle = Math.PI * 2 + radOffset - 0.01;
1440
- for (let angle = radOffset; angle < endAngle; angle = angle + increment) {
1440
+ for (let angle2 = radOffset; angle2 < endAngle; angle2 = angle2 + increment) {
1441
1441
  const p = [
1442
- _offsetOpt(offset, o) + cx + rx * Math.cos(angle),
1443
- _offsetOpt(offset, o) + cy + ry * Math.sin(angle)
1442
+ _offsetOpt(offset, o) + cx + rx * Math.cos(angle2),
1443
+ _offsetOpt(offset, o) + cy + ry * Math.sin(angle2)
1444
1444
  ];
1445
1445
  corePoints.push(p);
1446
1446
  allPoints.push(p);
@@ -1467,10 +1467,10 @@ function _arc(increment, cx, cy, rx, ry, strt, stp, offset, o) {
1467
1467
  _offsetOpt(offset, o) + cx + 0.9 * rx * Math.cos(radOffset - increment),
1468
1468
  _offsetOpt(offset, o) + cy + 0.9 * ry * Math.sin(radOffset - increment)
1469
1469
  ]);
1470
- for (let angle = radOffset; angle <= stp; angle = angle + increment) {
1470
+ for (let angle2 = radOffset; angle2 <= stp; angle2 = angle2 + increment) {
1471
1471
  points.push([
1472
- _offsetOpt(offset, o) + cx + rx * Math.cos(angle),
1473
- _offsetOpt(offset, o) + cy + ry * Math.sin(angle)
1472
+ _offsetOpt(offset, o) + cx + rx * Math.cos(angle2),
1473
+ _offsetOpt(offset, o) + cy + ry * Math.sin(angle2)
1474
1474
  ]);
1475
1475
  }
1476
1476
  points.push([
@@ -2267,11 +2267,10 @@ import {
2267
2267
  } from "@excalidraw/common";
2268
2268
  import {
2269
2269
  degreesToRadians,
2270
- lineSegment as lineSegment7,
2271
- pointDistance as pointDistance7,
2272
- pointFrom as pointFrom14,
2270
+ lineSegment as lineSegment6,
2271
+ pointFrom as pointFrom13,
2273
2272
  pointFromArray as pointFromArray3,
2274
- pointRotateRads as pointRotateRads13
2273
+ pointRotateRads as pointRotateRads12
2275
2274
  } from "@excalidraw/math";
2276
2275
 
2277
2276
  // ../utils/src/shape.ts
@@ -2296,24 +2295,24 @@ import {
2296
2295
  } from "@excalidraw/math";
2297
2296
  import { getElementAbsoluteCoords } from "@excalidraw/element";
2298
2297
  var getPolygonShape = (element) => {
2299
- const { angle, width, height, x, y } = element;
2298
+ const { angle: angle2, width, height, x, y } = element;
2300
2299
  const cx = x + width / 2;
2301
2300
  const cy = y + height / 2;
2302
2301
  const center = pointFrom(cx, cy);
2303
2302
  let data;
2304
2303
  if (element.type === "diamond") {
2305
2304
  data = polygon2(
2306
- pointRotateRads(pointFrom(cx, y), center, angle),
2307
- pointRotateRads(pointFrom(x + width, cy), center, angle),
2308
- pointRotateRads(pointFrom(cx, y + height), center, angle),
2309
- pointRotateRads(pointFrom(x, cy), center, angle)
2305
+ pointRotateRads(pointFrom(cx, y), center, angle2),
2306
+ pointRotateRads(pointFrom(x + width, cy), center, angle2),
2307
+ pointRotateRads(pointFrom(cx, y + height), center, angle2),
2308
+ pointRotateRads(pointFrom(x, cy), center, angle2)
2310
2309
  );
2311
2310
  } else {
2312
2311
  data = polygon2(
2313
- pointRotateRads(pointFrom(x, y), center, angle),
2314
- pointRotateRads(pointFrom(x + width, y), center, angle),
2315
- pointRotateRads(pointFrom(x + width, y + height), center, angle),
2316
- pointRotateRads(pointFrom(x, y + height), center, angle)
2312
+ pointRotateRads(pointFrom(x, y), center, angle2),
2313
+ pointRotateRads(pointFrom(x + width, y), center, angle2),
2314
+ pointRotateRads(pointFrom(x + width, y + height), center, angle2),
2315
+ pointRotateRads(pointFrom(x, y + height), center, angle2)
2317
2316
  );
2318
2317
  }
2319
2318
  return {
@@ -2322,12 +2321,12 @@ var getPolygonShape = (element) => {
2322
2321
  };
2323
2322
  };
2324
2323
  var getEllipseShape = (element) => {
2325
- const { width, height, angle, x, y } = element;
2324
+ const { width, height, angle: angle2, x, y } = element;
2326
2325
  return {
2327
2326
  type: "ellipse",
2328
2327
  data: {
2329
2328
  center: pointFrom(x + width / 2, y + height / 2),
2330
- angle,
2329
+ angle: angle2,
2331
2330
  halfWidth: width / 2,
2332
2331
  halfHeight: height / 2
2333
2332
  }
@@ -2611,11 +2610,367 @@ function ae(e, t = {}) {
2611
2610
  return ce(me(e, t), t);
2612
2611
  }
2613
2612
 
2613
+ // ../laser-pointer/src/index.ts
2614
+ init_define_import_meta_env();
2615
+
2616
+ // ../laser-pointer/src/state.ts
2617
+ init_define_import_meta_env();
2618
+
2619
+ // ../laser-pointer/src/math.ts
2620
+ init_define_import_meta_env();
2621
+ function add([ax, ay, ar], [bx, by, br]) {
2622
+ return [ax + bx, ay + by, ar + br];
2623
+ }
2624
+ function sub([ax, ay, ar], [bx, by, br]) {
2625
+ return [ax - bx, ay - by, ar - br];
2626
+ }
2627
+ function smul([x, y, r], s) {
2628
+ return [x * s, y * s, r * s];
2629
+ }
2630
+ function norm([x, y, r]) {
2631
+ return [x / Math.sqrt(x ** 2 + y ** 2), y / Math.sqrt(x ** 2 + y ** 2), r];
2632
+ }
2633
+ function rot([x, y, r], rad) {
2634
+ return [
2635
+ Math.cos(rad) * x - Math.sin(rad) * y,
2636
+ Math.sin(rad) * x + Math.cos(rad) * y,
2637
+ r
2638
+ ];
2639
+ }
2640
+ function plerp(a2, b2, t) {
2641
+ return add(a2, smul(sub(b2, a2), t));
2642
+ }
2643
+ function angle(p, p1, p2) {
2644
+ return Math.atan2(p2[1] - p[1], p2[0] - p[0]) - Math.atan2(p1[1] - p[1], p1[0] - p[0]);
2645
+ }
2646
+ function normAngle(a2) {
2647
+ return Math.atan2(Math.sin(a2), Math.cos(a2));
2648
+ }
2649
+ function mag([x, y]) {
2650
+ return Math.sqrt(x ** 2 + y ** 2);
2651
+ }
2652
+ function dist([ax, ay], [bx, by]) {
2653
+ return Math.sqrt((bx - ax) ** 2 + (by - ay) ** 2);
2654
+ }
2655
+ function runLength(ps) {
2656
+ if (ps.length < 2) {
2657
+ return 0;
2658
+ }
2659
+ let len = 0;
2660
+ for (let i = 1; i <= ps.length - 1; i++) {
2661
+ len += dist(ps[i - 1], ps[i]);
2662
+ }
2663
+ len += dist(ps[ps.length - 2], ps[ps.length - 1]);
2664
+ return len;
2665
+ }
2666
+ var clamp = (v, min, max) => Math.max(min, Math.min(max, v));
2667
+ function distancePointToSegment(p3, p1, p2) {
2668
+ const sMag = dist(p1, p2);
2669
+ if (sMag === 0) {
2670
+ return dist(p3, p1);
2671
+ }
2672
+ const u = clamp(
2673
+ ((p3[0] - p1[0]) * (p2[0] - p1[0]) + (p3[1] - p1[1]) * (p2[1] - p1[1])) / sMag ** 2,
2674
+ 0,
2675
+ 1
2676
+ );
2677
+ const pi = [
2678
+ p1[0] + u * (p2[0] - p1[0]),
2679
+ p1[1] + u * (p2[1] - p1[1]),
2680
+ p3[2]
2681
+ ];
2682
+ return dist(pi, p3);
2683
+ }
2684
+
2685
+ // ../laser-pointer/src/simplify.ts
2686
+ init_define_import_meta_env();
2687
+ function douglasPeucker(points, epsilon) {
2688
+ if (epsilon === 0) {
2689
+ return points;
2690
+ }
2691
+ if (points.length <= 2) {
2692
+ return points;
2693
+ }
2694
+ const first = points[0];
2695
+ const last = points[points.length - 1];
2696
+ const [maxDistance, maxIndex] = points.reduce(
2697
+ ([maxDistance2, maxIndex2], point, index) => {
2698
+ const distance3 = distancePointToSegment(point, first, last);
2699
+ return distance3 > maxDistance2 ? [distance3, index] : [maxDistance2, maxIndex2];
2700
+ },
2701
+ [0, -1]
2702
+ );
2703
+ if (maxDistance >= epsilon) {
2704
+ const maxIndexPoint = points[maxIndex];
2705
+ return [
2706
+ ...douglasPeucker(
2707
+ [first, ...points.slice(1, maxIndex), maxIndexPoint],
2708
+ epsilon
2709
+ ).slice(0, -1),
2710
+ maxIndexPoint,
2711
+ ...douglasPeucker(
2712
+ [maxIndexPoint, ...points.slice(maxIndex, -1), last],
2713
+ epsilon
2714
+ ).slice(1)
2715
+ ];
2716
+ }
2717
+ return [first, last];
2718
+ }
2719
+
2720
+ // ../laser-pointer/src/state.ts
2721
+ var LaserPointer = class _LaserPointer {
2722
+ static defaults = {
2723
+ size: 2,
2724
+ streamline: 0.45,
2725
+ simplify: 0.1,
2726
+ simplifyPhase: "output",
2727
+ keepHead: false,
2728
+ sizeMapping: () => 1
2729
+ };
2730
+ static constants = {
2731
+ cornerDetectionMaxAngle: 75,
2732
+ cornerDetectionVariance: (s) => s > 35 ? 0.5 : 1,
2733
+ maxTailLength: 50
2734
+ };
2735
+ options;
2736
+ constructor(options) {
2737
+ this.options = Object.assign({}, _LaserPointer.defaults, options);
2738
+ }
2739
+ originalPoints = [];
2740
+ stablePoints = [];
2741
+ tailPoints = [];
2742
+ isFresh = true;
2743
+ get lastPoint() {
2744
+ return this.tailPoints[this.tailPoints.length - 1] ?? this.stablePoints[this.stablePoints.length - 1];
2745
+ }
2746
+ addPoint(point) {
2747
+ const lastPoint = this.originalPoints[this.originalPoints.length - 1];
2748
+ if (lastPoint && lastPoint[0] === point[0] && lastPoint[1] === point[1]) {
2749
+ return;
2750
+ }
2751
+ this.originalPoints.push(point);
2752
+ if (this.isFresh) {
2753
+ this.isFresh = false;
2754
+ this.stablePoints.push(point);
2755
+ return;
2756
+ }
2757
+ if (this.options.streamline > 0) {
2758
+ point = plerp(this.lastPoint, point, 1 - this.options.streamline);
2759
+ }
2760
+ this.tailPoints.push(point);
2761
+ if (runLength(this.tailPoints) > _LaserPointer.constants.maxTailLength) {
2762
+ this.stabilizeTail();
2763
+ }
2764
+ }
2765
+ close() {
2766
+ this.stabilizeTail();
2767
+ }
2768
+ stabilizeTail() {
2769
+ if (this.options.simplify > 0 && this.options.simplifyPhase === "tail") {
2770
+ throw new Error("Not implemented yet");
2771
+ } else {
2772
+ this.stablePoints.push(...this.tailPoints);
2773
+ this.tailPoints = [];
2774
+ }
2775
+ }
2776
+ getSize(sizeOverride, pressure, index, totalLength, runningLength) {
2777
+ return (sizeOverride ?? this.options.size) * this.options.sizeMapping({
2778
+ pressure,
2779
+ runningLength,
2780
+ currentIndex: index,
2781
+ totalLength
2782
+ });
2783
+ }
2784
+ getStrokeOutline(sizeOverride) {
2785
+ if (this.isFresh) {
2786
+ return [];
2787
+ }
2788
+ let points = [...this.stablePoints, ...this.tailPoints];
2789
+ if (this.options.simplify > 0 && this.options.simplifyPhase === "input") {
2790
+ points = douglasPeucker(points, this.options.simplify);
2791
+ }
2792
+ const len = points.length;
2793
+ if (len === 0) {
2794
+ return [];
2795
+ }
2796
+ if (len === 1) {
2797
+ const c = points[0];
2798
+ const size = this.getSize(sizeOverride, c[2], 0, len, 0);
2799
+ if (size < 0.5) {
2800
+ return [];
2801
+ }
2802
+ const ps = [];
2803
+ for (let theta = 0; theta <= Math.PI * 2; theta += Math.PI / 16) {
2804
+ ps.push(add(c, smul(rot([1, 0, 0], theta), size)));
2805
+ }
2806
+ ps.push(
2807
+ add(
2808
+ c,
2809
+ smul(
2810
+ [1, 0, 0],
2811
+ this.getSize(sizeOverride, c[2], 0, len, 0)
2812
+ )
2813
+ )
2814
+ );
2815
+ return ps;
2816
+ }
2817
+ if (len === 2) {
2818
+ const c = points[0];
2819
+ const n = points[1];
2820
+ const cSize = this.getSize(sizeOverride, c[2], 0, len, 0);
2821
+ const nSize = this.getSize(sizeOverride, n[2], 0, len, 0);
2822
+ if (cSize < 0.5 || nSize < 0.5) {
2823
+ return [];
2824
+ }
2825
+ const ps = [];
2826
+ const pAngle = angle(c, [c[0], c[1] - 100, c[2]], n);
2827
+ for (let theta = pAngle; theta <= Math.PI + pAngle; theta += Math.PI / 16) {
2828
+ ps.push(add(c, smul(rot([1, 0, 0], theta), cSize)));
2829
+ }
2830
+ for (let theta = Math.PI + pAngle; theta <= Math.PI * 2 + pAngle; theta += Math.PI / 16) {
2831
+ ps.push(add(n, smul(rot([1, 0, 0], theta), nSize)));
2832
+ }
2833
+ ps.push(ps[0]);
2834
+ return ps;
2835
+ }
2836
+ const forwardPoints = [];
2837
+ const backwardPoints = [];
2838
+ let speed = 0;
2839
+ let prevSpeed = 0;
2840
+ let visibleStartIndex = 0;
2841
+ let runningLength = 0;
2842
+ for (let i = 1; i < len - 1; i++) {
2843
+ const p = points[i - 1];
2844
+ const c = points[i];
2845
+ const n = points[i + 1];
2846
+ const pressure = c[2];
2847
+ const d = dist(p, c);
2848
+ runningLength += d;
2849
+ speed = prevSpeed + (d - prevSpeed) * 0.2;
2850
+ const cSize = this.getSize(sizeOverride, pressure, i, len, runningLength);
2851
+ if (cSize === 0) {
2852
+ visibleStartIndex = i + 1;
2853
+ continue;
2854
+ }
2855
+ const dirPC = norm(sub(p, c));
2856
+ const dirNC = norm(sub(n, c));
2857
+ const p1dirPC = rot(dirPC, Math.PI / 2);
2858
+ const p2dirPC = rot(dirPC, -Math.PI / 2);
2859
+ const p1dirNC = rot(dirNC, Math.PI / 2);
2860
+ const p2dirNC = rot(dirNC, -Math.PI / 2);
2861
+ const p1PC = add(c, smul(p1dirPC, cSize));
2862
+ const p2PC = add(c, smul(p2dirPC, cSize));
2863
+ const p1NC = add(c, smul(p1dirNC, cSize));
2864
+ const p2NC = add(c, smul(p2dirNC, cSize));
2865
+ const ftdir = add(p1dirPC, p2dirNC);
2866
+ const btdir = add(p2dirPC, p1dirNC);
2867
+ const paPC = add(
2868
+ c,
2869
+ smul(mag(ftdir) === 0 ? dirPC : norm(ftdir), cSize)
2870
+ );
2871
+ const paNC = add(
2872
+ c,
2873
+ smul(mag(btdir) === 0 ? dirNC : norm(btdir), cSize)
2874
+ );
2875
+ const cAngle = normAngle(angle(c, p, n));
2876
+ const D_ANGLE = _LaserPointer.constants.cornerDetectionMaxAngle / 180 * Math.PI * _LaserPointer.constants.cornerDetectionVariance(speed);
2877
+ if (Math.abs(cAngle) < D_ANGLE) {
2878
+ const tAngle = Math.abs(normAngle(Math.PI - cAngle));
2879
+ if (tAngle === 0) {
2880
+ continue;
2881
+ }
2882
+ if (cAngle < 0) {
2883
+ backwardPoints.push(p2PC, paNC);
2884
+ for (let theta = 0; theta <= tAngle; theta += tAngle / 4) {
2885
+ forwardPoints.push(add(c, rot(smul(p1dirPC, cSize), theta)));
2886
+ }
2887
+ for (let theta = tAngle; theta >= 0; theta -= tAngle / 4) {
2888
+ backwardPoints.push(add(c, rot(smul(p1dirPC, cSize), theta)));
2889
+ }
2890
+ backwardPoints.push(paNC, p1NC);
2891
+ } else {
2892
+ forwardPoints.push(p1PC, paPC);
2893
+ for (let theta = 0; theta <= tAngle; theta += tAngle / 4) {
2894
+ backwardPoints.push(
2895
+ add(c, rot(smul(p1dirPC, -cSize), -theta))
2896
+ );
2897
+ }
2898
+ for (let theta = tAngle; theta >= 0; theta -= tAngle / 4) {
2899
+ forwardPoints.push(
2900
+ add(c, rot(smul(p1dirPC, -cSize), -theta))
2901
+ );
2902
+ }
2903
+ forwardPoints.push(paPC, p2NC);
2904
+ }
2905
+ } else {
2906
+ forwardPoints.push(paPC);
2907
+ backwardPoints.push(paNC);
2908
+ }
2909
+ prevSpeed = speed;
2910
+ }
2911
+ if (visibleStartIndex >= len - 2) {
2912
+ if (this.options.keepHead) {
2913
+ const c = points[len - 1];
2914
+ const ps = [];
2915
+ for (let theta = 0; theta <= Math.PI * 2; theta += Math.PI / 16) {
2916
+ ps.push(
2917
+ add(
2918
+ c,
2919
+ smul(rot([1, 0, 0], theta), this.options.size)
2920
+ )
2921
+ );
2922
+ }
2923
+ ps.push(add(c, smul([1, 0, 0], this.options.size)));
2924
+ return ps;
2925
+ }
2926
+ return [];
2927
+ }
2928
+ const first = points[visibleStartIndex];
2929
+ const second = points[visibleStartIndex + 1];
2930
+ const penultimate = points[len - 2];
2931
+ const ultimate = points[len - 1];
2932
+ const dirFS = norm(sub(second, first));
2933
+ const dirPU = norm(sub(penultimate, ultimate));
2934
+ const ppdirFS = rot(dirFS, -Math.PI / 2);
2935
+ const ppdirPU = rot(dirPU, Math.PI / 2);
2936
+ const startCapSize = this.getSize(sizeOverride, first[2], 0, len, 0);
2937
+ const startCap = [];
2938
+ const endCapSize = this.options.keepHead ? this.options.size : this.getSize(sizeOverride, penultimate[2], len - 2, len, runningLength);
2939
+ const endCap = [];
2940
+ if (startCapSize > 0.1) {
2941
+ for (let theta = 0; theta <= Math.PI; theta += Math.PI / 16) {
2942
+ startCap.unshift(
2943
+ add(first, rot(smul(ppdirFS, startCapSize), -theta))
2944
+ );
2945
+ }
2946
+ startCap.unshift(add(first, smul(ppdirFS, -startCapSize)));
2947
+ } else {
2948
+ startCap.push(first);
2949
+ }
2950
+ for (let theta = 0; theta <= Math.PI * 3; theta += Math.PI / 16) {
2951
+ endCap.push(add(ultimate, rot(smul(ppdirPU, -endCapSize), -theta)));
2952
+ }
2953
+ const strokeOutline = [
2954
+ ...startCap,
2955
+ ...forwardPoints,
2956
+ ...endCap.reverse(),
2957
+ ...backwardPoints.reverse()
2958
+ ];
2959
+ if (startCap.length > 0) {
2960
+ strokeOutline.push(startCap[0]);
2961
+ }
2962
+ if (this.options.simplify > 0 && this.options.simplifyPhase === "output") {
2963
+ return douglasPeucker(strokeOutline, this.options.simplify);
2964
+ }
2965
+ return strokeOutline;
2966
+ }
2967
+ };
2968
+
2614
2969
  // src/shape.ts
2615
2970
  import {
2616
- pointFrom as pointFrom13,
2971
+ pointFrom as pointFrom12,
2617
2972
  pointDistance as pointDistance6,
2618
- pointRotateRads as pointRotateRads12
2973
+ pointRotateRads as pointRotateRads11
2619
2974
  } from "@excalidraw/math";
2620
2975
  import {
2621
2976
  ROUGHNESS,
@@ -2624,16 +2979,17 @@ import {
2624
2979
  assertNever as assertNever2,
2625
2980
  COLOR_PALETTE,
2626
2981
  LINE_POLYGON_POINT_MERGE_DISTANCE,
2627
- applyDarkModeFilter as applyDarkModeFilter2
2982
+ applyDarkModeFilter as applyDarkModeFilter2,
2983
+ DEFAULT_STROKE_STREAMLINE
2628
2984
  } from "@excalidraw/common";
2629
2985
 
2630
2986
  // src/renderElement.ts
2631
2987
  init_define_import_meta_env();
2632
2988
  import {
2633
2989
  isRightAngleRads,
2634
- lineSegment as lineSegment6,
2635
- pointFrom as pointFrom12,
2636
- pointRotateRads as pointRotateRads11
2990
+ lineSegment as lineSegment5,
2991
+ pointFrom as pointFrom11,
2992
+ pointRotateRads as pointRotateRads10
2637
2993
  } from "@excalidraw/math";
2638
2994
  import {
2639
2995
  BOUND_TEXT_PADDING as BOUND_TEXT_PADDING3,
@@ -2664,7 +3020,7 @@ import {
2664
3020
  vectorAdd as vectorAdd2,
2665
3021
  vectorScale as vectorScale2,
2666
3022
  pointFromVector as pointFromVector2,
2667
- clamp,
3023
+ clamp as clamp2,
2668
3024
  isCloseTo
2669
3025
  } from "@excalidraw/math";
2670
3026
  var MINIMAL_CROP_SIZE = 10;
@@ -2698,7 +3054,7 @@ var cropElement = (element, elementsMap, transformHandle, naturalWidth, naturalH
2698
3054
  let changeInHeight = pointerY - element.y;
2699
3055
  let changeInWidth = pointerX - element.x;
2700
3056
  if (transformHandle.includes("n")) {
2701
- nextHeight = clamp(
3057
+ nextHeight = clamp2(
2702
3058
  element.height - changeInHeight,
2703
3059
  MINIMAL_CROP_SIZE,
2704
3060
  isFlippedByY ? uncroppedHeight - croppedTop : element.height + croppedTop
@@ -2706,7 +3062,7 @@ var cropElement = (element, elementsMap, transformHandle, naturalWidth, naturalH
2706
3062
  }
2707
3063
  if (transformHandle.includes("s")) {
2708
3064
  changeInHeight = pointerY - element.y - element.height;
2709
- nextHeight = clamp(
3065
+ nextHeight = clamp2(
2710
3066
  element.height + changeInHeight,
2711
3067
  MINIMAL_CROP_SIZE,
2712
3068
  isFlippedByY ? element.height + croppedTop : uncroppedHeight - croppedTop
@@ -2714,14 +3070,14 @@ var cropElement = (element, elementsMap, transformHandle, naturalWidth, naturalH
2714
3070
  }
2715
3071
  if (transformHandle.includes("e")) {
2716
3072
  changeInWidth = pointerX - element.x - element.width;
2717
- nextWidth = clamp(
3073
+ nextWidth = clamp2(
2718
3074
  element.width + changeInWidth,
2719
3075
  MINIMAL_CROP_SIZE,
2720
3076
  isFlippedByX ? element.width + croppedLeft : uncroppedWidth - croppedLeft
2721
3077
  );
2722
3078
  }
2723
3079
  if (transformHandle.includes("w")) {
2724
- nextWidth = clamp(
3080
+ nextWidth = clamp2(
2725
3081
  element.width - changeInWidth,
2726
3082
  MINIMAL_CROP_SIZE,
2727
3083
  isFlippedByX ? uncroppedWidth - croppedLeft : element.width + croppedLeft
@@ -2761,7 +3117,7 @@ var cropElement = (element, elementsMap, transformHandle, naturalWidth, naturalH
2761
3117
  const distanceToLeft = croppedLeft + element.width / 2;
2762
3118
  const distanceToRight = uncroppedWidth - croppedLeft - element.width / 2;
2763
3119
  const MAX_WIDTH = Math.min(distanceToLeft, distanceToRight) * 2;
2764
- nextWidth = clamp(
3120
+ nextWidth = clamp2(
2765
3121
  nextHeight * widthAspectRatio,
2766
3122
  MINIMAL_CROP_SIZE,
2767
3123
  MAX_WIDTH
@@ -2779,7 +3135,7 @@ var cropElement = (element, elementsMap, transformHandle, naturalWidth, naturalH
2779
3135
  const distanceToLeft = croppedLeft + element.width / 2;
2780
3136
  const distanceToRight = uncroppedWidth - croppedLeft - element.width / 2;
2781
3137
  const MAX_WIDTH = Math.min(distanceToLeft, distanceToRight) * 2;
2782
- nextWidth = clamp(
3138
+ nextWidth = clamp2(
2783
3139
  nextHeight * widthAspectRatio,
2784
3140
  MINIMAL_CROP_SIZE,
2785
3141
  MAX_WIDTH
@@ -2797,7 +3153,7 @@ var cropElement = (element, elementsMap, transformHandle, naturalWidth, naturalH
2797
3153
  const distanceToTop = croppedTop + element.height / 2;
2798
3154
  const distanceToBottom = uncroppedHeight - croppedTop - element.height / 2;
2799
3155
  const MAX_HEIGHT = Math.min(distanceToTop, distanceToBottom) * 2;
2800
- nextHeight = clamp(
3156
+ nextHeight = clamp2(
2801
3157
  nextWidth / widthAspectRatio,
2802
3158
  MINIMAL_CROP_SIZE,
2803
3159
  MAX_HEIGHT
@@ -2815,7 +3171,7 @@ var cropElement = (element, elementsMap, transformHandle, naturalWidth, naturalH
2815
3171
  const distanceToTop = croppedTop + element.height / 2;
2816
3172
  const distanceToBottom = uncroppedHeight - croppedTop - element.height / 2;
2817
3173
  const MAX_HEIGHT = Math.min(distanceToTop, distanceToBottom) * 2;
2818
- nextHeight = clamp(
3174
+ nextHeight = clamp2(
2819
3175
  nextWidth / widthAspectRatio,
2820
3176
  MINIMAL_CROP_SIZE,
2821
3177
  MAX_HEIGHT
@@ -2832,7 +3188,7 @@ var cropElement = (element, elementsMap, transformHandle, naturalWidth, naturalH
2832
3188
  if (widthAspectRatio) {
2833
3189
  if (changeInWidth > -changeInHeight) {
2834
3190
  const MAX_HEIGHT = isFlippedByY ? uncroppedHeight - croppedTop : croppedTop + element.height;
2835
- nextHeight = clamp(
3191
+ nextHeight = clamp2(
2836
3192
  nextWidth / widthAspectRatio,
2837
3193
  MINIMAL_CROP_SIZE,
2838
3194
  MAX_HEIGHT
@@ -2840,7 +3196,7 @@ var cropElement = (element, elementsMap, transformHandle, naturalWidth, naturalH
2840
3196
  nextWidth = nextHeight * widthAspectRatio;
2841
3197
  } else {
2842
3198
  const MAX_WIDTH = isFlippedByX ? croppedLeft + element.width : uncroppedWidth - croppedLeft;
2843
- nextWidth = clamp(
3199
+ nextWidth = clamp2(
2844
3200
  nextHeight * widthAspectRatio,
2845
3201
  MINIMAL_CROP_SIZE,
2846
3202
  MAX_WIDTH
@@ -2855,7 +3211,7 @@ var cropElement = (element, elementsMap, transformHandle, naturalWidth, naturalH
2855
3211
  if (widthAspectRatio) {
2856
3212
  if (changeInWidth < changeInHeight) {
2857
3213
  const MAX_HEIGHT = isFlippedByY ? uncroppedHeight - croppedTop : croppedTop + element.height;
2858
- nextHeight = clamp(
3214
+ nextHeight = clamp2(
2859
3215
  nextWidth / widthAspectRatio,
2860
3216
  MINIMAL_CROP_SIZE,
2861
3217
  MAX_HEIGHT
@@ -2863,7 +3219,7 @@ var cropElement = (element, elementsMap, transformHandle, naturalWidth, naturalH
2863
3219
  nextWidth = nextHeight * widthAspectRatio;
2864
3220
  } else {
2865
3221
  const MAX_WIDTH = isFlippedByX ? uncroppedWidth - croppedLeft : croppedLeft + element.width;
2866
- nextWidth = clamp(
3222
+ nextWidth = clamp2(
2867
3223
  nextHeight * widthAspectRatio,
2868
3224
  MINIMAL_CROP_SIZE,
2869
3225
  MAX_WIDTH
@@ -2878,7 +3234,7 @@ var cropElement = (element, elementsMap, transformHandle, naturalWidth, naturalH
2878
3234
  if (widthAspectRatio) {
2879
3235
  if (changeInWidth > changeInHeight) {
2880
3236
  const MAX_HEIGHT = isFlippedByY ? croppedTop + element.height : uncroppedHeight - croppedTop;
2881
- nextHeight = clamp(
3237
+ nextHeight = clamp2(
2882
3238
  nextWidth / widthAspectRatio,
2883
3239
  MINIMAL_CROP_SIZE,
2884
3240
  MAX_HEIGHT
@@ -2886,7 +3242,7 @@ var cropElement = (element, elementsMap, transformHandle, naturalWidth, naturalH
2886
3242
  nextWidth = nextHeight * widthAspectRatio;
2887
3243
  } else {
2888
3244
  const MAX_WIDTH = isFlippedByX ? croppedLeft + element.width : uncroppedWidth - croppedLeft;
2889
- nextWidth = clamp(
3245
+ nextWidth = clamp2(
2890
3246
  nextHeight * widthAspectRatio,
2891
3247
  MINIMAL_CROP_SIZE,
2892
3248
  MAX_WIDTH
@@ -2901,7 +3257,7 @@ var cropElement = (element, elementsMap, transformHandle, naturalWidth, naturalH
2901
3257
  if (widthAspectRatio) {
2902
3258
  if (-changeInWidth > changeInHeight) {
2903
3259
  const MAX_HEIGHT = isFlippedByY ? croppedTop + element.height : uncroppedHeight - croppedTop;
2904
- nextHeight = clamp(
3260
+ nextHeight = clamp2(
2905
3261
  nextWidth / widthAspectRatio,
2906
3262
  MINIMAL_CROP_SIZE,
2907
3263
  MAX_HEIGHT
@@ -2909,7 +3265,7 @@ var cropElement = (element, elementsMap, transformHandle, naturalWidth, naturalH
2909
3265
  nextWidth = nextHeight * widthAspectRatio;
2910
3266
  } else {
2911
3267
  const MAX_WIDTH = isFlippedByX ? uncroppedWidth - croppedLeft : croppedLeft + element.width;
2912
- nextWidth = clamp(
3268
+ nextWidth = clamp2(
2913
3269
  nextHeight * widthAspectRatio,
2914
3270
  MINIMAL_CROP_SIZE,
2915
3271
  MAX_WIDTH
@@ -2977,17 +3333,17 @@ var recomputeOrigin = (stateAtCropStart, transformHandle, width, height, shouldM
2977
3333
  newTopLeft[1] = startCenter[1] - newBoundsHeight / 2;
2978
3334
  }
2979
3335
  }
2980
- const angle = stateAtCropStart.angle;
2981
- const rotatedTopLeft = pointRotateRads2(newTopLeft, startCenter, angle);
3336
+ const angle2 = stateAtCropStart.angle;
3337
+ const rotatedTopLeft = pointRotateRads2(newTopLeft, startCenter, angle2);
2982
3338
  const newCenter = [
2983
3339
  newTopLeft[0] + Math.abs(newBoundsWidth) / 2,
2984
3340
  newTopLeft[1] + Math.abs(newBoundsHeight) / 2
2985
3341
  ];
2986
- const rotatedNewCenter = pointRotateRads2(newCenter, startCenter, angle);
3342
+ const rotatedNewCenter = pointRotateRads2(newCenter, startCenter, angle2);
2987
3343
  newTopLeft = pointRotateRads2(
2988
3344
  rotatedTopLeft,
2989
3345
  rotatedNewCenter,
2990
- -angle
3346
+ -angle2
2991
3347
  );
2992
3348
  const newOrigin = [...newTopLeft];
2993
3349
  newOrigin[0] += stateAtCropStart.x - newBoundsX1;
@@ -3149,7 +3505,7 @@ import {
3149
3505
  } from "@excalidraw/common";
3150
3506
  import {
3151
3507
  PRECISION as PRECISION2,
3152
- clamp as clamp3,
3508
+ clamp as clamp4,
3153
3509
  lineSegment as lineSegment4,
3154
3510
  pointDistance as pointDistance4,
3155
3511
  pointDistanceSq,
@@ -4695,8 +5051,8 @@ var computeBoundTextPosition = (container, boundTextElement, elementsMap) => {
4695
5051
  } else {
4696
5052
  x = containerCoords.x + (maxContainerWidth / 2 - boundTextElement.width / 2);
4697
5053
  }
4698
- const angle = container.angle ?? 0;
4699
- if (angle !== 0) {
5054
+ const angle2 = container.angle ?? 0;
5055
+ if (angle2 !== 0) {
4700
5056
  const contentCenter = pointFrom4(
4701
5057
  containerCoords.x + maxContainerWidth / 2,
4702
5058
  containerCoords.y + maxContainerHeight / 2
@@ -4705,7 +5061,7 @@ var computeBoundTextPosition = (container, boundTextElement, elementsMap) => {
4705
5061
  x + boundTextElement.width / 2,
4706
5062
  y + boundTextElement.height / 2
4707
5063
  );
4708
- const [rx, ry] = pointRotateRads4(textCenter, contentCenter, angle);
5064
+ const [rx, ry] = pointRotateRads4(textCenter, contentCenter, angle2);
4709
5065
  return {
4710
5066
  x: rx - boundTextElement.width / 2,
4711
5067
  y: ry - boundTextElement.height / 2
@@ -4722,7 +5078,13 @@ var getBoundTextElement = (element, elementsMap) => {
4722
5078
  }
4723
5079
  const boundTextElementId = getBoundTextElementId(element);
4724
5080
  if (boundTextElementId) {
4725
- return elementsMap.get(boundTextElementId) || null;
5081
+ const boundTextElement = elementsMap.get(boundTextElementId) || null;
5082
+ if (boundTextElement && !isNonDeletedElement(boundTextElement)) {
5083
+ console.error(
5084
+ "[NONDELETED][INVARIANT] Bound text element `isDeleted: true` which is not expected."
5085
+ );
5086
+ }
5087
+ return boundTextElement;
4726
5088
  }
4727
5089
  return null;
4728
5090
  };
@@ -4962,6 +5324,7 @@ var hasBackground = (type) => type === "rectangle" || type === "iframe" || type
4962
5324
  var hasStrokeColor = (type) => type === "rectangle" || type === "ellipse" || type === "diamond" || type === "freedraw" || type === "arrow" || type === "line" || type === "text" || type === "embeddable";
4963
5325
  var hasStrokeWidth = (type) => type === "rectangle" || type === "iframe" || type === "embeddable" || type === "ellipse" || type === "diamond" || type === "freedraw" || type === "arrow" || type === "line";
4964
5326
  var hasStrokeStyle = (type) => type === "rectangle" || type === "iframe" || type === "embeddable" || type === "ellipse" || type === "diamond" || type === "arrow" || type === "line";
5327
+ var hasFreedrawMode = (type) => type === "freedraw";
4965
5328
  var canChangeRoundness = (type) => type === "rectangle" || type === "iframe" || type === "embeddable" || type === "line" || type === "diamond" || type === "image";
4966
5329
  var toolIsArrow = (type) => type === "arrow";
4967
5330
  var canHaveArrowheads = (type) => type === "arrow";
@@ -5030,8 +5393,8 @@ var hitElementItself = ({
5030
5393
  cachedHit = result;
5031
5394
  return result;
5032
5395
  };
5033
- var isPointInRotatedBounds = (point, bounds, angle, tolerance = 0) => {
5034
- const adjustedPoint = angle === 0 ? point : pointRotateRads6(point, getCenterForBounds(bounds), -angle);
5396
+ var isPointInRotatedBounds = (point, bounds, angle2, tolerance = 0) => {
5397
+ const adjustedPoint = angle2 === 0 ? point : pointRotateRads6(point, getCenterForBounds(bounds), -angle2);
5035
5398
  return isPointWithinBounds(
5036
5399
  pointFrom5(bounds[0] - tolerance, bounds[1] - tolerance),
5037
5400
  adjustedPoint,
@@ -5207,7 +5570,7 @@ var intersectElementWithLineSegment = (element, elementsMap, line2, offset = 0,
5207
5570
  );
5208
5571
  }
5209
5572
  };
5210
- var curveIntersections = (curves, segment, intersections, center, angle, onlyFirst = false) => {
5573
+ var curveIntersections = (curves, segment, intersections, center, angle2, onlyFirst = false) => {
5211
5574
  for (const c of curves) {
5212
5575
  const b1 = getCubicBezierCurveBound(c[0], c[1], c[2], c[3]);
5213
5576
  const b2 = [
@@ -5222,7 +5585,7 @@ var curveIntersections = (curves, segment, intersections, center, angle, onlyFir
5222
5585
  const hits = curveIntersectLineSegment(c, segment);
5223
5586
  if (hits.length > 0) {
5224
5587
  for (const j of hits) {
5225
- intersections.push(pointRotateRads6(j, center, angle));
5588
+ intersections.push(pointRotateRads6(j, center, angle2));
5226
5589
  }
5227
5590
  if (onlyFirst) {
5228
5591
  return intersections;
@@ -5231,11 +5594,11 @@ var curveIntersections = (curves, segment, intersections, center, angle, onlyFir
5231
5594
  }
5232
5595
  return intersections;
5233
5596
  };
5234
- var lineIntersections = (lines, segment, intersections, center, angle, onlyFirst = false) => {
5597
+ var lineIntersections = (lines, segment, intersections, center, angle2, onlyFirst = false) => {
5235
5598
  for (const l2 of lines) {
5236
5599
  const intersection = lineSegmentIntersectionPoints2(l2, segment);
5237
5600
  if (intersection) {
5238
- intersections.push(pointRotateRads6(intersection, center, angle));
5601
+ intersections.push(pointRotateRads6(intersection, center, angle2));
5239
5602
  if (onlyFirst) {
5240
5603
  return intersections;
5241
5604
  }
@@ -5381,7 +5744,7 @@ var isPointInElement = (point, element, elementsMap) => {
5381
5744
  };
5382
5745
  var isBindableElementInsideOtherBindable = (innerElement, outerElement, elementsMap) => {
5383
5746
  const getCornerPoints = (element, offset2) => {
5384
- const { x, y, width, height, angle } = element;
5747
+ const { x, y, width, height, angle: angle2 } = element;
5385
5748
  const center = elementCenterPoint(element, elementsMap);
5386
5749
  if (element.type === "diamond") {
5387
5750
  const [topX, topY, rightX, rightY, bottomX, bottomY, leftX, leftY] = getDiamondPoints(element);
@@ -5395,7 +5758,7 @@ var isBindableElementInsideOtherBindable = (innerElement, outerElement, elements
5395
5758
  pointFrom5(x + leftX - offset2, y + leftY)
5396
5759
  // left
5397
5760
  ];
5398
- return corners2.map((corner) => pointRotateRads6(corner, center, angle));
5761
+ return corners2.map((corner) => pointRotateRads6(corner, center, angle2));
5399
5762
  }
5400
5763
  if (element.type === "ellipse") {
5401
5764
  const cx = x + width / 2;
@@ -5412,7 +5775,7 @@ var isBindableElementInsideOtherBindable = (innerElement, outerElement, elements
5412
5775
  pointFrom5(cx - rx - offset2, cy)
5413
5776
  // left
5414
5777
  ];
5415
- return corners2.map((corner) => pointRotateRads6(corner, center, angle));
5778
+ return corners2.map((corner) => pointRotateRads6(corner, center, angle2));
5416
5779
  }
5417
5780
  const corners = [
5418
5781
  pointFrom5(x - offset2, y - offset2),
@@ -5424,7 +5787,7 @@ var isBindableElementInsideOtherBindable = (innerElement, outerElement, elements
5424
5787
  pointFrom5(x - offset2, y + height + offset2)
5425
5788
  // bottom-left
5426
5789
  ];
5427
- return corners.map((corner) => pointRotateRads6(corner, center, angle));
5790
+ return corners.map((corner) => pointRotateRads6(corner, center, angle2));
5428
5791
  };
5429
5792
  const offset = -1 * Math.max(innerElement.width, innerElement.height) / 20;
5430
5793
  const innerCorners = getCornerPoints(innerElement, offset);
@@ -5650,7 +6013,7 @@ import {
5650
6013
  // src/elbowArrow.ts
5651
6014
  init_define_import_meta_env();
5652
6015
  import {
5653
- clamp as clamp2,
6016
+ clamp as clamp3,
5654
6017
  pointDistance as pointDistance3,
5655
6018
  pointFrom as pointFrom7,
5656
6019
  pointScaleFromOrigin as pointScaleFromOrigin2,
@@ -6994,12 +7357,12 @@ var normalizeArrowElementUpdate = (global2, nextFixedSegments, startIsSpecial, e
6994
7357
  );
6995
7358
  }
6996
7359
  points = points.map(
6997
- ([x, y]) => pointFrom7(clamp2(x, -1e6, 1e6), clamp2(y, -1e6, 1e6))
7360
+ ([x, y]) => pointFrom7(clamp3(x, -1e6, 1e6), clamp3(y, -1e6, 1e6))
6998
7361
  );
6999
7362
  return {
7000
7363
  points,
7001
- x: clamp2(offsetX, -1e6, 1e6),
7002
- y: clamp2(offsetY, -1e6, 1e6),
7364
+ x: clamp3(offsetX, -1e6, 1e6),
7365
+ y: clamp3(offsetY, -1e6, 1e6),
7003
7366
  fixedSegments: (nextFixedSegments?.length ?? 0) > 0 ? nextFixedSegments : null,
7004
7367
  ...getSizeFromPoints(points),
7005
7368
  startIsSpecial,
@@ -7205,13 +7568,14 @@ var BASE_BINDING_GAP = 5;
7205
7568
  var BASE_BINDING_GAP_ELBOW = 5;
7206
7569
  var BASE_ARROW_MIN_LENGTH = 10;
7207
7570
  var FOCUS_POINT_SIZE = 10 / 1.5;
7571
+ var MIN_BINDABLE_SIZE = 1;
7208
7572
  var getBindingGap = (bindTarget, opts) => {
7209
7573
  return (opts.elbowed ? BASE_BINDING_GAP_ELBOW : BASE_BINDING_GAP) + bindTarget.strokeWidth / 2;
7210
7574
  };
7211
7575
  var maxBindingDistance_simple = (zoom) => {
7212
7576
  const BASE_BINDING_DISTANCE = Math.max(BASE_BINDING_GAP, 15);
7213
7577
  const zoomValue = zoom?.value && zoom.value < 1 ? zoom.value : 1;
7214
- return clamp3(
7578
+ return clamp4(
7215
7579
  // reducing zoom impact so that the diff between binding distance and
7216
7580
  // binding gap is kept to minimum when possible
7217
7581
  BASE_BINDING_DISTANCE / (zoomValue * 1.5),
@@ -7438,7 +7802,9 @@ var bindingStrategyForSimpleArrowEndpointDragging_complex = (point, currentBindi
7438
7802
  const isOverlapping = oppositeBinding ? getAllHoveredElementAtPoint(point, elements, elementsMap).some(
7439
7803
  (el) => el.id === oppositeBinding.elementId
7440
7804
  ) : false;
7441
- const oppositeElement = oppositeBinding ? elementsMap.get(oppositeBinding.elementId) : null;
7805
+ const oppositeElement = oppositeBinding ? elementsMap.get(
7806
+ oppositeBinding.elementId
7807
+ ) : null;
7442
7808
  const otherIsTransparent = isOverlapping && oppositeElement ? isTransparent2(oppositeElement.backgroundColor) : false;
7443
7809
  const isNested = hit && oppositeElement && isBindableElementInsideOtherBindable(oppositeElement, hit, elementsMap);
7444
7810
  if (globalBindMode === "inside" || globalBindMode === "skip") {
@@ -7523,10 +7889,12 @@ var getBindingStrategyForDraggingBindingElementEndpoints_simple = (arrow, draggi
7523
7889
  const endDragged = draggingPoints.has(endIdx);
7524
7890
  let start = { mode: void 0 };
7525
7891
  let end = { mode: void 0 };
7526
- invariant7(
7527
- arrow.points.length > 1,
7528
- "Do not attempt to bind linear elements with a single point"
7529
- );
7892
+ if (arrow.points.length < 2) {
7893
+ console.error(
7894
+ "Attempting to bind a linear element with less than 2 points"
7895
+ );
7896
+ return { start: { mode: void 0 }, end: { mode: void 0 } };
7897
+ }
7530
7898
  if (!startDragged && !endDragged) {
7531
7899
  return { start, end };
7532
7900
  }
@@ -7687,10 +8055,12 @@ var getBindingStrategyForDraggingBindingElementEndpoints_complex = (arrow, dragg
7687
8055
  const endDragged = draggingPoints.has(endIdx);
7688
8056
  let start = { mode: void 0 };
7689
8057
  let end = { mode: void 0 };
7690
- invariant7(
7691
- arrow.points.length > 1,
7692
- "Do not attempt to bind linear elements with a single point"
7693
- );
8058
+ if (arrow.points.length < 2) {
8059
+ console.error(
8060
+ "Attempting to bind a linear element with less than 2 points"
8061
+ );
8062
+ return { start: { mode: void 0 }, end: { mode: void 0 } };
8063
+ }
7694
8064
  if (!startDragged && !endDragged) {
7695
8065
  return { start, end };
7696
8066
  }
@@ -7856,7 +8226,12 @@ var updateBoundElements = (changedElement, scene, options) => {
7856
8226
  });
7857
8227
  }
7858
8228
  const visitor = (element) => {
7859
- if (!isArrowElement(element) || element.isDeleted) {
8229
+ if (element && !isNonDeletedElement(element)) {
8230
+ console.error(
8231
+ "[NONDELETED][INVARIANT] updateBoundElements(): `isDeleted: true` in visitor"
8232
+ );
8233
+ }
8234
+ if (!isArrowElement(element) || !isNonDeletedElement(element)) {
7860
8235
  return;
7861
8236
  }
7862
8237
  if (!doesNeedUpdate(element, changedElement)) {
@@ -7910,7 +8285,9 @@ var updateArrowBindings = (latestElement, startOrEnd, elementsMap, scene, appSta
7910
8285
  "Elbow arrows not supported for indirect updates"
7911
8286
  );
7912
8287
  const binding = latestElement[startOrEnd];
7913
- const bindableElement = binding && elementsMap.get(binding.elementId);
8288
+ const bindableElement = binding && elementsMap.get(
8289
+ binding.elementId
8290
+ );
7914
8291
  const point = LinearElementEditor.getPointAtIndexGlobalCoordinates(
7915
8292
  latestElement,
7916
8293
  startOrEnd === "startBinding" ? 0 : -1,
@@ -8175,12 +8552,12 @@ var avoidRectangularCorner = (arrowElement, bindTarget, elementsMap, p) => {
8175
8552
  return p;
8176
8553
  };
8177
8554
  var snapToMid = (bindTarget, elementsMap, p, tolerance = 0.05, arrowElement) => {
8178
- const { x, y, width, height, angle } = bindTarget;
8555
+ const { x, y, width, height, angle: angle2 } = bindTarget;
8179
8556
  const center = elementCenterPoint(bindTarget, elementsMap, -0.1, -0.1);
8180
- const nonRotated = pointRotateRads8(p, center, -angle);
8557
+ const nonRotated = pointRotateRads8(p, center, -angle2);
8181
8558
  const bindingGap = arrowElement ? getBindingGap(bindTarget, arrowElement) : 0;
8182
- const verticalThreshold = clamp3(tolerance * height, 5, 80);
8183
- const horizontalThreshold = clamp3(tolerance * width, 5, 80);
8559
+ const verticalThreshold = clamp4(tolerance * height, 5, 80);
8560
+ const horizontalThreshold = clamp4(tolerance * width, 5, 80);
8184
8561
  if (pointDistance4(center, nonRotated) < bindingGap) {
8185
8562
  return void 0;
8186
8563
  }
@@ -8188,25 +8565,25 @@ var snapToMid = (bindTarget, elementsMap, p, tolerance = 0.05, arrowElement) =>
8188
8565
  return pointRotateRads8(
8189
8566
  pointFrom8(x - bindingGap, center[1]),
8190
8567
  center,
8191
- angle
8568
+ angle2
8192
8569
  );
8193
8570
  } else if (nonRotated[1] <= y + height / 2 && nonRotated[0] > center[0] - horizontalThreshold && nonRotated[0] < center[0] + horizontalThreshold) {
8194
8571
  return pointRotateRads8(
8195
8572
  pointFrom8(center[0], y - bindingGap),
8196
8573
  center,
8197
- angle
8574
+ angle2
8198
8575
  );
8199
8576
  } else if (nonRotated[0] >= x + width / 2 && nonRotated[1] > center[1] - verticalThreshold && nonRotated[1] < center[1] + verticalThreshold) {
8200
8577
  return pointRotateRads8(
8201
8578
  pointFrom8(x + width + bindingGap, center[1]),
8202
8579
  center,
8203
- angle
8580
+ angle2
8204
8581
  );
8205
8582
  } else if (nonRotated[1] >= y + height / 2 && nonRotated[0] > center[0] - horizontalThreshold && nonRotated[0] < center[0] + horizontalThreshold) {
8206
8583
  return pointRotateRads8(
8207
8584
  pointFrom8(center[0], y + height + bindingGap),
8208
8585
  center,
8209
- angle
8586
+ angle2
8210
8587
  );
8211
8588
  } else if (bindTarget.type === "diamond") {
8212
8589
  const distance3 = bindingGap;
@@ -8227,16 +8604,16 @@ var snapToMid = (bindTarget, elementsMap, p, tolerance = 0.05, arrowElement) =>
8227
8604
  y + 3 * height / 4 + distance3
8228
8605
  );
8229
8606
  if (pointDistance4(topLeft, nonRotated) < Math.max(horizontalThreshold, verticalThreshold)) {
8230
- return pointRotateRads8(topLeft, center, angle);
8607
+ return pointRotateRads8(topLeft, center, angle2);
8231
8608
  }
8232
8609
  if (pointDistance4(topRight, nonRotated) < Math.max(horizontalThreshold, verticalThreshold)) {
8233
- return pointRotateRads8(topRight, center, angle);
8610
+ return pointRotateRads8(topRight, center, angle2);
8234
8611
  }
8235
8612
  if (pointDistance4(bottomLeft, nonRotated) < Math.max(horizontalThreshold, verticalThreshold)) {
8236
- return pointRotateRads8(bottomLeft, center, angle);
8613
+ return pointRotateRads8(bottomLeft, center, angle2);
8237
8614
  }
8238
8615
  if (pointDistance4(bottomRight, nonRotated) < Math.max(horizontalThreshold, verticalThreshold)) {
8239
- return pointRotateRads8(bottomRight, center, angle);
8616
+ return pointRotateRads8(bottomRight, center, angle2);
8240
8617
  }
8241
8618
  }
8242
8619
  return void 0;
@@ -8394,10 +8771,14 @@ var calculateFixedPointForElbowArrowBinding = (linearElement, hoveredElement, st
8394
8771
  globalMidPoint,
8395
8772
  -hoveredElement.angle
8396
8773
  );
8774
+ if (hoveredElement.width < MIN_BINDABLE_SIZE || hoveredElement.height < MIN_BINDABLE_SIZE) {
8775
+ return { fixedPoint: normalizeFixedPoint([0.5, 0.5]) };
8776
+ }
8777
+ const sizeFloor = getBindingGap(hoveredElement, linearElement);
8397
8778
  return {
8398
8779
  fixedPoint: normalizeFixedPoint([
8399
- (nonRotatedSnappedGlobalPoint[0] - hoveredElement.x) / Math.max(hoveredElement.width, PRECISION2),
8400
- (nonRotatedSnappedGlobalPoint[1] - hoveredElement.y) / Math.max(hoveredElement.height, PRECISION2)
8780
+ (nonRotatedSnappedGlobalPoint[0] - hoveredElement.x) / Math.max(hoveredElement.width, sizeFloor),
8781
+ (nonRotatedSnappedGlobalPoint[1] - hoveredElement.y) / Math.max(hoveredElement.height, sizeFloor)
8401
8782
  ])
8402
8783
  };
8403
8784
  };
@@ -8413,8 +8794,12 @@ var calculateFixedPointForNonElbowArrowBinding = (linearElement, hoveredElement,
8413
8794
  elementCenter,
8414
8795
  -hoveredElement.angle
8415
8796
  );
8416
- const fixedPointX = (nonRotatedPoint[0] - hoveredElement.x) / Math.max(hoveredElement.width, PRECISION2);
8417
- const fixedPointY = (nonRotatedPoint[1] - hoveredElement.y) / Math.max(hoveredElement.height, PRECISION2);
8797
+ if (hoveredElement.width < MIN_BINDABLE_SIZE || hoveredElement.height < MIN_BINDABLE_SIZE) {
8798
+ return { fixedPoint: normalizeFixedPoint([0.5, 0.5]) };
8799
+ }
8800
+ const sizeFloor = getBindingGap(hoveredElement, linearElement);
8801
+ const fixedPointX = (nonRotatedPoint[0] - hoveredElement.x) / Math.max(hoveredElement.width, sizeFloor);
8802
+ const fixedPointY = (nonRotatedPoint[1] - hoveredElement.y) / Math.max(hoveredElement.height, sizeFloor);
8418
8803
  return {
8419
8804
  fixedPoint: normalizeFixedPoint([fixedPointX, fixedPointY])
8420
8805
  };
@@ -8739,17 +9124,21 @@ var getArrowLocalFixedPoints = (arrow, elementsMap) => {
8739
9124
  var isFixedPoint = (fixedPoint) => {
8740
9125
  return Array.isArray(fixedPoint) && fixedPoint.length === 2 && fixedPoint.every((coord) => Number.isFinite(coord));
8741
9126
  };
9127
+ var FIXED_POINT_BOUND = 10;
8742
9128
  var normalizeFixedPoint = (fixedPoint) => {
8743
9129
  if (!isFixedPoint(fixedPoint)) {
8744
9130
  return [0.5001, 0.5001];
8745
9131
  }
8746
- const EPSILON2 = 1e-4;
8747
- if (Math.abs(fixedPoint[0] - 0.5) < EPSILON2 || Math.abs(fixedPoint[1] - 0.5) < EPSILON2) {
8748
- return fixedPoint.map(
8749
- (ratio) => Math.abs(ratio - 0.5) < EPSILON2 ? 0.5001 : ratio
9132
+ const EPSILON = 1e-4;
9133
+ const clamped = fixedPoint.map(
9134
+ (ratio) => clamp4(ratio, -FIXED_POINT_BOUND, FIXED_POINT_BOUND)
9135
+ );
9136
+ if (Math.abs(clamped[0] - 0.5) < EPSILON || Math.abs(clamped[1] - 0.5) < EPSILON) {
9137
+ return clamped.map(
9138
+ (ratio) => Math.abs(ratio - 0.5) < EPSILON ? 0.5001 : ratio
8750
9139
  );
8751
9140
  }
8752
- return fixedPoint;
9141
+ return clamped;
8753
9142
  };
8754
9143
  var getShapeType = (element) => {
8755
9144
  if (element.type === "ellipse" || element.type === "diamond") {
@@ -8806,11 +9195,11 @@ var getShapeSideAdaptive = (fixedPoint, shapeType) => {
8806
9195
  const [x, y] = fixedPoint;
8807
9196
  const centerX = x - 0.5;
8808
9197
  const centerY = y - 0.5;
8809
- let angle = Math.atan2(centerY, centerX);
8810
- if (angle < 0) {
8811
- angle += 2 * Math.PI;
9198
+ let angle2 = Math.atan2(centerY, centerX);
9199
+ if (angle2 < 0) {
9200
+ angle2 += 2 * Math.PI;
8812
9201
  }
8813
- const degrees = angle * 180 / Math.PI;
9202
+ const degrees = angle2 * 180 / Math.PI;
8814
9203
  const config = SHAPE_CONFIGS[shapeType];
8815
9204
  const boundaries = getSectorBoundaries(config);
8816
9205
  for (const boundary of boundaries) {
@@ -8965,33 +9354,33 @@ var getBindingSideMidPoint = (binding, elementsMap) => {
8965
9354
  break;
8966
9355
  }
8967
9356
  case "top-right": {
8968
- const angle = -Math.PI / 4;
8969
- const ellipseX = radiusX * Math.cos(angle);
8970
- const ellipseY = radiusY * Math.sin(angle);
9357
+ const angle2 = -Math.PI / 4;
9358
+ const ellipseX = radiusX * Math.cos(angle2);
9359
+ const ellipseY = radiusY * Math.sin(angle2);
8971
9360
  x = ellipseCenterX + ellipseX + OFFSET * 0.707;
8972
9361
  y = ellipseCenterY + ellipseY - OFFSET * 0.707;
8973
9362
  break;
8974
9363
  }
8975
9364
  case "bottom-right": {
8976
- const angle = Math.PI / 4;
8977
- const ellipseX = radiusX * Math.cos(angle);
8978
- const ellipseY = radiusY * Math.sin(angle);
9365
+ const angle2 = Math.PI / 4;
9366
+ const ellipseX = radiusX * Math.cos(angle2);
9367
+ const ellipseY = radiusY * Math.sin(angle2);
8979
9368
  x = ellipseCenterX + ellipseX + OFFSET * 0.707;
8980
9369
  y = ellipseCenterY + ellipseY + OFFSET * 0.707;
8981
9370
  break;
8982
9371
  }
8983
9372
  case "bottom-left": {
8984
- const angle = 3 * Math.PI / 4;
8985
- const ellipseX = radiusX * Math.cos(angle);
8986
- const ellipseY = radiusY * Math.sin(angle);
9373
+ const angle2 = 3 * Math.PI / 4;
9374
+ const ellipseX = radiusX * Math.cos(angle2);
9375
+ const ellipseY = radiusY * Math.sin(angle2);
8987
9376
  x = ellipseCenterX + ellipseX - OFFSET * 0.707;
8988
9377
  y = ellipseCenterY + ellipseY + OFFSET * 0.707;
8989
9378
  break;
8990
9379
  }
8991
9380
  case "top-left": {
8992
- const angle = -3 * Math.PI / 4;
8993
- const ellipseX = radiusX * Math.cos(angle);
8994
- const ellipseY = radiusY * Math.sin(angle);
9381
+ const angle2 = -3 * Math.PI / 4;
9382
+ const ellipseX = radiusX * Math.cos(angle2);
9383
+ const ellipseY = radiusY * Math.sin(angle2);
8995
9384
  x = ellipseCenterX + ellipseX - OFFSET * 0.707;
8996
9385
  y = ellipseCenterY + ellipseY - OFFSET * 0.707;
8997
9386
  break;
@@ -10187,11 +10576,11 @@ var LinearElementEditor = class _LinearElementEditor {
10187
10576
  return false;
10188
10577
  }
10189
10578
  const origin = linearElementEditor.initialState.origin;
10190
- const dist = pointDistance5(
10579
+ const dist2 = pointDistance5(
10191
10580
  origin,
10192
10581
  pointFrom9(pointerCoords.x, pointerCoords.y)
10193
10582
  );
10194
- if (!appState.selectedLinearElement?.isEditing && dist < DRAGGING_THRESHOLD / appState.zoom.value) {
10583
+ if (!appState.selectedLinearElement?.isEditing && dist2 < DRAGGING_THRESHOLD / appState.zoom.value) {
10195
10584
  return false;
10196
10585
  }
10197
10586
  return true;
@@ -10757,52 +11146,15 @@ var determineCustomLinearAngle = (pivotPoint, draggedPoint) => Math.atan2(dragge
10757
11146
  // src/frame.ts
10758
11147
  init_define_import_meta_env();
10759
11148
  import { arrayToMap as arrayToMap5 } from "@excalidraw/common";
10760
- import { isPointWithinBounds as isPointWithinBounds2, pointFrom as pointFrom11 } from "@excalidraw/math";
10761
-
10762
- // ../utils/src/bbox.ts
10763
- init_define_import_meta_env();
10764
11149
  import {
10765
- vectorCross as vectorCross3,
10766
- vectorFromPoint as vectorFromPoint9
11150
+ isPointWithinBounds as isPointWithinBounds2,
11151
+ pointFrom as pointFrom10,
11152
+ segmentsIntersectAt as segmentsIntersectAt2
10767
11153
  } from "@excalidraw/math";
10768
- function getBBox(line2) {
10769
- return [
10770
- Math.min(line2[0][0], line2[1][0]),
10771
- Math.min(line2[0][1], line2[1][1]),
10772
- Math.max(line2[0][0], line2[1][0]),
10773
- Math.max(line2[0][1], line2[1][1])
10774
- ];
10775
- }
10776
- function doBBoxesIntersect(a2, b2) {
10777
- return a2[0] <= b2[2] && a2[2] >= b2[0] && a2[1] <= b2[3] && a2[3] >= b2[1];
10778
- }
10779
- var EPSILON = 1e-6;
10780
- function isPointOnLine(l2, p) {
10781
- const p1 = vectorFromPoint9(l2[1], l2[0]);
10782
- const p2 = vectorFromPoint9(p, l2[0]);
10783
- const r = vectorCross3(p1, p2);
10784
- return Math.abs(r) < EPSILON;
10785
- }
10786
- function isPointRightOfLine(l2, p) {
10787
- const p1 = vectorFromPoint9(l2[1], l2[0]);
10788
- const p2 = vectorFromPoint9(p, l2[0]);
10789
- return vectorCross3(p1, p2) < 0;
10790
- }
10791
- function isLineSegmentTouchingOrCrossingLine(a2, b2) {
10792
- return isPointOnLine(a2, b2[0]) || isPointOnLine(a2, b2[1]) || (isPointRightOfLine(a2, b2[0]) ? !isPointRightOfLine(a2, b2[1]) : isPointRightOfLine(a2, b2[1]));
10793
- }
10794
- function doLineSegmentsIntersect(a2, b2) {
10795
- return doBBoxesIntersect(getBBox(a2), getBBox(b2)) && isLineSegmentTouchingOrCrossingLine(a2, b2) && isLineSegmentTouchingOrCrossingLine(b2, a2);
10796
- }
10797
11154
 
10798
11155
  // src/selection.ts
10799
11156
  init_define_import_meta_env();
10800
11157
  import { arrayToMap as arrayToMap3, isShallowEqual as isShallowEqual2 } from "@excalidraw/common";
10801
- import {
10802
- lineSegment as lineSegment5,
10803
- pointFrom as pointFrom10,
10804
- pointRotateRads as pointRotateRads10
10805
- } from "@excalidraw/math";
10806
11158
 
10807
11159
  // src/groups.ts
10808
11160
  init_define_import_meta_env();
@@ -11074,7 +11426,9 @@ var getSelectedElementsByGroup = (selectedElements, elementsMap, appState) => {
11074
11426
  addToGroupsMap(element, selectedGroupId);
11075
11427
  }
11076
11428
  });
11077
- return Array.from(groups.values()).concat(Array.from(elements.values()));
11429
+ return Array.from(groups.values()).concat(
11430
+ Array.from(elements.values())
11431
+ );
11078
11432
  };
11079
11433
 
11080
11434
  // src/selection.ts
@@ -11108,248 +11462,71 @@ var getElementsWithinSelection = (elements, selection, elementsMap, excludeEleme
11108
11462
  selectionX2,
11109
11463
  selectionY2
11110
11464
  ];
11111
- const selectionEdges = [
11112
- lineSegment5(
11113
- pointFrom10(selectionX1, selectionY1),
11114
- pointFrom10(selectionX2, selectionY1)
11115
- ),
11116
- lineSegment5(
11117
- pointFrom10(selectionX2, selectionY1),
11118
- pointFrom10(selectionX2, selectionY2)
11119
- ),
11120
- lineSegment5(
11121
- pointFrom10(selectionX2, selectionY2),
11122
- pointFrom10(selectionX1, selectionY2)
11123
- ),
11124
- lineSegment5(
11125
- pointFrom10(selectionX1, selectionY2),
11126
- pointFrom10(selectionX1, selectionY1)
11127
- )
11128
- ];
11129
- const framesInSelection = excludeElementsInFrames ? /* @__PURE__ */ new Set() : null;
11130
- const groups = {};
11131
- const elementsInSelection = /* @__PURE__ */ new Set();
11132
- for (const element of elements) {
11133
- if (shouldIgnoreElementFromSelection(element)) {
11134
- continue;
11465
+ return elementsOverlappingBBox({
11466
+ elements,
11467
+ bounds: selectionBounds,
11468
+ elementsMap,
11469
+ type: boxSelectionMode,
11470
+ shouldIgnoreElementFromSelection,
11471
+ excludeElementsInFrames
11472
+ });
11473
+ };
11474
+ var getVisibleAndNonSelectedElements = (elements, selectedElements, appState, elementsMap) => {
11475
+ const selectedElementsSet = new Set(
11476
+ selectedElements.map((element) => element.id)
11477
+ );
11478
+ return elements.filter((element) => {
11479
+ const isVisible = isElementInViewport(
11480
+ element,
11481
+ appState.width,
11482
+ appState.height,
11483
+ appState,
11484
+ elementsMap
11485
+ );
11486
+ return !selectedElementsSet.has(element.id) && isVisible;
11487
+ });
11488
+ };
11489
+ var isSomeElementSelected = function() {
11490
+ let lastElements = null;
11491
+ let lastSelectedElementIds = null;
11492
+ let isSelected = null;
11493
+ const ret = (elements, appState) => {
11494
+ if (isSelected != null && elements === lastElements && appState.selectedElementIds === lastSelectedElementIds) {
11495
+ return isSelected;
11135
11496
  }
11136
- const groupId = element.groupIds.at(-1);
11137
- if (groupId) {
11138
- if (!groups[groupId]) {
11139
- groups[groupId] = [];
11497
+ isSelected = elements.some(
11498
+ (element) => appState.selectedElementIds[element.id]
11499
+ );
11500
+ lastElements = elements;
11501
+ lastSelectedElementIds = appState.selectedElementIds;
11502
+ return isSelected;
11503
+ };
11504
+ ret.clearCache = () => {
11505
+ lastElements = null;
11506
+ lastSelectedElementIds = null;
11507
+ isSelected = null;
11508
+ };
11509
+ return ret;
11510
+ }();
11511
+ var getSelectedElements = (elements, appState, opts) => {
11512
+ const addedElements = /* @__PURE__ */ new Set();
11513
+ const selectedElements = [];
11514
+ for (const element of elements.values()) {
11515
+ if (appState.selectedElementIds[element.id]) {
11516
+ if (isNonDeletedElement(element)) {
11517
+ selectedElements.push(element);
11518
+ addedElements.add(element.id);
11519
+ } else {
11520
+ console.error(
11521
+ "[NONDELETED][INVARIANT] getSelectedElements skipping deleted selected element which should not be in the selection"
11522
+ );
11140
11523
  }
11141
- groups[groupId].push(element);
11524
+ continue;
11142
11525
  }
11143
- const strokeWidth = element.strokeWidth;
11144
- let labelAABB = null;
11145
- let elementAABB = getElementBounds(element, elementsMap);
11146
- elementAABB = [
11147
- elementAABB[0] - strokeWidth / 2,
11148
- elementAABB[1] - strokeWidth / 2,
11149
- elementAABB[2] + strokeWidth / 2,
11150
- elementAABB[3] + strokeWidth / 2
11151
- ];
11152
- const boundTextElement = isArrowElement(element) && getBoundTextElement(element, elementsMap);
11153
- if (boundTextElement) {
11154
- const { x, y } = LinearElementEditor.getBoundTextElementPosition(
11155
- element,
11156
- boundTextElement,
11157
- elementsMap
11158
- );
11159
- labelAABB = [
11160
- x,
11161
- y,
11162
- x + boundTextElement.width,
11163
- y + boundTextElement.height
11164
- ];
11165
- }
11166
- const associatedFrame = getContainingFrame(element, elementsMap);
11167
- if (associatedFrame && elementOverlapsWithFrame(element, associatedFrame, elementsMap)) {
11168
- const frameAABB = getElementBounds(associatedFrame, elementsMap);
11169
- elementAABB = [
11170
- Math.max(elementAABB[0], frameAABB[0]),
11171
- Math.max(elementAABB[1], frameAABB[1]),
11172
- Math.min(elementAABB[2], frameAABB[2]),
11173
- Math.min(elementAABB[3], frameAABB[3])
11174
- ];
11175
- labelAABB = labelAABB ? [
11176
- Math.max(labelAABB[0], frameAABB[0]),
11177
- Math.max(labelAABB[1], frameAABB[1]),
11178
- Math.min(labelAABB[2], frameAABB[2]),
11179
- Math.min(labelAABB[3], frameAABB[3])
11180
- ] : null;
11181
- }
11182
- const commonAABB2 = labelAABB ? [
11183
- Math.min(labelAABB[0], elementAABB[0]),
11184
- Math.min(labelAABB[1], elementAABB[1]),
11185
- Math.max(labelAABB[2], elementAABB[2]),
11186
- Math.max(labelAABB[3], elementAABB[3])
11187
- ] : elementAABB;
11188
- if (boundsContainBounds(selectionBounds, commonAABB2)) {
11189
- if (framesInSelection && isFrameLikeElement(element)) {
11190
- framesInSelection.add(element.id);
11191
- }
11192
- elementsInSelection.add(element);
11193
- continue;
11194
- }
11195
- if (boxSelectionMode === "overlap" && labelAABB && doBoundsIntersect(selectionBounds, labelAABB)) {
11196
- elementsInSelection.add(element);
11197
- continue;
11198
- }
11199
- if (boxSelectionMode === "overlap" && doBoundsIntersect(selectionBounds, elementAABB)) {
11200
- let hasIntersection = false;
11201
- if (isLinearElement(element) || isFreeDrawElement(element)) {
11202
- const center = elementCenterPoint(element, elementsMap);
11203
- hasIntersection = element.points.some((point) => {
11204
- const rotatedPoint = pointRotateRads10(
11205
- pointFrom10(element.x + point[0], element.y + point[1]),
11206
- center,
11207
- element.angle
11208
- );
11209
- return pointInsideBounds(rotatedPoint, selectionBounds);
11210
- });
11211
- } else {
11212
- const nonRotatedElementBounds = getElementBounds(
11213
- element,
11214
- elementsMap,
11215
- true
11216
- );
11217
- const center = elementCenterPoint(element, elementsMap);
11218
- hasIntersection = [
11219
- pointRotateRads10(
11220
- pointFrom10(
11221
- (nonRotatedElementBounds[0] + nonRotatedElementBounds[2]) / 2,
11222
- nonRotatedElementBounds[1]
11223
- ),
11224
- center,
11225
- element.angle
11226
- ),
11227
- pointRotateRads10(
11228
- pointFrom10(
11229
- nonRotatedElementBounds[2],
11230
- (nonRotatedElementBounds[1] + nonRotatedElementBounds[3]) / 2
11231
- ),
11232
- center,
11233
- element.angle
11234
- ),
11235
- pointRotateRads10(
11236
- pointFrom10(
11237
- (nonRotatedElementBounds[0] + nonRotatedElementBounds[2]) / 2,
11238
- nonRotatedElementBounds[3]
11239
- ),
11240
- center,
11241
- element.angle
11242
- ),
11243
- pointRotateRads10(
11244
- pointFrom10(
11245
- nonRotatedElementBounds[0],
11246
- (nonRotatedElementBounds[1] + nonRotatedElementBounds[3]) / 2
11247
- ),
11248
- center,
11249
- element.angle
11250
- )
11251
- ].some((point) => {
11252
- return pointInsideBounds(
11253
- pointRotateRads10(point, center, element.angle),
11254
- selectionBounds
11255
- );
11256
- });
11257
- }
11258
- if (!hasIntersection) {
11259
- hasIntersection = selectionEdges.some(
11260
- (selectionEdge) => intersectElementWithLineSegment(
11261
- element,
11262
- elementsMap,
11263
- selectionEdge,
11264
- strokeWidth / 2,
11265
- true
11266
- // Stop at first hit for better performance
11267
- ).length > 0
11268
- );
11269
- }
11270
- if (hasIntersection) {
11271
- if (framesInSelection && isFrameLikeElement(element)) {
11272
- framesInSelection.add(element.id);
11273
- }
11274
- elementsInSelection.add(element);
11275
- continue;
11276
- }
11277
- }
11278
- }
11279
- if (framesInSelection) {
11280
- elementsInSelection.forEach((element) => {
11281
- if (element.frameId && framesInSelection.has(element.frameId)) {
11282
- elementsInSelection.delete(element);
11283
- }
11284
- });
11285
- }
11286
- if (boxSelectionMode === "overlap") {
11287
- Array.from(elementsInSelection).forEach((element) => {
11288
- const groupId = element.groupIds.at(-1);
11289
- const group = groupId ? groups[groupId] : null;
11290
- group?.forEach((groupElement) => elementsInSelection.add(groupElement));
11291
- });
11292
- } else if (boxSelectionMode === "contain") {
11293
- elementsInSelection.forEach((element) => {
11294
- const groupId = element.groupIds.at(-1);
11295
- const group = groupId ? groups[groupId] : null;
11296
- if (group && !group.every((groupElement) => elementsInSelection.has(groupElement))) {
11297
- elementsInSelection.delete(element);
11298
- }
11299
- });
11300
- }
11301
- return elements.filter((element) => elementsInSelection.has(element));
11302
- };
11303
- var getVisibleAndNonSelectedElements = (elements, selectedElements, appState, elementsMap) => {
11304
- const selectedElementsSet = new Set(
11305
- selectedElements.map((element) => element.id)
11306
- );
11307
- return elements.filter((element) => {
11308
- const isVisible = isElementInViewport(
11309
- element,
11310
- appState.width,
11311
- appState.height,
11312
- appState,
11313
- elementsMap
11314
- );
11315
- return !selectedElementsSet.has(element.id) && isVisible;
11316
- });
11317
- };
11318
- var isSomeElementSelected = function() {
11319
- let lastElements = null;
11320
- let lastSelectedElementIds = null;
11321
- let isSelected = null;
11322
- const ret = (elements, appState) => {
11323
- if (isSelected != null && elements === lastElements && appState.selectedElementIds === lastSelectedElementIds) {
11324
- return isSelected;
11325
- }
11326
- isSelected = elements.some(
11327
- (element) => appState.selectedElementIds[element.id]
11328
- );
11329
- lastElements = elements;
11330
- lastSelectedElementIds = appState.selectedElementIds;
11331
- return isSelected;
11332
- };
11333
- ret.clearCache = () => {
11334
- lastElements = null;
11335
- lastSelectedElementIds = null;
11336
- isSelected = null;
11337
- };
11338
- return ret;
11339
- }();
11340
- var getSelectedElements = (elements, appState, opts) => {
11341
- const addedElements = /* @__PURE__ */ new Set();
11342
- const selectedElements = [];
11343
- for (const element of elements.values()) {
11344
- if (appState.selectedElementIds[element.id]) {
11345
- selectedElements.push(element);
11346
- addedElements.add(element.id);
11347
- continue;
11348
- }
11349
- if (opts?.includeBoundTextElement && isBoundToContainer(element) && appState.selectedElementIds[element?.containerId]) {
11350
- selectedElements.push(element);
11351
- addedElements.add(element.id);
11352
- continue;
11526
+ if (opts?.includeBoundTextElement && isBoundToContainer(element) && appState.selectedElementIds[element?.containerId]) {
11527
+ selectedElements.push(element);
11528
+ addedElements.add(element.id);
11529
+ continue;
11353
11530
  }
11354
11531
  }
11355
11532
  if (opts?.includeElementsInFrames) {
@@ -11686,7 +11863,7 @@ function isElementIntersectingFrame(element, frame, elementsMap) {
11686
11863
  const elementLineSegments = getElementLineSegments(element, elementsMap);
11687
11864
  const intersecting = frameLineSegments.some(
11688
11865
  (frameLineSegment) => elementLineSegments.some(
11689
- (elementLineSegment) => doLineSegmentsIntersect(frameLineSegment, elementLineSegment)
11866
+ (elementLineSegment) => segmentsIntersectAt2(frameLineSegment, elementLineSegment)
11690
11867
  )
11691
11868
  );
11692
11869
  return intersecting;
@@ -11722,9 +11899,9 @@ var elementOverlapsWithFrame = (element, frame, elementsMap) => {
11722
11899
  var isCursorInFrame = (cursorCoords, frame, elementsMap) => {
11723
11900
  const [fx1, fy1, fx2, fy2] = getElementAbsoluteCoords2(frame, elementsMap);
11724
11901
  return isPointWithinBounds2(
11725
- pointFrom11(fx1, fy1),
11726
- pointFrom11(cursorCoords.x, cursorCoords.y),
11727
- pointFrom11(fx2, fy2)
11902
+ pointFrom10(fx1, fy1),
11903
+ pointFrom10(cursorCoords.x, cursorCoords.y),
11904
+ pointFrom10(fx2, fy2)
11728
11905
  );
11729
11906
  };
11730
11907
  var groupsAreAtLeastIntersectingTheFrame = (elements, groupIds, frame) => {
@@ -11831,8 +12008,11 @@ var getElementsInResizingFrame = (allElements, frame, appState, elementsMap) =>
11831
12008
  const newGroupElementsCompletelyInFrame = Array.from(
11832
12009
  elementsCompletelyInFrame
11833
12010
  ).filter((element) => element.groupIds.length > 0);
12011
+ const nonDeletedNewGroupElementsCompletelyInFrame = getNonDeletedElements(
12012
+ newGroupElementsCompletelyInFrame
12013
+ );
11834
12014
  const groupIds = selectGroupsFromGivenElements(
11835
- newGroupElementsCompletelyInFrame,
12015
+ nonDeletedNewGroupElementsCompletelyInFrame,
11836
12016
  appState
11837
12017
  );
11838
12018
  for (const [id, isSelected] of Object.entries(groupIds)) {
@@ -11974,9 +12154,6 @@ var addElementsToFrame = (allElements, elementsToAdd, frame) => {
11974
12154
  if (isFrameLikeElement(element) || element.frameId && otherFrames.has(element.frameId)) {
11975
12155
  continue;
11976
12156
  }
11977
- if (element.frameId && element.frameId !== frame.id) {
11978
- continue;
11979
- }
11980
12157
  finalElementsToAdd.add(element);
11981
12158
  const boundTextElement = getBoundTextElement(element, elementsMap);
11982
12159
  if (boundTextElement && !finalElementsToAdd.has(boundTextElement)) {
@@ -12303,43 +12480,6 @@ var generateElementCanvas = (element, elementsMap, zoom, renderConfig, appState)
12303
12480
  const rc = rough_default.canvas(canvas);
12304
12481
  drawElementOnCanvas(element, rc, context, renderConfig);
12305
12482
  context.restore();
12306
- const boundTextElement = getBoundTextElement(element, elementsMap);
12307
- const boundTextCanvas = document.createElement("canvas");
12308
- const boundTextCanvasContext = boundTextCanvas.getContext("2d");
12309
- if (isArrowElement(element) && boundTextElement) {
12310
- const [x1, y1, x2, y2] = getElementAbsoluteCoords2(element, elementsMap);
12311
- const maxDim = Math.max(distance2(x1, x2), distance2(y1, y2));
12312
- boundTextCanvas.width = maxDim * window.devicePixelRatio * scale + padding * scale * 10;
12313
- boundTextCanvas.height = maxDim * window.devicePixelRatio * scale + padding * scale * 10;
12314
- boundTextCanvasContext.translate(
12315
- boundTextCanvas.width / 2,
12316
- boundTextCanvas.height / 2
12317
- );
12318
- boundTextCanvasContext.rotate(element.angle);
12319
- boundTextCanvasContext.drawImage(
12320
- canvas,
12321
- -canvas.width / 2,
12322
- -canvas.height / 2,
12323
- canvas.width,
12324
- canvas.height
12325
- );
12326
- const [, , , , boundTextCx, boundTextCy] = getElementAbsoluteCoords2(
12327
- boundTextElement,
12328
- elementsMap
12329
- );
12330
- boundTextCanvasContext.rotate(-element.angle);
12331
- const offsetX = (boundTextCanvas.width - canvas.width) / 2;
12332
- const offsetY = (boundTextCanvas.height - canvas.height) / 2;
12333
- const shiftX = boundTextCanvas.width / 2 - (boundTextCx - x1) * window.devicePixelRatio * scale - offsetX - padding * scale;
12334
- const shiftY = boundTextCanvas.height / 2 - (boundTextCy - y1) * window.devicePixelRatio * scale - offsetY - padding * scale;
12335
- boundTextCanvasContext.translate(-shiftX, -shiftY);
12336
- boundTextCanvasContext.clearRect(
12337
- -(boundTextElement.width / 2 + BOUND_TEXT_PADDING3) * window.devicePixelRatio * scale,
12338
- -(boundTextElement.height / 2 + BOUND_TEXT_PADDING3) * window.devicePixelRatio * scale,
12339
- (boundTextElement.width + BOUND_TEXT_PADDING3 * 2) * window.devicePixelRatio * scale,
12340
- (boundTextElement.height + BOUND_TEXT_PADDING3 * 2) * window.devicePixelRatio * scale
12341
- );
12342
- }
12343
12483
  return {
12344
12484
  element,
12345
12485
  canvas,
@@ -12348,10 +12488,7 @@ var generateElementCanvas = (element, elementsMap, zoom, renderConfig, appState)
12348
12488
  zoomValue: zoom.value,
12349
12489
  canvasOffsetX,
12350
12490
  canvasOffsetY,
12351
- boundTextElementVersion: getBoundTextElement(element, elementsMap)?.version || null,
12352
12491
  containingFrameOpacity: getContainingFrame(element, elementsMap)?.opacity || 100,
12353
- boundTextCanvas,
12354
- angle: element.angle,
12355
12492
  imageCrop: isImageElement(element) ? element.crop : null
12356
12493
  };
12357
12494
  };
@@ -12408,7 +12545,10 @@ var drawElementOnCanvas = (element, rc, context, renderConfig) => {
12408
12545
  const shapes = ShapeCache.generateElementShape(element, renderConfig);
12409
12546
  for (const shape of shapes) {
12410
12547
  if (typeof shape === "string") {
12411
- context.fillStyle = renderConfig.theme === THEME.DARK ? applyDarkModeFilter(element.strokeColor) : element.strokeColor;
12548
+ context.fillStyle = applyDarkModeFilter(
12549
+ element.strokeColor,
12550
+ renderConfig.theme === THEME.DARK
12551
+ );
12412
12552
  context.fill(new Path2D(shape));
12413
12553
  } else {
12414
12554
  rc.draw(shape);
@@ -12516,7 +12656,10 @@ var drawElementOnCanvas = (element, rc, context, renderConfig) => {
12516
12656
  context.canvas.setAttribute("dir", rtl ? "rtl" : "ltr");
12517
12657
  context.save();
12518
12658
  context.font = getFontString3(element);
12519
- context.fillStyle = renderConfig.theme === THEME.DARK ? applyDarkModeFilter(element.strokeColor) : element.strokeColor;
12659
+ context.fillStyle = applyDarkModeFilter(
12660
+ element.strokeColor,
12661
+ renderConfig.theme === THEME.DARK
12662
+ );
12520
12663
  context.textAlign = element.textAlign;
12521
12664
  const lines = element.text.replace(/\r\n?/g, "\n").split("\n");
12522
12665
  const horizontalOffset = element.textAlign === "center" ? element.width / 2 : element.textAlign === "right" ? element.width : 0;
@@ -12553,15 +12696,9 @@ var generateElementWithCanvas = (element, elementsMap, renderConfig, appState) =
12553
12696
  };
12554
12697
  const prevElementWithCanvas = elementWithCanvasCache.get(element);
12555
12698
  const shouldRegenerateBecauseZoom = prevElementWithCanvas && prevElementWithCanvas.zoomValue !== zoom.value && !appState?.shouldCacheIgnoreZoom;
12556
- const boundTextElement = getBoundTextElement(element, elementsMap);
12557
- const boundTextElementVersion = boundTextElement?.version || null;
12558
12699
  const imageCrop = isImageElement(element) ? element.crop : null;
12559
12700
  const containingFrameOpacity = getContainingFrame(element, elementsMap)?.opacity || 100;
12560
- if (!prevElementWithCanvas || shouldRegenerateBecauseZoom || prevElementWithCanvas.theme !== appState.theme || prevElementWithCanvas.boundTextElementVersion !== boundTextElementVersion || prevElementWithCanvas.imageCrop !== imageCrop || prevElementWithCanvas.containingFrameOpacity !== containingFrameOpacity || // since we rotate the canvas when copying from cached canvas, we don't
12561
- // regenerate the cached canvas. But we need to in case of labels which are
12562
- // cached alongside the arrow, and we want the labels to remain unrotated
12563
- // with respect to the arrow.
12564
- isArrowElement(element) && boundTextElement && element.angle !== prevElementWithCanvas.angle) {
12701
+ if (!prevElementWithCanvas || shouldRegenerateBecauseZoom || prevElementWithCanvas.theme !== appState.theme || prevElementWithCanvas.imageCrop !== imageCrop || prevElementWithCanvas.containingFrameOpacity !== containingFrameOpacity) {
12565
12702
  const elementWithCanvas = generateElementCanvas(
12566
12703
  element,
12567
12704
  elementsMap,
@@ -12580,7 +12717,6 @@ var generateElementWithCanvas = (element, elementsMap, renderConfig, appState) =
12580
12717
  var drawElementFromCanvas = (elementWithCanvas, context, renderConfig, appState, allElementsMap) => {
12581
12718
  const element = elementWithCanvas.element;
12582
12719
  const padding = getCanvasPadding(element);
12583
- const zoom = elementWithCanvas.scale;
12584
12720
  const [x1, y1, x2, y2] = getElementAbsoluteCoords2(element, allElementsMap);
12585
12721
  const cx = ((x1 + x2) / 2 + appState.scrollX) * window.devicePixelRatio;
12586
12722
  const cy = ((y1 + y2) / 2 + appState.scrollY) * window.devicePixelRatio;
@@ -12588,48 +12724,51 @@ var drawElementFromCanvas = (elementWithCanvas, context, renderConfig, appState,
12588
12724
  context.scale(1 / window.devicePixelRatio, 1 / window.devicePixelRatio);
12589
12725
  const boundTextElement = getBoundTextElement(element, allElementsMap);
12590
12726
  if (isArrowElement(element) && boundTextElement) {
12591
- const offsetX = (elementWithCanvas.boundTextCanvas.width - elementWithCanvas.canvas.width) / 2;
12592
- const offsetY = (elementWithCanvas.boundTextCanvas.height - elementWithCanvas.canvas.height) / 2;
12593
- context.translate(cx, cy);
12594
- context.drawImage(
12595
- elementWithCanvas.boundTextCanvas,
12596
- -(x2 - x1) / 2 * window.devicePixelRatio - offsetX / zoom - padding,
12597
- -(y2 - y1) / 2 * window.devicePixelRatio - offsetY / zoom - padding,
12598
- elementWithCanvas.boundTextCanvas.width / zoom,
12599
- elementWithCanvas.boundTextCanvas.height / zoom
12727
+ const [, , , , boundTextCx, boundTextCy] = getElementAbsoluteCoords2(
12728
+ boundTextElement,
12729
+ allElementsMap
12600
12730
  );
12601
- } else {
12602
- context.translate(cx, cy);
12603
- context.rotate(element.angle);
12604
- if ("scale" in elementWithCanvas.element && !isPendingImageElement(element, renderConfig)) {
12605
- context.scale(
12606
- elementWithCanvas.element.scale[0],
12607
- elementWithCanvas.element.scale[1]
12608
- );
12609
- }
12610
- context.translate(-cx, -cy);
12611
- context.drawImage(
12612
- elementWithCanvas.canvas,
12613
- (x1 + appState.scrollX) * window.devicePixelRatio - padding * elementWithCanvas.scale / elementWithCanvas.scale,
12614
- (y1 + appState.scrollY) * window.devicePixelRatio - padding * elementWithCanvas.scale / elementWithCanvas.scale,
12615
- elementWithCanvas.canvas.width / elementWithCanvas.scale,
12616
- elementWithCanvas.canvas.height / elementWithCanvas.scale
12731
+ const outerHalf = Math.max(distance2(x1, x2), distance2(y1, y2)) * window.devicePixelRatio + padding * 10;
12732
+ context.beginPath();
12733
+ context.rect(cx - outerHalf, cy - outerHalf, outerHalf * 2, outerHalf * 2);
12734
+ context.rect(
12735
+ (boundTextCx - boundTextElement.width / 2 - BOUND_TEXT_PADDING3 + appState.scrollX) * window.devicePixelRatio,
12736
+ (boundTextCy - boundTextElement.height / 2 - BOUND_TEXT_PADDING3 + appState.scrollY) * window.devicePixelRatio,
12737
+ (boundTextElement.width + BOUND_TEXT_PADDING3 * 2) * window.devicePixelRatio,
12738
+ (boundTextElement.height + BOUND_TEXT_PADDING3 * 2) * window.devicePixelRatio
12739
+ );
12740
+ context.clip("evenodd");
12741
+ }
12742
+ context.translate(cx, cy);
12743
+ context.rotate(element.angle);
12744
+ if ("scale" in elementWithCanvas.element && !isPendingImageElement(element, renderConfig)) {
12745
+ context.scale(
12746
+ elementWithCanvas.element.scale[0],
12747
+ elementWithCanvas.element.scale[1]
12748
+ );
12749
+ }
12750
+ context.translate(-cx, -cy);
12751
+ context.drawImage(
12752
+ elementWithCanvas.canvas,
12753
+ (x1 + appState.scrollX) * window.devicePixelRatio - padding * elementWithCanvas.scale / elementWithCanvas.scale,
12754
+ (y1 + appState.scrollY) * window.devicePixelRatio - padding * elementWithCanvas.scale / elementWithCanvas.scale,
12755
+ elementWithCanvas.canvas.width / elementWithCanvas.scale,
12756
+ elementWithCanvas.canvas.height / elementWithCanvas.scale
12757
+ );
12758
+ if (define_import_meta_env_default.VITE_APP_DEBUG_ENABLE_TEXT_CONTAINER_BOUNDING_BOX === "true" && hasBoundTextElement(element)) {
12759
+ const textElement = getBoundTextElement(
12760
+ element,
12761
+ allElementsMap
12762
+ );
12763
+ const coords = getContainerCoords(element);
12764
+ context.strokeStyle = "#c92a2a";
12765
+ context.lineWidth = 3;
12766
+ context.strokeRect(
12767
+ (coords.x + appState.scrollX) * window.devicePixelRatio,
12768
+ (coords.y + appState.scrollY) * window.devicePixelRatio,
12769
+ getBoundTextMaxWidth(element, textElement) * window.devicePixelRatio,
12770
+ getBoundTextMaxHeight(element, textElement) * window.devicePixelRatio
12617
12771
  );
12618
- if (define_import_meta_env_default.VITE_APP_DEBUG_ENABLE_TEXT_CONTAINER_BOUNDING_BOX === "true" && hasBoundTextElement(element)) {
12619
- const textElement = getBoundTextElement(
12620
- element,
12621
- allElementsMap
12622
- );
12623
- const coords = getContainerCoords(element);
12624
- context.strokeStyle = "#c92a2a";
12625
- context.lineWidth = 3;
12626
- context.strokeRect(
12627
- (coords.x + appState.scrollX) * window.devicePixelRatio,
12628
- (coords.y + appState.scrollY) * window.devicePixelRatio,
12629
- getBoundTextMaxWidth(element, textElement) * window.devicePixelRatio,
12630
- getBoundTextMaxHeight(element, textElement) * window.devicePixelRatio
12631
- );
12632
- }
12633
12772
  }
12634
12773
  context.restore();
12635
12774
  };
@@ -12664,7 +12803,10 @@ var renderElement = (element, elementsMap, allElementsMap, rc, context, renderCo
12664
12803
  );
12665
12804
  context.fillStyle = "rgba(0, 0, 200, 0.04)";
12666
12805
  context.lineWidth = FRAME_STYLE.strokeWidth / appState.zoom.value;
12667
- context.strokeStyle = appState.theme === THEME.DARK ? applyDarkModeFilter(FRAME_STYLE.strokeColor) : FRAME_STYLE.strokeColor;
12806
+ context.strokeStyle = applyDarkModeFilter(
12807
+ FRAME_STYLE.strokeColor,
12808
+ appState.theme === THEME.DARK
12809
+ );
12668
12810
  if (isMagicFrameElement(element)) {
12669
12811
  context.strokeStyle = appState.theme === THEME.LIGHT ? "#7affd7" : applyDarkModeFilter("#1d8264");
12670
12812
  }
@@ -12730,8 +12872,10 @@ var renderElement = (element, elementsMap, allElementsMap, rc, context, renderCo
12730
12872
  case "embeddable": {
12731
12873
  if (renderConfig.isExporting) {
12732
12874
  const [x1, y1, x2, y2] = getElementAbsoluteCoords2(element, elementsMap);
12733
- const cx = (x1 + x2) / 2 + appState.scrollX;
12734
- const cy = (y1 + y2) / 2 + appState.scrollY;
12875
+ const centerX = (x1 + x2) / 2;
12876
+ const centerY = (y1 + y2) / 2;
12877
+ const cx = centerX + appState.scrollX;
12878
+ const cy = centerY + appState.scrollY;
12735
12879
  let shiftX = (x2 - x1) / 2 - (element.x - x1);
12736
12880
  let shiftY = (y2 - y1) / 2 - (element.y - y1);
12737
12881
  if (isTextElement(element)) {
@@ -12750,46 +12894,26 @@ var renderElement = (element, elementsMap, allElementsMap, rc, context, renderCo
12750
12894
  context.translate(cx, cy);
12751
12895
  const boundTextElement = getBoundTextElement(element, elementsMap);
12752
12896
  if (isArrowElement(element) && boundTextElement) {
12753
- const tempCanvas = document.createElement("canvas");
12754
- const tempCanvasContext = tempCanvas.getContext("2d");
12755
- const maxDim = Math.max(distance2(x1, x2), distance2(y1, y2));
12756
- const padding = getCanvasPadding(element);
12757
- tempCanvas.width = maxDim * appState.exportScale + padding * 10 * appState.exportScale;
12758
- tempCanvas.height = maxDim * appState.exportScale + padding * 10 * appState.exportScale;
12759
- tempCanvasContext.translate(
12760
- tempCanvas.width / 2,
12761
- tempCanvas.height / 2
12762
- );
12763
- tempCanvasContext.scale(appState.exportScale, appState.exportScale);
12764
12897
  shiftX = element.width / 2 - (element.x - x1);
12765
12898
  shiftY = element.height / 2 - (element.y - y1);
12766
- tempCanvasContext.rotate(element.angle);
12767
- const tempRc = rough_default.canvas(tempCanvas);
12768
- tempCanvasContext.translate(-shiftX, -shiftY);
12769
- drawElementOnCanvas(element, tempRc, tempCanvasContext, renderConfig);
12770
- tempCanvasContext.translate(shiftX, shiftY);
12771
- tempCanvasContext.rotate(-element.angle);
12772
12899
  const [, , , , boundTextCx, boundTextCy] = getElementAbsoluteCoords2(
12773
12900
  boundTextElement,
12774
12901
  elementsMap
12775
12902
  );
12776
- const boundTextShiftX = (x1 + x2) / 2 - boundTextCx;
12777
- const boundTextShiftY = (y1 + y2) / 2 - boundTextCy;
12778
- tempCanvasContext.translate(-boundTextShiftX, -boundTextShiftY);
12779
- tempCanvasContext.clearRect(
12780
- -boundTextElement.width / 2,
12781
- -boundTextElement.height / 2,
12782
- boundTextElement.width,
12783
- boundTextElement.height
12784
- );
12785
- context.scale(1 / appState.exportScale, 1 / appState.exportScale);
12786
- context.drawImage(
12787
- tempCanvas,
12788
- -tempCanvas.width / 2,
12789
- -tempCanvas.height / 2,
12790
- tempCanvas.width,
12791
- tempCanvas.height
12792
- );
12903
+ const holeX = boundTextCx - centerX - boundTextElement.width / 2 - BOUND_TEXT_PADDING3;
12904
+ const holeY = boundTextCy - centerY - boundTextElement.height / 2 - BOUND_TEXT_PADDING3;
12905
+ const holeWidth = boundTextElement.width + BOUND_TEXT_PADDING3 * 2;
12906
+ const holeHeight = boundTextElement.height + BOUND_TEXT_PADDING3 * 2;
12907
+ const outerHalf = Math.max(distance2(x1, x2), distance2(y1, y2)) + getCanvasPadding(element) * 10;
12908
+ context.save();
12909
+ context.beginPath();
12910
+ context.rect(-outerHalf, -outerHalf, outerHalf * 2, outerHalf * 2);
12911
+ context.rect(holeX, holeY, holeWidth, holeHeight);
12912
+ context.clip("evenodd");
12913
+ context.rotate(element.angle);
12914
+ context.translate(-shiftX, -shiftY);
12915
+ drawElementOnCanvas(element, rc, context, renderConfig);
12916
+ context.restore();
12793
12917
  } else {
12794
12918
  context.rotate(element.angle);
12795
12919
  if (element.type === "image") {
@@ -12825,7 +12949,10 @@ var renderElement = (element, elementsMap, allElementsMap, rc, context, renderCo
12825
12949
  context.save();
12826
12950
  context.globalAlpha = 0.1;
12827
12951
  const uncroppedElementCanvas = generateElementCanvas(
12828
- getUncroppedImageElement(elementWithCanvas.element, elementsMap),
12952
+ getUncroppedImageElement(
12953
+ elementWithCanvas.element,
12954
+ elementsMap
12955
+ ),
12829
12956
  allElementsMap,
12830
12957
  appState.zoom,
12831
12958
  renderConfig,
@@ -12867,7 +12994,7 @@ function getFreedrawOutlineAsSegments(element, points, elementsMap) {
12867
12994
  },
12868
12995
  elementsMap
12869
12996
  );
12870
- const center = pointFrom12(
12997
+ const center = pointFrom11(
12871
12998
  (bounds[0] + bounds[2]) / 2,
12872
12999
  (bounds[1] + bounds[3]) / 2
12873
13000
  );
@@ -12875,10 +13002,10 @@ function getFreedrawOutlineAsSegments(element, points, elementsMap) {
12875
13002
  return points.slice(2).reduce(
12876
13003
  (acc, curr) => {
12877
13004
  acc.push(
12878
- lineSegment6(
13005
+ lineSegment5(
12879
13006
  acc[acc.length - 1][1],
12880
- pointRotateRads11(
12881
- pointFrom12(curr[0] + element.x, curr[1] + element.y),
13007
+ pointRotateRads10(
13008
+ pointFrom11(curr[0] + element.x, curr[1] + element.y),
12882
13009
  center,
12883
13010
  element.angle
12884
13011
  )
@@ -12887,17 +13014,17 @@ function getFreedrawOutlineAsSegments(element, points, elementsMap) {
12887
13014
  return acc;
12888
13015
  },
12889
13016
  [
12890
- lineSegment6(
12891
- pointRotateRads11(
12892
- pointFrom12(
13017
+ lineSegment5(
13018
+ pointRotateRads10(
13019
+ pointFrom11(
12893
13020
  points[0][0] + element.x,
12894
13021
  points[0][1] + element.y
12895
13022
  ),
12896
13023
  center,
12897
13024
  element.angle
12898
13025
  ),
12899
- pointRotateRads11(
12900
- pointFrom12(
13026
+ pointRotateRads10(
13027
+ pointFrom11(
12901
13028
  points[1][0] + element.x,
12902
13029
  points[1][1] + element.y
12903
13030
  ),
@@ -12992,7 +13119,7 @@ var generateRoughOptions = (element, continuousPath = false, isDarkMode = false)
12992
13119
  fillWeight: element.strokeWidth / 2,
12993
13120
  hachureGap: element.strokeWidth * 4,
12994
13121
  roughness: adjustRoughness(element),
12995
- stroke: isDarkMode ? applyDarkModeFilter2(element.strokeColor) : element.strokeColor,
13122
+ stroke: applyDarkModeFilter2(element.strokeColor, isDarkMode),
12996
13123
  preserveVertices: continuousPath || element.roughness < ROUGHNESS.cartoonist
12997
13124
  };
12998
13125
  switch (element.type) {
@@ -13002,7 +13129,7 @@ var generateRoughOptions = (element, continuousPath = false, isDarkMode = false)
13002
13129
  case "diamond":
13003
13130
  case "ellipse": {
13004
13131
  options.fillStyle = element.fillStyle;
13005
- options.fill = isTransparent3(element.backgroundColor) ? void 0 : isDarkMode ? applyDarkModeFilter2(element.backgroundColor) : element.backgroundColor;
13132
+ options.fill = isTransparent3(element.backgroundColor) ? void 0 : applyDarkModeFilter2(element.backgroundColor, isDarkMode);
13006
13133
  if (element.type === "ellipse") {
13007
13134
  options.curveFitting = 1;
13008
13135
  }
@@ -13012,7 +13139,7 @@ var generateRoughOptions = (element, continuousPath = false, isDarkMode = false)
13012
13139
  case "freedraw": {
13013
13140
  if (isPathALoop(element.points)) {
13014
13141
  options.fillStyle = element.fillStyle;
13015
- options.fill = element.backgroundColor === "transparent" ? void 0 : isDarkMode ? applyDarkModeFilter2(element.backgroundColor) : element.backgroundColor;
13142
+ options.fill = element.backgroundColor === "transparent" ? void 0 : applyDarkModeFilter2(element.backgroundColor, isDarkMode);
13016
13143
  }
13017
13144
  return options;
13018
13145
  }
@@ -13087,8 +13214,11 @@ var getArrowheadShapes = (element, shape, position, arrowhead, generator, option
13087
13214
  if (arrowhead === null) {
13088
13215
  return [];
13089
13216
  }
13090
- const strokeColor = isDarkMode ? applyDarkModeFilter2(element.strokeColor) : element.strokeColor;
13091
- const backgroundFillColor = isDarkMode ? applyDarkModeFilter2(canvasBackgroundColor) : canvasBackgroundColor;
13217
+ const strokeColor = applyDarkModeFilter2(element.strokeColor, isDarkMode);
13218
+ const backgroundFillColor = applyDarkModeFilter2(
13219
+ canvasBackgroundColor,
13220
+ isDarkMode
13221
+ );
13092
13222
  const cardinalityOneOrManyOffset = -0.25;
13093
13223
  const cardinalityZeroCircleScale = 0.8;
13094
13224
  switch (arrowhead) {
@@ -13273,26 +13403,26 @@ var generateLinearCollisionShape = (element, elementsMap) => {
13273
13403
  switch (element.type) {
13274
13404
  case "line":
13275
13405
  case "arrow": {
13276
- const points = element.points.length ? element.points : [pointFrom13(0, 0)];
13406
+ const points = element.points.length ? element.points : [pointFrom12(0, 0)];
13277
13407
  if (isElbowArrow(element)) {
13278
13408
  return generator.path(generateElbowArrowShape(points, 16), options).sets[0].ops;
13279
13409
  } else if (!element.roundness) {
13280
13410
  return points.map((point, idx) => {
13281
- const p = pointRotateRads12(
13282
- pointFrom13(element.x + point[0], element.y + point[1]),
13411
+ const p = pointRotateRads11(
13412
+ pointFrom12(element.x + point[0], element.y + point[1]),
13283
13413
  center,
13284
13414
  element.angle
13285
13415
  );
13286
13416
  return {
13287
13417
  op: idx === 0 ? "move" : "lineTo",
13288
- data: pointFrom13(p[0] - element.x, p[1] - element.y)
13418
+ data: pointFrom12(p[0] - element.x, p[1] - element.y)
13289
13419
  };
13290
13420
  });
13291
13421
  }
13292
13422
  return generator.curve(points, options).sets[0].ops.slice(0, element.points.length).map((op, i) => {
13293
13423
  if (i === 0) {
13294
- const p = pointRotateRads12(
13295
- pointFrom13(
13424
+ const p = pointRotateRads11(
13425
+ pointFrom12(
13296
13426
  element.x + op.data[0],
13297
13427
  element.y + op.data[1]
13298
13428
  ),
@@ -13301,30 +13431,30 @@ var generateLinearCollisionShape = (element, elementsMap) => {
13301
13431
  );
13302
13432
  return {
13303
13433
  op: "move",
13304
- data: pointFrom13(p[0] - element.x, p[1] - element.y)
13434
+ data: pointFrom12(p[0] - element.x, p[1] - element.y)
13305
13435
  };
13306
13436
  }
13307
13437
  return {
13308
13438
  op: "bcurveTo",
13309
13439
  data: [
13310
- pointRotateRads12(
13311
- pointFrom13(
13440
+ pointRotateRads11(
13441
+ pointFrom12(
13312
13442
  element.x + op.data[0],
13313
13443
  element.y + op.data[1]
13314
13444
  ),
13315
13445
  center,
13316
13446
  element.angle
13317
13447
  ),
13318
- pointRotateRads12(
13319
- pointFrom13(
13448
+ pointRotateRads11(
13449
+ pointFrom12(
13320
13450
  element.x + op.data[2],
13321
13451
  element.y + op.data[3]
13322
13452
  ),
13323
13453
  center,
13324
13454
  element.angle
13325
13455
  ),
13326
- pointRotateRads12(
13327
- pointFrom13(
13456
+ pointRotateRads11(
13457
+ pointFrom12(
13328
13458
  element.x + op.data[4],
13329
13459
  element.y + op.data[5]
13330
13460
  ),
@@ -13332,7 +13462,7 @@ var generateLinearCollisionShape = (element, elementsMap) => {
13332
13462
  element.angle
13333
13463
  )
13334
13464
  ].map(
13335
- (p) => pointFrom13(p[0] - element.x, p[1] - element.y)
13465
+ (p) => pointFrom12(p[0] - element.x, p[1] - element.y)
13336
13466
  ).flat()
13337
13467
  };
13338
13468
  });
@@ -13347,8 +13477,8 @@ var generateLinearCollisionShape = (element, elementsMap) => {
13347
13477
  );
13348
13478
  return generator.curve(simplifiedPoints, options).sets[0].ops.slice(0, element.points.length).map((op, i) => {
13349
13479
  if (i === 0) {
13350
- const p = pointRotateRads12(
13351
- pointFrom13(
13480
+ const p = pointRotateRads11(
13481
+ pointFrom12(
13352
13482
  element.x + op.data[0],
13353
13483
  element.y + op.data[1]
13354
13484
  ),
@@ -13357,30 +13487,30 @@ var generateLinearCollisionShape = (element, elementsMap) => {
13357
13487
  );
13358
13488
  return {
13359
13489
  op: "move",
13360
- data: pointFrom13(p[0] - element.x, p[1] - element.y)
13490
+ data: pointFrom12(p[0] - element.x, p[1] - element.y)
13361
13491
  };
13362
13492
  }
13363
13493
  return {
13364
13494
  op: "bcurveTo",
13365
13495
  data: [
13366
- pointRotateRads12(
13367
- pointFrom13(
13496
+ pointRotateRads11(
13497
+ pointFrom12(
13368
13498
  element.x + op.data[0],
13369
13499
  element.y + op.data[1]
13370
13500
  ),
13371
13501
  center,
13372
13502
  element.angle
13373
13503
  ),
13374
- pointRotateRads12(
13375
- pointFrom13(
13504
+ pointRotateRads11(
13505
+ pointFrom12(
13376
13506
  element.x + op.data[2],
13377
13507
  element.y + op.data[3]
13378
13508
  ),
13379
13509
  center,
13380
13510
  element.angle
13381
13511
  ),
13382
- pointRotateRads12(
13383
- pointFrom13(
13512
+ pointRotateRads11(
13513
+ pointFrom12(
13384
13514
  element.x + op.data[4],
13385
13515
  element.y + op.data[5]
13386
13516
  ),
@@ -13388,7 +13518,7 @@ var generateLinearCollisionShape = (element, elementsMap) => {
13388
13518
  element.angle
13389
13519
  )
13390
13520
  ].map(
13391
- (p) => pointFrom13(p[0] - element.x, p[1] - element.y)
13521
+ (p) => pointFrom12(p[0] - element.x, p[1] - element.y)
13392
13522
  ).flat()
13393
13523
  };
13394
13524
  });
@@ -13489,7 +13619,7 @@ var _generateElementShape = (element, generator, {
13489
13619
  case "arrow": {
13490
13620
  let shape;
13491
13621
  const options = generateRoughOptions(element, false, isDarkMode);
13492
- const points = element.points.length ? element.points : [pointFrom13(0, 0)];
13622
+ const points = element.points.length ? element.points : [pointFrom12(0, 0)];
13493
13623
  if (isElbowArrow(element)) {
13494
13624
  if (!points.every(
13495
13625
  (point) => Math.abs(point[0]) <= 1e6 && Math.abs(point[1]) <= 1e6
@@ -13653,14 +13783,14 @@ var getElementShape = (element, elementsMap) => {
13653
13783
  return shouldTestInside(element) ? getClosedCurveShape(
13654
13784
  element,
13655
13785
  roughShape,
13656
- pointFrom13(element.x, element.y),
13786
+ pointFrom12(element.x, element.y),
13657
13787
  element.angle,
13658
- pointFrom13(cx, cy)
13788
+ pointFrom12(cx, cy)
13659
13789
  ) : getCurveShape(
13660
13790
  roughShape,
13661
- pointFrom13(element.x, element.y),
13791
+ pointFrom12(element.x, element.y),
13662
13792
  element.angle,
13663
- pointFrom13(cx, cy)
13793
+ pointFrom12(cx, cy)
13664
13794
  );
13665
13795
  }
13666
13796
  case "ellipse":
@@ -13669,7 +13799,7 @@ var getElementShape = (element, elementsMap) => {
13669
13799
  const [, , , , cx, cy] = getElementAbsoluteCoords2(element, elementsMap);
13670
13800
  return getFreedrawShape(
13671
13801
  element,
13672
- pointFrom13(cx, cy),
13802
+ pointFrom12(cx, cy),
13673
13803
  shouldTestInside(element)
13674
13804
  );
13675
13805
  }
@@ -13688,9 +13818,9 @@ var toggleLinePolygonState = (element, nextPolygonState) => {
13688
13818
  firstPoint[1] - lastPoint[1]
13689
13819
  );
13690
13820
  if (distance3 > LINE_POLYGON_POINT_MERGE_DISTANCE || updatedPoints.length < 4) {
13691
- updatedPoints.push(pointFrom13(firstPoint[0], firstPoint[1]));
13821
+ updatedPoints.push(pointFrom12(firstPoint[0], firstPoint[1]));
13692
13822
  } else {
13693
- updatedPoints[updatedPoints.length - 1] = pointFrom13(
13823
+ updatedPoints[updatedPoints.length - 1] = pointFrom12(
13694
13824
  firstPoint[0],
13695
13825
  firstPoint[1]
13696
13826
  );
@@ -13707,19 +13837,46 @@ var getFreeDrawSvgPath = (element) => {
13707
13837
  getFreedrawOutlinePoints(element)
13708
13838
  );
13709
13839
  };
13710
- var getFreedrawOutlinePoints = (element) => {
13711
- const inputPoints = element.simulatePressure ? element.points : element.points.length ? element.points.map(([x, y], i) => [x, y, element.pressures[i]]) : [[0, 0, 0.5]];
13840
+ var VARIABLE_WIDTH_FREEDRAW = {
13841
+ /** Stroke size relative to `strokeWidth` for pressure-sensitive strokes. */
13842
+ SIZE_FACTOR: 4.25,
13843
+ THINNING: 0.6,
13844
+ SMOOTHING: 0.5
13845
+ };
13846
+ var CONSTANT_WIDTH_FREEDRAW = {
13847
+ /** Stroke size relative to `strokeWidth` for uniform (laser) strokes. */
13848
+ SIZE_FACTOR: 1.4
13849
+ };
13850
+ var getFreedrawStreamline = (element) => element.strokeOptions?.streamline ?? DEFAULT_STROKE_STREAMLINE;
13851
+ var getVariableWidthFreedrawOutline = (element) => {
13852
+ const inputPoints = element.simulatePressure ? element.points : element.points.length ? element.points.map(
13853
+ ([x, y], i) => [x, y, element.pressures[i]]
13854
+ ) : [[0, 0, 0.5]];
13712
13855
  return ae(inputPoints, {
13713
13856
  simulatePressure: element.simulatePressure,
13714
- size: element.strokeWidth * 4.25,
13715
- thinning: 0.6,
13716
- smoothing: 0.5,
13717
- streamline: 0.5,
13857
+ size: element.strokeWidth * VARIABLE_WIDTH_FREEDRAW.SIZE_FACTOR,
13858
+ thinning: VARIABLE_WIDTH_FREEDRAW.THINNING,
13859
+ smoothing: VARIABLE_WIDTH_FREEDRAW.SMOOTHING,
13860
+ streamline: getFreedrawStreamline(element),
13718
13861
  easing: (t) => Math.sin(t * Math.PI / 2),
13719
13862
  // https://easings.net/#easeOutSine
13720
13863
  last: true
13721
13864
  });
13722
13865
  };
13866
+ var createLaserPointer = (element) => new LaserPointer({
13867
+ size: element.strokeWidth * CONSTANT_WIDTH_FREEDRAW.SIZE_FACTOR,
13868
+ streamline: getFreedrawStreamline(element),
13869
+ simplify: 0,
13870
+ sizeMapping: (details) => Math.max(0.1, details.pressure)
13871
+ });
13872
+ var getConstantWidthFreedrawOutline = (element) => {
13873
+ const laserPointer = createLaserPointer(element);
13874
+ element.points.map(([x, y]) => laserPointer.addPoint([x, y, 1]));
13875
+ return laserPointer.getStrokeOutline().map(([x, y]) => [x, y]);
13876
+ };
13877
+ var getFreedrawOutlinePoints = (element) => {
13878
+ return element.strokeOptions?.variability === "constant" ? getConstantWidthFreedrawOutline(element) : getVariableWidthFreedrawOutline(element);
13879
+ };
13723
13880
  var med = (A2, B2) => {
13724
13881
  return [(A2[0] + B2[0]) / 2, (A2[1] + B2[1]) / 2];
13725
13882
  };
@@ -13783,9 +13940,9 @@ var ElementBounds = class _ElementBounds {
13783
13940
  if (isFreeDrawElement(element)) {
13784
13941
  const [minX, minY, maxX, maxY] = getBoundsFromPoints(
13785
13942
  element.points.map(
13786
- ([x, y]) => pointRotateRads13(
13787
- pointFrom14(x, y),
13788
- pointFrom14(cx - element.x, cy - element.y),
13943
+ ([x, y]) => pointRotateRads12(
13944
+ pointFrom13(x, y),
13945
+ pointFrom13(cx - element.x, cy - element.y),
13789
13946
  element.angle
13790
13947
  )
13791
13948
  )
@@ -13799,24 +13956,24 @@ var ElementBounds = class _ElementBounds {
13799
13956
  } else if (isLinearElement(element)) {
13800
13957
  bounds = getLinearElementRotatedBounds(element, cx, cy, elementsMap);
13801
13958
  } else if (element.type === "diamond") {
13802
- const [x11, y11] = pointRotateRads13(
13803
- pointFrom14(cx, y1),
13804
- pointFrom14(cx, cy),
13959
+ const [x11, y11] = pointRotateRads12(
13960
+ pointFrom13(cx, y1),
13961
+ pointFrom13(cx, cy),
13805
13962
  element.angle
13806
13963
  );
13807
- const [x12, y12] = pointRotateRads13(
13808
- pointFrom14(cx, y2),
13809
- pointFrom14(cx, cy),
13964
+ const [x12, y12] = pointRotateRads12(
13965
+ pointFrom13(cx, y2),
13966
+ pointFrom13(cx, cy),
13810
13967
  element.angle
13811
13968
  );
13812
- const [x22, y22] = pointRotateRads13(
13813
- pointFrom14(x1, cy),
13814
- pointFrom14(cx, cy),
13969
+ const [x22, y22] = pointRotateRads12(
13970
+ pointFrom13(x1, cy),
13971
+ pointFrom13(cx, cy),
13815
13972
  element.angle
13816
13973
  );
13817
- const [x21, y21] = pointRotateRads13(
13818
- pointFrom14(x2, cy),
13819
- pointFrom14(cx, cy),
13974
+ const [x21, y21] = pointRotateRads12(
13975
+ pointFrom13(x2, cy),
13976
+ pointFrom13(cx, cy),
13820
13977
  element.angle
13821
13978
  );
13822
13979
  const minX = Math.min(x11, x12, x22, x21);
@@ -13833,24 +13990,24 @@ var ElementBounds = class _ElementBounds {
13833
13990
  const hh = Math.hypot(h * cos, w * sin);
13834
13991
  bounds = [cx - ww, cy - hh, cx + ww, cy + hh];
13835
13992
  } else {
13836
- const [x11, y11] = pointRotateRads13(
13837
- pointFrom14(x1, y1),
13838
- pointFrom14(cx, cy),
13993
+ const [x11, y11] = pointRotateRads12(
13994
+ pointFrom13(x1, y1),
13995
+ pointFrom13(cx, cy),
13839
13996
  element.angle
13840
13997
  );
13841
- const [x12, y12] = pointRotateRads13(
13842
- pointFrom14(x1, y2),
13843
- pointFrom14(cx, cy),
13998
+ const [x12, y12] = pointRotateRads12(
13999
+ pointFrom13(x1, y2),
14000
+ pointFrom13(cx, cy),
13844
14001
  element.angle
13845
14002
  );
13846
- const [x22, y22] = pointRotateRads13(
13847
- pointFrom14(x2, y2),
13848
- pointFrom14(cx, cy),
14003
+ const [x22, y22] = pointRotateRads12(
14004
+ pointFrom13(x2, y2),
14005
+ pointFrom13(cx, cy),
13849
14006
  element.angle
13850
14007
  );
13851
- const [x21, y21] = pointRotateRads13(
13852
- pointFrom14(x2, y1),
13853
- pointFrom14(cx, cy),
14008
+ const [x21, y21] = pointRotateRads12(
14009
+ pointFrom13(x2, y1),
14010
+ pointFrom13(cx, cy),
13854
14011
  element.angle
13855
14012
  );
13856
14013
  const minX = Math.min(x11, x12, x22, x21);
@@ -13904,7 +14061,7 @@ var getElementLineSegments = (element, elementsMap) => {
13904
14061
  element,
13905
14062
  elementsMap
13906
14063
  );
13907
- const center = pointFrom14(cx, cy);
14064
+ const center = pointFrom13(cx, cy);
13908
14065
  if (shape.type === "polycurve") {
13909
14066
  const curves = shape.data;
13910
14067
  const pointsOnCurves = curves.map(
@@ -13916,9 +14073,9 @@ var getElementLineSegments = (element, elementsMap) => {
13916
14073
  let i = 0;
13917
14074
  while (i < points.length - 1) {
13918
14075
  segments.push(
13919
- lineSegment7(
13920
- pointFrom14(points[i][0], points[i][1]),
13921
- pointFrom14(points[i + 1][0], points[i + 1][1])
14076
+ lineSegment6(
14077
+ pointFrom13(points[i][0], points[i][1]),
14078
+ pointFrom13(points[i + 1][0], points[i + 1][1])
13922
14079
  )
13923
14080
  );
13924
14081
  i++;
@@ -13929,9 +14086,9 @@ var getElementLineSegments = (element, elementsMap) => {
13929
14086
  let i = 0;
13930
14087
  while (i < points.length - 1) {
13931
14088
  segments.push(
13932
- lineSegment7(
13933
- pointFrom14(points[i][0], points[i][1]),
13934
- pointFrom14(points[i + 1][0], points[i + 1][1])
14089
+ lineSegment6(
14090
+ pointFrom13(points[i][0], points[i][1]),
14091
+ pointFrom13(points[i + 1][0], points[i + 1][1])
13935
14092
  )
13936
14093
  );
13937
14094
  i++;
@@ -13955,10 +14112,10 @@ var getElementLineSegments = (element, elementsMap) => {
13955
14112
  const container = getContainerElement(element, elementsMap);
13956
14113
  if (container && isLinearElement(container)) {
13957
14114
  const segments2 = [
13958
- lineSegment7(pointFrom14(x1, y1), pointFrom14(x2, y1)),
13959
- lineSegment7(pointFrom14(x2, y1), pointFrom14(x2, y2)),
13960
- lineSegment7(pointFrom14(x2, y2), pointFrom14(x1, y2)),
13961
- lineSegment7(pointFrom14(x1, y2), pointFrom14(x1, y1))
14115
+ lineSegment6(pointFrom13(x1, y1), pointFrom13(x2, y1)),
14116
+ lineSegment6(pointFrom13(x2, y1), pointFrom13(x2, y2)),
14117
+ lineSegment6(pointFrom13(x2, y2), pointFrom13(x1, y2)),
14118
+ lineSegment6(pointFrom13(x1, y2), pointFrom13(x1, y1))
13962
14119
  ];
13963
14120
  return segments2;
13964
14121
  }
@@ -13966,7 +14123,7 @@ var getElementLineSegments = (element, elementsMap) => {
13966
14123
  const points = shape.data;
13967
14124
  const segments = [];
13968
14125
  for (let i = 0; i < points.length - 1; i++) {
13969
- segments.push(lineSegment7(points[i], points[i + 1]));
14126
+ segments.push(lineSegment6(points[i], points[i + 1]));
13970
14127
  }
13971
14128
  return segments;
13972
14129
  } else if (shape.type === "ellipse") {
@@ -13981,45 +14138,45 @@ var getElementLineSegments = (element, elementsMap) => {
13981
14138
  [cx, y2],
13982
14139
  [x1, cy],
13983
14140
  [x2, cy]
13984
- ].map((point) => pointRotateRads13(point, center, element.angle));
14141
+ ].map((point) => pointRotateRads12(point, center, element.angle));
13985
14142
  return [
13986
- lineSegment7(nw, ne),
13987
- lineSegment7(sw, se2),
13988
- lineSegment7(nw, sw),
13989
- lineSegment7(ne, se2),
13990
- lineSegment7(nw, e),
13991
- lineSegment7(sw, e),
13992
- lineSegment7(ne, w),
13993
- lineSegment7(se2, w)
14143
+ lineSegment6(nw, ne),
14144
+ lineSegment6(sw, se2),
14145
+ lineSegment6(nw, sw),
14146
+ lineSegment6(ne, se2),
14147
+ lineSegment6(nw, e),
14148
+ lineSegment6(sw, e),
14149
+ lineSegment6(ne, w),
14150
+ lineSegment6(se2, w)
13994
14151
  ];
13995
14152
  };
13996
14153
  var _isRectanguloidElement = (element) => {
13997
14154
  return element != null && (element.type === "rectangle" || element.type === "image" || element.type === "iframe" || element.type === "embeddable" || element.type === "frame" || element.type === "magicframe" || element.type === "text" && !element.containerId);
13998
14155
  };
13999
- var getRotatedSides = (sides, center, angle) => {
14156
+ var getRotatedSides = (sides, center, angle2) => {
14000
14157
  return sides.map((side) => {
14001
- return lineSegment7(
14002
- pointRotateRads13(side[0], center, angle),
14003
- pointRotateRads13(side[1], center, angle)
14158
+ return lineSegment6(
14159
+ pointRotateRads12(side[0], center, angle2),
14160
+ pointRotateRads12(side[1], center, angle2)
14004
14161
  );
14005
14162
  });
14006
14163
  };
14007
- var getSegmentsOnCurve = (curve4, center, angle) => {
14164
+ var getSegmentsOnCurve = (curve4, center, angle2) => {
14008
14165
  const points = pointsOnBezierCurves(curve4, 10);
14009
14166
  let i = 0;
14010
14167
  const segments = [];
14011
14168
  while (i < points.length - 1) {
14012
14169
  segments.push(
14013
- lineSegment7(
14014
- pointRotateRads13(
14015
- pointFrom14(points[i][0], points[i][1]),
14170
+ lineSegment6(
14171
+ pointRotateRads12(
14172
+ pointFrom13(points[i][0], points[i][1]),
14016
14173
  center,
14017
- angle
14174
+ angle2
14018
14175
  ),
14019
- pointRotateRads13(
14020
- pointFrom14(points[i + 1][0], points[i + 1][1]),
14176
+ pointRotateRads12(
14177
+ pointFrom13(points[i + 1][0], points[i + 1][1]),
14021
14178
  center,
14022
- angle
14179
+ angle2
14023
14180
  )
14024
14181
  )
14025
14182
  );
@@ -14028,7 +14185,7 @@ var getSegmentsOnCurve = (curve4, center, angle) => {
14028
14185
  return segments;
14029
14186
  };
14030
14187
  var getSegmentsOnEllipse = (ellipse4) => {
14031
- const center = pointFrom14(
14188
+ const center = pointFrom13(
14032
14189
  ellipse4.x + ellipse4.width / 2,
14033
14190
  ellipse4.y + ellipse4.height / 2
14034
14191
  );
@@ -14042,12 +14199,12 @@ var getSegmentsOnEllipse = (ellipse4) => {
14042
14199
  const t = i * deltaT;
14043
14200
  const x = center[0] + a2 * Math.cos(t);
14044
14201
  const y = center[1] + b2 * Math.sin(t);
14045
- points.push(pointRotateRads13(pointFrom14(x, y), center, ellipse4.angle));
14202
+ points.push(pointRotateRads12(pointFrom13(x, y), center, ellipse4.angle));
14046
14203
  }
14047
14204
  for (let i = 0; i < points.length - 1; i++) {
14048
- segments.push(lineSegment7(points[i], points[i + 1]));
14205
+ segments.push(lineSegment6(points[i], points[i + 1]));
14049
14206
  }
14050
- segments.push(lineSegment7(points[points.length - 1], points[0]));
14207
+ segments.push(lineSegment6(points[points.length - 1], points[0]));
14051
14208
  return segments;
14052
14209
  };
14053
14210
  var getRectangleBoxAbsoluteCoords = (boxSceneCoords) => {
@@ -14125,7 +14282,7 @@ var getCubicBezierCurveBound = (p0, p1, p2, p3) => {
14125
14282
  return [minX, minY, maxX, maxY];
14126
14283
  };
14127
14284
  var getMinMaxXYFromCurvePathOps = (ops, transformXY) => {
14128
- let currentP = pointFrom14(0, 0);
14285
+ let currentP = pointFrom13(0, 0);
14129
14286
  const { minX, minY, maxX, maxY } = ops.reduce(
14130
14287
  (limits, { op, data }) => {
14131
14288
  if (op === "move") {
@@ -14133,9 +14290,9 @@ var getMinMaxXYFromCurvePathOps = (ops, transformXY) => {
14133
14290
  invariant10(p != null, "Op data is not a point");
14134
14291
  currentP = p;
14135
14292
  } else if (op === "bcurveTo") {
14136
- const _p1 = pointFrom14(data[0], data[1]);
14137
- const _p2 = pointFrom14(data[2], data[3]);
14138
- const _p3 = pointFrom14(data[4], data[5]);
14293
+ const _p1 = pointFrom13(data[0], data[1]);
14294
+ const _p2 = pointFrom13(data[2], data[3]);
14295
+ const _p3 = pointFrom13(data[4], data[5]);
14139
14296
  const p1 = transformXY ? transformXY(_p1) : _p1;
14140
14297
  const p2 = transformXY ? transformXY(_p2) : _p2;
14141
14298
  const p3 = transformXY ? transformXY(_p3) : _p3;
@@ -14226,17 +14383,17 @@ var getArrowheadPoints = (element, shape, position, arrowhead, offsetMultiplier
14226
14383
  const index = position === "start" ? 1 : ops.length - 1;
14227
14384
  const data = ops[index].data;
14228
14385
  invariant10(data.length === 6, "Op data length is not 6");
14229
- const p3 = pointFrom14(data[4], data[5]);
14230
- const p2 = pointFrom14(data[2], data[3]);
14231
- const p1 = pointFrom14(data[0], data[1]);
14386
+ const p3 = pointFrom13(data[4], data[5]);
14387
+ const p2 = pointFrom13(data[2], data[3]);
14388
+ const p1 = pointFrom13(data[0], data[1]);
14232
14389
  const prevOp = ops[index - 1];
14233
- let p0 = pointFrom14(0, 0);
14390
+ let p0 = pointFrom13(0, 0);
14234
14391
  if (prevOp.op === "move") {
14235
14392
  const p = pointFromArray3(prevOp.data);
14236
14393
  invariant10(p != null, "Op data is not a point");
14237
14394
  p0 = p;
14238
14395
  } else if (prevOp.op === "bcurveTo") {
14239
- p0 = pointFrom14(prevOp.data[4], prevOp.data[5]);
14396
+ p0 = pointFrom13(prevOp.data[4], prevOp.data[5]);
14240
14397
  }
14241
14398
  const equation = (t, idx) => Math.pow(1 - t, 3) * p3[idx] + 3 * t * Math.pow(1 - t, 2) * p2[idx] + 3 * Math.pow(t, 2) * (1 - t) * p1[idx] + p0[idx] * Math.pow(t, 3);
14242
14399
  const [x2, y2] = position === "start" ? p0 : p3;
@@ -14261,45 +14418,45 @@ var getArrowheadPoints = (element, shape, position, arrowhead, offsetMultiplier
14261
14418
  const diameter = Math.hypot(ys - ty, xs - tx) + element.strokeWidth - 2;
14262
14419
  return [tx, ty, diameter];
14263
14420
  }
14264
- const angle = getArrowheadAngle(arrowhead);
14421
+ const angle2 = getArrowheadAngle(arrowhead);
14265
14422
  if (arrowhead === "cardinality_many" || arrowhead === "cardinality_one_or_many") {
14266
- const [x32, y32] = pointRotateRads13(
14267
- pointFrom14(tx, ty),
14268
- pointFrom14(xs, ys),
14269
- degreesToRadians(-angle)
14423
+ const [x32, y32] = pointRotateRads12(
14424
+ pointFrom13(tx, ty),
14425
+ pointFrom13(xs, ys),
14426
+ degreesToRadians(-angle2)
14270
14427
  );
14271
- const [x42, y42] = pointRotateRads13(
14272
- pointFrom14(tx, ty),
14273
- pointFrom14(xs, ys),
14274
- degreesToRadians(angle)
14428
+ const [x42, y42] = pointRotateRads12(
14429
+ pointFrom13(tx, ty),
14430
+ pointFrom13(xs, ys),
14431
+ degreesToRadians(angle2)
14275
14432
  );
14276
14433
  return [xs, ys, x32, y32, x42, y42];
14277
14434
  }
14278
- const [x3, y3] = pointRotateRads13(
14279
- pointFrom14(xs, ys),
14280
- pointFrom14(tx, ty),
14281
- -angle * Math.PI / 180
14435
+ const [x3, y3] = pointRotateRads12(
14436
+ pointFrom13(xs, ys),
14437
+ pointFrom13(tx, ty),
14438
+ -angle2 * Math.PI / 180
14282
14439
  );
14283
- const [x4, y4] = pointRotateRads13(
14284
- pointFrom14(xs, ys),
14285
- pointFrom14(tx, ty),
14286
- degreesToRadians(angle)
14440
+ const [x4, y4] = pointRotateRads12(
14441
+ pointFrom13(xs, ys),
14442
+ pointFrom13(tx, ty),
14443
+ degreesToRadians(angle2)
14287
14444
  );
14288
14445
  if (arrowhead === "diamond" || arrowhead === "diamond_outline") {
14289
14446
  let ox;
14290
14447
  let oy;
14291
14448
  if (position === "start") {
14292
14449
  const [px, py] = element.points.length > 1 ? element.points[1] : [0, 0];
14293
- [ox, oy] = pointRotateRads13(
14294
- pointFrom14(tx + minSize * 2, ty),
14295
- pointFrom14(tx, ty),
14450
+ [ox, oy] = pointRotateRads12(
14451
+ pointFrom13(tx + minSize * 2, ty),
14452
+ pointFrom13(tx, ty),
14296
14453
  Math.atan2(py - ty, px - tx)
14297
14454
  );
14298
14455
  } else {
14299
14456
  const [px, py] = element.points.length > 1 ? element.points[element.points.length - 2] : [0, 0];
14300
- [ox, oy] = pointRotateRads13(
14301
- pointFrom14(tx - minSize * 2, ty),
14302
- pointFrom14(tx, ty),
14457
+ [ox, oy] = pointRotateRads12(
14458
+ pointFrom13(tx - minSize * 2, ty),
14459
+ pointFrom13(tx, ty),
14303
14460
  Math.atan2(ty - py, tx - px)
14304
14461
  );
14305
14462
  }
@@ -14328,9 +14485,9 @@ var getLinearElementRotatedBounds = (element, cx, cy, elementsMap) => {
14328
14485
  const boundTextElement = getBoundTextElement(element, elementsMap);
14329
14486
  if (element.points.length < 2) {
14330
14487
  const [pointX, pointY] = element.points[0];
14331
- const [x, y] = pointRotateRads13(
14332
- pointFrom14(element.x + pointX, element.y + pointY),
14333
- pointFrom14(cx, cy),
14488
+ const [x, y] = pointRotateRads12(
14489
+ pointFrom13(element.x + pointX, element.y + pointY),
14490
+ pointFrom13(cx, cy),
14334
14491
  element.angle
14335
14492
  );
14336
14493
  let coords2 = [x, y, x, y];
@@ -14353,9 +14510,9 @@ var getLinearElementRotatedBounds = (element, cx, cy, elementsMap) => {
14353
14510
  const cachedShape = ShapeCache.get(element, null)?.[0];
14354
14511
  const shape = cachedShape ?? generateLinearElementShape(element);
14355
14512
  const ops = getCurvePathOps(shape);
14356
- const transformXY = ([x, y]) => pointRotateRads13(
14357
- pointFrom14(element.x + x, element.y + y),
14358
- pointFrom14(cx, cy),
14513
+ const transformXY = ([x, y]) => pointRotateRads12(
14514
+ pointFrom13(element.x + x, element.y + y),
14515
+ pointFrom13(cx, cy),
14359
14516
  element.angle
14360
14517
  );
14361
14518
  const res = getMinMaxXYFromCurvePathOps(ops, transformXY);
@@ -14456,26 +14613,6 @@ var getElementPointsCoords = (element, points) => {
14456
14613
  maxY + element.y
14457
14614
  ];
14458
14615
  };
14459
- var getClosestElementBounds = (elements, from) => {
14460
- if (!elements.length) {
14461
- return [0, 0, 0, 0];
14462
- }
14463
- let minDistance = Infinity;
14464
- let closestElement = elements[0];
14465
- const elementsMap = arrayToMap6(elements);
14466
- elements.forEach((element) => {
14467
- const [x1, y1, x2, y2] = getElementBounds(element, elementsMap);
14468
- const distance3 = pointDistance7(
14469
- pointFrom14((x1 + x2) / 2, (y1 + y2) / 2),
14470
- pointFrom14(from.x, from.y)
14471
- );
14472
- if (distance3 < minDistance) {
14473
- minDistance = distance3;
14474
- closestElement = element;
14475
- }
14476
- });
14477
- return getElementBounds(closestElement, elementsMap);
14478
- };
14479
14616
  var getCommonBoundingBox = (elements) => {
14480
14617
  const [minX, minY, maxX, maxY] = getCommonBounds(elements);
14481
14618
  return {
@@ -14503,7 +14640,7 @@ var getVisibleSceneBounds = ({
14503
14640
  -scrollY + height / zoom.value
14504
14641
  ];
14505
14642
  };
14506
- var getCenterForBounds = (bounds) => pointFrom14(
14643
+ var getCenterForBounds = (bounds) => pointFrom13(
14507
14644
  bounds[0] + (bounds[2] - bounds[0]) / 2,
14508
14645
  bounds[1] + (bounds[3] - bounds[1]) / 2
14509
14646
  );
@@ -14517,23 +14654,23 @@ var aabbForElement = (element, elementsMap, offset) => {
14517
14654
  midY: element.y + element.height / 2
14518
14655
  };
14519
14656
  const center = elementCenterPoint(element, elementsMap);
14520
- const [topLeftX, topLeftY] = pointRotateRads13(
14521
- pointFrom14(bbox.minX, bbox.minY),
14657
+ const [topLeftX, topLeftY] = pointRotateRads12(
14658
+ pointFrom13(bbox.minX, bbox.minY),
14522
14659
  center,
14523
14660
  element.angle
14524
14661
  );
14525
- const [topRightX, topRightY] = pointRotateRads13(
14526
- pointFrom14(bbox.maxX, bbox.minY),
14662
+ const [topRightX, topRightY] = pointRotateRads12(
14663
+ pointFrom13(bbox.maxX, bbox.minY),
14527
14664
  center,
14528
14665
  element.angle
14529
14666
  );
14530
- const [bottomRightX, bottomRightY] = pointRotateRads13(
14531
- pointFrom14(bbox.maxX, bbox.maxY),
14667
+ const [bottomRightX, bottomRightY] = pointRotateRads12(
14668
+ pointFrom13(bbox.maxX, bbox.maxY),
14532
14669
  center,
14533
14670
  element.angle
14534
14671
  );
14535
- const [bottomLeftX, bottomLeftY] = pointRotateRads13(
14536
- pointFrom14(bbox.minX, bbox.maxY),
14672
+ const [bottomLeftX, bottomLeftY] = pointRotateRads12(
14673
+ pointFrom13(bbox.minX, bbox.maxY),
14537
14674
  center,
14538
14675
  element.angle
14539
14676
  );
@@ -14565,19 +14702,224 @@ var doBoundsIntersect = (bounds1, bounds2) => {
14565
14702
  return minX1 < maxX2 && maxX1 > minX2 && minY1 < maxY2 && maxY1 > minY2;
14566
14703
  };
14567
14704
  var boundsContainBounds = (outerBounds, innerBounds) => [
14568
- pointFrom14(innerBounds[0], innerBounds[1]),
14569
- pointFrom14(innerBounds[0], innerBounds[3]),
14570
- pointFrom14(innerBounds[2], innerBounds[1]),
14571
- pointFrom14(innerBounds[2], innerBounds[3])
14705
+ pointFrom13(innerBounds[0], innerBounds[1]),
14706
+ pointFrom13(innerBounds[0], innerBounds[3]),
14707
+ pointFrom13(innerBounds[2], innerBounds[1]),
14708
+ pointFrom13(innerBounds[2], innerBounds[3])
14572
14709
  ].every((point) => pointInsideBoundsInclusive(point, outerBounds));
14710
+ var elementsOverlappingBBox = ({
14711
+ elements,
14712
+ elementsMap,
14713
+ bounds,
14714
+ type,
14715
+ excludeElementsInFrames,
14716
+ shouldIgnoreElementFromSelection: shouldIgnoreElementFromSelection2
14717
+ }) => {
14718
+ if (!elementsMap) {
14719
+ elementsMap = arrayToMap6(elements);
14720
+ }
14721
+ const selectionBounds = isExcalidrawElement(bounds) ? getElementBounds(bounds, elementsMap) : bounds;
14722
+ const [selectionX1, selectionY1, selectionX2, selectionY2] = selectionBounds;
14723
+ const selectionEdges = [
14724
+ lineSegment6(
14725
+ pointFrom13(selectionX1, selectionY1),
14726
+ pointFrom13(selectionX2, selectionY1)
14727
+ ),
14728
+ lineSegment6(
14729
+ pointFrom13(selectionX2, selectionY1),
14730
+ pointFrom13(selectionX2, selectionY2)
14731
+ ),
14732
+ lineSegment6(
14733
+ pointFrom13(selectionX2, selectionY2),
14734
+ pointFrom13(selectionX1, selectionY2)
14735
+ ),
14736
+ lineSegment6(
14737
+ pointFrom13(selectionX1, selectionY2),
14738
+ pointFrom13(selectionX1, selectionY1)
14739
+ )
14740
+ ];
14741
+ const framesInSelection = excludeElementsInFrames ? /* @__PURE__ */ new Set() : null;
14742
+ const groups = {};
14743
+ const elementsInSelection = /* @__PURE__ */ new Set();
14744
+ for (const element of elements) {
14745
+ if (shouldIgnoreElementFromSelection2?.(element)) {
14746
+ continue;
14747
+ }
14748
+ const groupId = element.groupIds.at(-1);
14749
+ if (groupId) {
14750
+ if (!groups[groupId]) {
14751
+ groups[groupId] = [];
14752
+ }
14753
+ groups[groupId].push(element);
14754
+ }
14755
+ const strokeWidth = element.strokeWidth;
14756
+ let labelAABB = null;
14757
+ let elementAABB = getElementBounds(element, elementsMap);
14758
+ elementAABB = [
14759
+ elementAABB[0] - strokeWidth / 2,
14760
+ elementAABB[1] - strokeWidth / 2,
14761
+ elementAABB[2] + strokeWidth / 2,
14762
+ elementAABB[3] + strokeWidth / 2
14763
+ ];
14764
+ const boundTextElement = isArrowElement(element) && getBoundTextElement(element, elementsMap);
14765
+ if (boundTextElement) {
14766
+ const { x, y } = LinearElementEditor.getBoundTextElementPosition(
14767
+ element,
14768
+ boundTextElement,
14769
+ elementsMap
14770
+ );
14771
+ labelAABB = [
14772
+ x,
14773
+ y,
14774
+ x + boundTextElement.width,
14775
+ y + boundTextElement.height
14776
+ ];
14777
+ }
14778
+ const associatedFrame = getContainingFrame(element, elementsMap);
14779
+ if (associatedFrame && elementOverlapsWithFrame(element, associatedFrame, elementsMap)) {
14780
+ const frameAABB = getElementBounds(associatedFrame, elementsMap);
14781
+ elementAABB = [
14782
+ Math.max(elementAABB[0], frameAABB[0]),
14783
+ Math.max(elementAABB[1], frameAABB[1]),
14784
+ Math.min(elementAABB[2], frameAABB[2]),
14785
+ Math.min(elementAABB[3], frameAABB[3])
14786
+ ];
14787
+ labelAABB = labelAABB ? [
14788
+ Math.max(labelAABB[0], frameAABB[0]),
14789
+ Math.max(labelAABB[1], frameAABB[1]),
14790
+ Math.min(labelAABB[2], frameAABB[2]),
14791
+ Math.min(labelAABB[3], frameAABB[3])
14792
+ ] : null;
14793
+ }
14794
+ const commonAABB2 = labelAABB ? [
14795
+ Math.min(labelAABB[0], elementAABB[0]),
14796
+ Math.min(labelAABB[1], elementAABB[1]),
14797
+ Math.max(labelAABB[2], elementAABB[2]),
14798
+ Math.max(labelAABB[3], elementAABB[3])
14799
+ ] : elementAABB;
14800
+ if (boundsContainBounds(selectionBounds, commonAABB2)) {
14801
+ if (framesInSelection && isFrameLikeElement(element)) {
14802
+ framesInSelection.add(element.id);
14803
+ }
14804
+ elementsInSelection.add(element);
14805
+ continue;
14806
+ }
14807
+ if (type === "overlap" && labelAABB && doBoundsIntersect(selectionBounds, labelAABB)) {
14808
+ elementsInSelection.add(element);
14809
+ continue;
14810
+ }
14811
+ if (type === "overlap" && doBoundsIntersect(selectionBounds, elementAABB)) {
14812
+ let hasIntersection = false;
14813
+ if (isLinearElement(element) || isFreeDrawElement(element)) {
14814
+ const center = elementCenterPoint(element, elementsMap);
14815
+ hasIntersection = element.points.some((point) => {
14816
+ const rotatedPoint = pointRotateRads12(
14817
+ pointFrom13(element.x + point[0], element.y + point[1]),
14818
+ center,
14819
+ element.angle
14820
+ );
14821
+ return pointInsideBounds(rotatedPoint, selectionBounds);
14822
+ });
14823
+ } else {
14824
+ const nonRotatedElementBounds = getElementBounds(
14825
+ element,
14826
+ elementsMap,
14827
+ true
14828
+ );
14829
+ const center = elementCenterPoint(element, elementsMap);
14830
+ hasIntersection = [
14831
+ pointRotateRads12(
14832
+ pointFrom13(
14833
+ (nonRotatedElementBounds[0] + nonRotatedElementBounds[2]) / 2,
14834
+ nonRotatedElementBounds[1]
14835
+ ),
14836
+ center,
14837
+ element.angle
14838
+ ),
14839
+ pointRotateRads12(
14840
+ pointFrom13(
14841
+ nonRotatedElementBounds[2],
14842
+ (nonRotatedElementBounds[1] + nonRotatedElementBounds[3]) / 2
14843
+ ),
14844
+ center,
14845
+ element.angle
14846
+ ),
14847
+ pointRotateRads12(
14848
+ pointFrom13(
14849
+ (nonRotatedElementBounds[0] + nonRotatedElementBounds[2]) / 2,
14850
+ nonRotatedElementBounds[3]
14851
+ ),
14852
+ center,
14853
+ element.angle
14854
+ ),
14855
+ pointRotateRads12(
14856
+ pointFrom13(
14857
+ nonRotatedElementBounds[0],
14858
+ (nonRotatedElementBounds[1] + nonRotatedElementBounds[3]) / 2
14859
+ ),
14860
+ center,
14861
+ element.angle
14862
+ )
14863
+ ].some((point) => {
14864
+ return pointInsideBounds(
14865
+ pointRotateRads12(point, center, element.angle),
14866
+ selectionBounds
14867
+ );
14868
+ });
14869
+ }
14870
+ if (!hasIntersection) {
14871
+ hasIntersection = selectionEdges.some(
14872
+ (selectionEdge) => intersectElementWithLineSegment(
14873
+ element,
14874
+ elementsMap,
14875
+ selectionEdge,
14876
+ strokeWidth / 2,
14877
+ true
14878
+ // Stop at first hit for better performance
14879
+ ).length > 0
14880
+ );
14881
+ }
14882
+ if (hasIntersection) {
14883
+ if (framesInSelection && isFrameLikeElement(element)) {
14884
+ framesInSelection.add(element.id);
14885
+ }
14886
+ elementsInSelection.add(element);
14887
+ continue;
14888
+ }
14889
+ }
14890
+ }
14891
+ if (framesInSelection) {
14892
+ elementsInSelection.forEach((element) => {
14893
+ if (element.frameId && framesInSelection.has(element.frameId)) {
14894
+ elementsInSelection.delete(element);
14895
+ }
14896
+ });
14897
+ }
14898
+ if (type === "overlap") {
14899
+ Array.from(elementsInSelection).forEach((element) => {
14900
+ const groupId = element.groupIds.at(-1);
14901
+ const group = groupId ? groups[groupId] : null;
14902
+ group?.forEach((groupElement) => elementsInSelection.add(groupElement));
14903
+ });
14904
+ } else if (type === "contain") {
14905
+ elementsInSelection.forEach((element) => {
14906
+ const groupId = element.groupIds.at(-1);
14907
+ const group = groupId ? groups[groupId] : null;
14908
+ if (group && !group.every((groupElement) => elementsInSelection.has(groupElement))) {
14909
+ elementsInSelection.delete(element);
14910
+ }
14911
+ });
14912
+ }
14913
+ return elements.filter((element) => elementsInSelection.has(element));
14914
+ };
14573
14915
  var elementCenterPoint = (element, elementsMap, xOffset = 0, yOffset = 0) => {
14574
14916
  if (isLinearElement(element) || isFreeDrawElement(element)) {
14575
14917
  const [x1, y1, x2, y2] = getElementAbsoluteCoords2(element, elementsMap);
14576
- const [x3, y3] = pointFrom14((x1 + x2) / 2, (y1 + y2) / 2);
14577
- return pointFrom14(x3 + xOffset, y3 + yOffset);
14918
+ const [x3, y3] = pointFrom13((x1 + x2) / 2, (y1 + y2) / 2);
14919
+ return pointFrom13(x3 + xOffset, y3 + yOffset);
14578
14920
  }
14579
14921
  const [x, y] = getCenterForBounds(getElementBounds(element, elementsMap));
14580
- return pointFrom14(x + xOffset, y + yOffset);
14922
+ return pointFrom13(x + xOffset, y + yOffset);
14581
14923
  };
14582
14924
 
14583
14925
  // src/sizeHelpers.ts
@@ -14648,18 +14990,18 @@ var getPerfectElementSize = (elementType, width, height) => {
14648
14990
  var getLockedLinearCursorAlignSize = (originX, originY, x, y, customAngle) => {
14649
14991
  let width = x - originX;
14650
14992
  let height = y - originY;
14651
- const angle = Math.atan2(height, width);
14652
- let lockedAngle = Math.round(angle / SHIFT_LOCKING_ANGLE) * SHIFT_LOCKING_ANGLE;
14993
+ const angle2 = Math.atan2(height, width);
14994
+ let lockedAngle = Math.round(angle2 / SHIFT_LOCKING_ANGLE) * SHIFT_LOCKING_ANGLE;
14653
14995
  if (customAngle) {
14654
14996
  const lower = Math.floor(customAngle / SHIFT_LOCKING_ANGLE) * SHIFT_LOCKING_ANGLE;
14655
14997
  if (radiansBetweenAngles(
14656
- angle,
14998
+ angle2,
14657
14999
  lower,
14658
15000
  lower + SHIFT_LOCKING_ANGLE
14659
15001
  )) {
14660
- if (radiansDifference(angle, customAngle) < SHIFT_LOCKING_ANGLE / 6) {
15002
+ if (radiansDifference(angle2, customAngle) < SHIFT_LOCKING_ANGLE / 6) {
14661
15003
  lockedAngle = customAngle;
14662
- } else if (normalizeRadians(angle) > normalizeRadians(customAngle)) {
15004
+ } else if (normalizeRadians(angle2) > normalizeRadians(customAngle)) {
14663
15005
  lockedAngle = lower + SHIFT_LOCKING_ANGLE;
14664
15006
  } else {
14665
15007
  lockedAngle = lower;
@@ -14711,7 +15053,7 @@ var alignElements = (selectedElements, alignment, scene, appState) => {
14711
15053
  selectedElements,
14712
15054
  scene.getNonDeletedElementsMap(),
14713
15055
  appState
14714
- );
15056
+ ).map(getNonDeletedElements);
14715
15057
  const selectionBoundingBox = getCommonBoundingBox(selectedElements);
14716
15058
  return groups.flatMap((group) => {
14717
15059
  const translation = calculateTranslation(
@@ -14913,6 +15255,11 @@ var duplicateElements = (opts) => {
14913
15255
  return acc;
14914
15256
  }
14915
15257
  processedIds.set(element2.id, true);
15258
+ if (!isNonDeletedElement(element2)) {
15259
+ console.error(
15260
+ "[NONDELETED][INVARIANT] Element to duplicate should be non-deleted"
15261
+ );
15262
+ }
14916
15263
  const newElement2 = duplicateElement(
14917
15264
  appState.editingGroupId,
14918
15265
  groupIdMap,
@@ -15768,7 +16115,7 @@ import {
15768
16115
  isTestEnv as isTestEnv6,
15769
16116
  toArray
15770
16117
  } from "@excalidraw/common";
15771
- import { isNonDeletedElement } from "@excalidraw/element";
16118
+ import { isNonDeletedElement as isNonDeletedElement2 } from "@excalidraw/element";
15772
16119
  import { isFrameLikeElement as isFrameLikeElement2 } from "@excalidraw/element";
15773
16120
  import { getElementsInGroup as getElementsInGroup2 } from "@excalidraw/element";
15774
16121
  import {
@@ -15778,7 +16125,7 @@ import {
15778
16125
  } from "@excalidraw/element";
15779
16126
  import { getSelectedElements as getSelectedElements2 } from "@excalidraw/element";
15780
16127
  import { mutateElement as mutateElement2 } from "@excalidraw/element";
15781
- var getNonDeletedElements = (allElements) => {
16128
+ var getNonDeletedElements2 = (allElements) => {
15782
16129
  const elementsMap = /* @__PURE__ */ new Map();
15783
16130
  const elements = [];
15784
16131
  for (const element of allElements) {
@@ -15893,7 +16240,7 @@ var Scene = class {
15893
16240
  }
15894
16241
  getNonDeletedElement(id) {
15895
16242
  const element = this.getElement(id);
15896
- if (element && isNonDeletedElement(element)) {
16243
+ if (element && isNonDeletedElement2(element)) {
15897
16244
  return element;
15898
16245
  }
15899
16246
  return null;
@@ -15938,11 +16285,11 @@ var Scene = class {
15938
16285
  }
15939
16286
  this.elementsMap.set(element.id, element);
15940
16287
  });
15941
- const nonDeletedElements = getNonDeletedElements(this.elements);
16288
+ const nonDeletedElements = getNonDeletedElements2(this.elements);
15942
16289
  this.nonDeletedElements = nonDeletedElements.elements;
15943
16290
  this.nonDeletedElementsMap = nonDeletedElements.elementsMap;
15944
16291
  this.frames = nextFrameLikes;
15945
- this.nonDeletedFramesLikes = getNonDeletedElements(this.frames).elements;
16292
+ this.nonDeletedFramesLikes = getNonDeletedElements2(this.frames).elements;
15946
16293
  this.triggerUpdate();
15947
16294
  }
15948
16295
  triggerUpdate() {
@@ -17271,9 +17618,14 @@ var ElementsDelta = class _ElementsDelta {
17271
17618
  static redrawBoundArrows(scene, changed) {
17272
17619
  for (const element of changed.values()) {
17273
17620
  if (!element.isDeleted && isBindableElement(element)) {
17274
- updateBoundElements(element, scene, {
17275
- changedElements: changed
17276
- });
17621
+ updateBoundElements(
17622
+ element,
17623
+ // NOTE: Assumed correct, no runtime check for isDeleted due to performance reasons
17624
+ scene,
17625
+ {
17626
+ changedElements: changed
17627
+ }
17628
+ );
17277
17629
  }
17278
17630
  }
17279
17631
  }
@@ -17335,7 +17687,7 @@ var distributeElements = (selectedElements, elementsMap, distribution, appState,
17335
17687
  selectedElements,
17336
17688
  elementsMap,
17337
17689
  appState
17338
- ).map((group) => [group, getCommonBoundingBox(group)]).sort((a2, b2) => a2[1][mid] - b2[1][mid]);
17690
+ ).map(getNonDeletedElements).map((group) => [group, getCommonBoundingBox(group)]).sort((a2, b2) => a2[1][mid] - b2[1][mid]);
17339
17691
  let span = 0;
17340
17692
  for (const group of groups) {
17341
17693
  span += group[1][extent];
@@ -17692,6 +18044,7 @@ import {
17692
18044
  DEFAULT_FONT_SIZE as DEFAULT_FONT_SIZE3,
17693
18045
  DEFAULT_TEXT_ALIGN,
17694
18046
  DEFAULT_VERTICAL_ALIGN,
18047
+ DEFAULT_STROKE_STREAMLINE as DEFAULT_STROKE_STREAMLINE2,
17695
18048
  VERTICAL_ALIGN as VERTICAL_ALIGN2,
17696
18049
  randomInteger as randomInteger5,
17697
18050
  randomId as randomId3,
@@ -17711,7 +18064,7 @@ var _newElementBase = (type, {
17711
18064
  opacity = DEFAULT_ELEMENT_PROPS.opacity,
17712
18065
  width = 0,
17713
18066
  height = 0,
17714
- angle = 0,
18067
+ angle: angle2 = 0,
17715
18068
  groupIds = [],
17716
18069
  frameId = null,
17717
18070
  index = null,
@@ -17738,7 +18091,7 @@ var _newElementBase = (type, {
17738
18091
  y,
17739
18092
  width,
17740
18093
  height,
17741
- angle,
18094
+ angle: angle2,
17742
18095
  strokeColor,
17743
18096
  backgroundColor,
17744
18097
  fillStyle,
@@ -17895,9 +18248,9 @@ var getAdjustedDimensions = (element, elementsMap, nextText) => {
17895
18248
  y: Number.isFinite(y) ? y : element.y
17896
18249
  };
17897
18250
  };
17898
- var adjustXYWithRotation = (sides, x, y, angle, deltaX1, deltaY1, deltaX2, deltaY2) => {
17899
- const cos = Math.cos(angle);
17900
- const sin = Math.sin(angle);
18251
+ var adjustXYWithRotation = (sides, x, y, angle2, deltaX1, deltaY1, deltaX2, deltaY2) => {
18252
+ const cos = Math.cos(angle2);
18253
+ const sin = Math.sin(angle2);
17901
18254
  if (sides.e && sides.w) {
17902
18255
  x += deltaX1 + deltaX2;
17903
18256
  } else if (sides.e) {
@@ -17945,7 +18298,11 @@ var newFreeDrawElement = (opts) => {
17945
18298
  ..._newElementBase(opts.type, opts),
17946
18299
  points: opts.points || [],
17947
18300
  pressures: opts.pressures || [],
17948
- simulatePressure: opts.simulatePressure
18301
+ simulatePressure: opts.simulatePressure,
18302
+ strokeOptions: opts.strokeOptions ?? {
18303
+ variability: "variable",
18304
+ streamline: DEFAULT_STROKE_STREAMLINE2
18305
+ }
17949
18306
  };
17950
18307
  };
17951
18308
  var newLinearElement = (opts) => {
@@ -18414,7 +18771,7 @@ var embeddableURLValidator = (url, validateEmbeddable) => {
18414
18771
  // src/flowchart.ts
18415
18772
  init_define_import_meta_env();
18416
18773
  import { KEYS as KEYS2, invariant as invariant11, toBrandedType as toBrandedType2 } from "@excalidraw/common";
18417
- import { pointFrom as pointFrom15 } from "@excalidraw/math";
18774
+ import { pointFrom as pointFrom14 } from "@excalidraw/math";
18418
18775
  var VERTICAL_OFFSET = 100;
18419
18776
  var HORIZONTAL_OFFSET = 100;
18420
18777
  var getLinkDirectionFromKey = (key) => {
@@ -18694,7 +19051,7 @@ var createBindingArrow = (startBindingElement, endBindingElement, direction, app
18694
19051
  strokeWidth: startBindingElement.strokeWidth,
18695
19052
  opacity: startBindingElement.opacity,
18696
19053
  roughness: startBindingElement.roughness,
18697
- points: [pointFrom15(0, 0), pointFrom15(endX, endY)],
19054
+ points: [pointFrom14(0, 0), pointFrom14(endX, endY)],
18698
19055
  elbowed: true
18699
19056
  });
18700
19057
  const elementsMap = scene.getNonDeletedElementsMap();
@@ -18745,7 +19102,8 @@ var createBindingArrow = (startBindingElement, endBindingElement, direction, app
18745
19102
  );
18746
19103
  return {
18747
19104
  ...bindingArrow,
18748
- ...update
19105
+ ...update,
19106
+ isDeleted: bindingArrow.isDeleted
18749
19107
  };
18750
19108
  };
18751
19109
  var FlowChartNavigator = class {
@@ -18882,12 +19240,13 @@ var isNodeInFlowchart = (element, elementsMap) => {
18882
19240
 
18883
19241
  // src/arrows/focus.ts
18884
19242
  init_define_import_meta_env();
18885
- import { pointDistance as pointDistance8, pointFrom as pointFrom16 } from "@excalidraw/math";
19243
+ import { pointDistance as pointDistance7, pointFrom as pointFrom15 } from "@excalidraw/math";
18886
19244
  import { invariant as invariant12 } from "@excalidraw/common";
18887
19245
 
18888
19246
  // src/zindex.ts
18889
19247
  init_define_import_meta_env();
18890
19248
  import { arrayToMap as arrayToMap11, findIndex, findLastIndex as findLastIndex2 } from "@excalidraw/common";
19249
+ import { isFiniteNumber } from "@excalidraw/math";
18891
19250
  var isOfTargetFrame = (element, frameId) => {
18892
19251
  return element.frameId === frameId || element.id === frameId;
18893
19252
  };
@@ -18977,7 +19336,12 @@ var getContiguousFrameRangeElements = (allElements, frameId) => {
18977
19336
  return allElements.slice(rangeStart, rangeEnd + 1);
18978
19337
  };
18979
19338
  var moveArrowAboveBindable2 = (point, arrow, elements, elementsMap, scene, hit) => {
18980
- const hoveredElement = hit ? hit : getHoveredElementForBinding(point, elements, elementsMap);
19339
+ const hoveredElement = hit ? hit : getHoveredElementForBinding(
19340
+ point,
19341
+ // SAFETY: callers that omit `hit` pass non-deleted elements
19342
+ getNonDeletedElements(elements),
19343
+ elementsMap
19344
+ );
18981
19345
  if (!hoveredElement) {
18982
19346
  return elements;
18983
19347
  }
@@ -19067,7 +19431,34 @@ var getTargetElementsMap = (elements, indices) => {
19067
19431
  return acc;
19068
19432
  }, /* @__PURE__ */ new Map());
19069
19433
  };
19434
+ var hasSameElementIds = (prevElements, nextElements) => {
19435
+ if (prevElements.length !== nextElements.length) {
19436
+ console.error(
19437
+ "z-index reordering failed: resulting array have different lengths"
19438
+ );
19439
+ return false;
19440
+ }
19441
+ const prevElementIdCounts = /* @__PURE__ */ new Map();
19442
+ for (const element of prevElements) {
19443
+ prevElementIdCounts.set(
19444
+ element.id,
19445
+ (prevElementIdCounts.get(element.id) || 0) + 1
19446
+ );
19447
+ }
19448
+ for (const element of nextElements) {
19449
+ const count = prevElementIdCounts.get(element.id);
19450
+ if (!count) {
19451
+ console.error(
19452
+ "z-index reordering failed: element id mismatch / duplicate ids"
19453
+ );
19454
+ return false;
19455
+ }
19456
+ prevElementIdCounts.set(element.id, count - 1);
19457
+ }
19458
+ return true;
19459
+ };
19070
19460
  var shiftElementsByOne = (elements, appState, direction, scene) => {
19461
+ const originalElements = elements;
19071
19462
  const indicesToMove = getIndicesToMove(elements, appState);
19072
19463
  const targetElementsMap = getTargetElementsMap(elements, indicesToMove);
19073
19464
  let groupedIndices = toContiguousGroups(indicesToMove);
@@ -19112,11 +19503,17 @@ var shiftElementsByOne = (elements, appState, direction, scene) => {
19112
19503
  ...trailingElements
19113
19504
  ];
19114
19505
  });
19506
+ if (!hasSameElementIds(originalElements, elements)) {
19507
+ return originalElements;
19508
+ }
19115
19509
  syncMovedIndices(elements, targetElementsMap);
19116
19510
  return elements;
19117
19511
  };
19118
19512
  var shiftElementsToEnd = (elements, appState, direction, containingFrame, elementsToBeMoved) => {
19119
19513
  const indicesToMove = getIndicesToMove(elements, appState, elementsToBeMoved);
19514
+ if (indicesToMove.length === 0) {
19515
+ return elements;
19516
+ }
19120
19517
  const targetElementsMap = getTargetElementsMap(elements, indicesToMove);
19121
19518
  const displacedElements = [];
19122
19519
  let leadingIndex;
@@ -19163,6 +19560,12 @@ var shiftElementsToEnd = (elements, appState, direction, containingFrame, elemen
19163
19560
  if (leadingIndex === -1) {
19164
19561
  leadingIndex = 0;
19165
19562
  }
19563
+ const isValidIndex = (index) => {
19564
+ return isFiniteNumber(index) && index >= 0;
19565
+ };
19566
+ if (!isValidIndex(leadingIndex) || !isValidIndex(trailingIndex) || leadingIndex > trailingIndex || indicesToMove.some((index) => index < leadingIndex || index > trailingIndex)) {
19567
+ return elements;
19568
+ }
19166
19569
  for (let index = leadingIndex; index < trailingIndex + 1; index++) {
19167
19570
  if (!indicesToMove.includes(index)) {
19168
19571
  displacedElements.push(elements[index]);
@@ -19182,6 +19585,9 @@ var shiftElementsToEnd = (elements, appState, direction, containingFrame, elemen
19182
19585
  ...targetElements,
19183
19586
  ...trailingElements
19184
19587
  ];
19588
+ if (!hasSameElementIds(elements, nextElements)) {
19589
+ return elements;
19590
+ }
19185
19591
  syncMovedIndices(nextElements, targetElementsMap);
19186
19592
  return nextElements;
19187
19593
  };
@@ -19223,7 +19629,7 @@ function shiftElementsAccountingForFrames(allElements, appState, direction, shif
19223
19629
  );
19224
19630
  for (const [frameId, children] of frameChildrenSets) {
19225
19631
  nextElements = shiftFunction(
19226
- allElements,
19632
+ nextElements,
19227
19633
  appState,
19228
19634
  direction,
19229
19635
  frameId,
@@ -19273,7 +19679,7 @@ var isFocusPointVisible = (focusPoint, arrow, bindableElement, elementsMap, appS
19273
19679
  associatedPointIdx,
19274
19680
  elementsMap
19275
19681
  );
19276
- if (pointDistance8(focusPoint, associatedArrowPoint) < FOCUS_POINT_SIZE * 1.5 / appState.zoom.value) {
19682
+ if (pointDistance7(focusPoint, associatedArrowPoint) < FOCUS_POINT_SIZE * 1.5 / appState.zoom.value) {
19277
19683
  return false;
19278
19684
  }
19279
19685
  }
@@ -19282,7 +19688,7 @@ var isFocusPointVisible = (focusPoint, arrow, bindableElement, elementsMap, appS
19282
19688
  startOrEnd === "end" ? arrow.points.length - 1 : 0,
19283
19689
  elementsMap
19284
19690
  );
19285
- return pointDistance8(focusPoint, arrowPoint) >= FOCUS_POINT_SIZE * 1.5 / appState.zoom.value && hitElementItself({
19691
+ return pointDistance7(focusPoint, arrowPoint) >= FOCUS_POINT_SIZE * 1.5 / appState.zoom.value && hitElementItself({
19286
19692
  element: bindableElement,
19287
19693
  elementsMap,
19288
19694
  point: focusPoint,
@@ -19372,7 +19778,7 @@ var handleFocusPointDrag = (linearElementEditor, elementsMap, pointerCoords, sce
19372
19778
  const isStartBinding = linearElementEditor.draggedFocusPointBinding === "start";
19373
19779
  const binding = isStartBinding ? arrow.startBinding : arrow.endBinding;
19374
19780
  const { x: offsetX, y: offsetY } = linearElementEditor.pointerOffset;
19375
- const point = pointFrom16(
19781
+ const point = pointFrom15(
19376
19782
  pointerCoords.x - offsetX,
19377
19783
  pointerCoords.y - offsetY
19378
19784
  );
@@ -19455,7 +19861,7 @@ var handleFocusPointDrag = (linearElementEditor, elementsMap, pointerCoords, sce
19455
19861
  }
19456
19862
  };
19457
19863
  var handleFocusPointPointerDown = (arrow, pointerDownState, elementsMap, appState) => {
19458
- const pointerPos = pointFrom16(
19864
+ const pointerPos = pointFrom15(
19459
19865
  pointerDownState.origin.x,
19460
19866
  pointerDownState.origin.y
19461
19867
  );
@@ -19475,7 +19881,7 @@ var handleFocusPointPointerDown = (arrow, pointerDownState, elementsMap, appStat
19475
19881
  elementsMap,
19476
19882
  appState,
19477
19883
  "start"
19478
- ) && pointDistance8(pointerPos, focusPoint) <= hitThreshold) {
19884
+ ) && pointDistance7(pointerPos, focusPoint) <= hitThreshold) {
19479
19885
  return {
19480
19886
  hitFocusPoint: "start",
19481
19887
  pointerOffset: {
@@ -19501,7 +19907,7 @@ var handleFocusPointPointerDown = (arrow, pointerDownState, elementsMap, appStat
19501
19907
  elementsMap,
19502
19908
  appState,
19503
19909
  "end"
19504
- ) && pointDistance8(pointerPos, focusPoint) <= hitThreshold) {
19910
+ ) && pointDistance7(pointerPos, focusPoint) <= hitThreshold) {
19505
19911
  return {
19506
19912
  hitFocusPoint: "end",
19507
19913
  pointerOffset: {
@@ -19558,7 +19964,7 @@ var handleFocusPointPointerUp = (linearElementEditor, scene) => {
19558
19964
  };
19559
19965
  var handleFocusPointHover = (arrow, scenePointerX, scenePointerY, scene, appState) => {
19560
19966
  const elementsMap = scene.getNonDeletedElementsMap();
19561
- const pointerPos = pointFrom16(scenePointerX, scenePointerY);
19967
+ const pointerPos = pointFrom15(scenePointerX, scenePointerY);
19562
19968
  const hitThreshold = FOCUS_POINT_SIZE * 1.5 / appState.zoom.value;
19563
19969
  if (arrow.startBinding?.elementId) {
19564
19970
  const bindableElement = elementsMap.get(arrow.startBinding.elementId);
@@ -19575,7 +19981,7 @@ var handleFocusPointHover = (arrow, scenePointerX, scenePointerY, scene, appStat
19575
19981
  elementsMap,
19576
19982
  appState,
19577
19983
  "start"
19578
- ) && pointDistance8(pointerPos, focusPoint) <= hitThreshold) {
19984
+ ) && pointDistance7(pointerPos, focusPoint) <= hitThreshold) {
19579
19985
  return "start";
19580
19986
  }
19581
19987
  }
@@ -19595,7 +20001,7 @@ var handleFocusPointHover = (arrow, scenePointerX, scenePointerY, scene, appStat
19595
20001
  elementsMap,
19596
20002
  appState,
19597
20003
  "end"
19598
- ) && pointDistance8(pointerPos, focusPoint) <= hitThreshold) {
20004
+ ) && pointDistance7(pointerPos, focusPoint) <= hitThreshold) {
19599
20005
  return "end";
19600
20006
  }
19601
20007
  }
@@ -19779,8 +20185,8 @@ init_define_import_meta_env();
19779
20185
  import {
19780
20186
  pointCenter as pointCenter3,
19781
20187
  normalizeRadians as normalizeRadians2,
19782
- pointFrom as pointFrom17,
19783
- pointRotateRads as pointRotateRads14
20188
+ pointFrom as pointFrom16,
20189
+ pointRotateRads as pointRotateRads13
19784
20190
  } from "@excalidraw/math";
19785
20191
  import {
19786
20192
  MIN_FONT_SIZE,
@@ -19892,20 +20298,20 @@ var rotateSingleElement = (element, scene, pointerX, pointerY, shouldRotateWithD
19892
20298
  );
19893
20299
  const cx = (x1 + x2) / 2;
19894
20300
  const cy = (y1 + y2) / 2;
19895
- let angle;
20301
+ let angle2;
19896
20302
  if (isFrameLikeElement(element)) {
19897
- angle = 0;
20303
+ angle2 = 0;
19898
20304
  } else {
19899
- angle = 5 * Math.PI / 2 + Math.atan2(pointerY - cy, pointerX - cx);
20305
+ angle2 = 5 * Math.PI / 2 + Math.atan2(pointerY - cy, pointerX - cx);
19900
20306
  if (shouldRotateWithDiscreteAngle2) {
19901
- angle = angle + SHIFT_LOCKING_ANGLE2 / 2;
19902
- angle = angle - angle % SHIFT_LOCKING_ANGLE2;
20307
+ angle2 = angle2 + SHIFT_LOCKING_ANGLE2 / 2;
20308
+ angle2 = angle2 - angle2 % SHIFT_LOCKING_ANGLE2;
19903
20309
  }
19904
- angle = normalizeRadians2(angle);
20310
+ angle2 = normalizeRadians2(angle2);
19905
20311
  }
19906
20312
  const boundTextElementId = getBoundTextElementId(element);
19907
20313
  let update = {
19908
- angle
20314
+ angle: angle2
19909
20315
  };
19910
20316
  if (isBindingElement(element)) {
19911
20317
  update = {
@@ -19928,7 +20334,7 @@ var rotateSingleElement = (element, scene, pointerX, pointerY, shouldRotateWithD
19928
20334
  scene.getNonDeletedElementsMap()
19929
20335
  );
19930
20336
  scene.mutateElement(textElement, {
19931
- angle,
20337
+ angle: angle2,
19932
20338
  x,
19933
20339
  y
19934
20340
  });
@@ -19968,7 +20374,7 @@ var resizeSingleTextElement = (origElement, element, scene, transformHandleType,
19968
20374
  return;
19969
20375
  }
19970
20376
  if (transformHandleType.includes("n") || transformHandleType.includes("s")) {
19971
- const previousOrigin = pointFrom17(origElement.x, origElement.y);
20377
+ const previousOrigin = pointFrom16(origElement.x, origElement.y);
19972
20378
  const newOrigin = getResizedOrigin(
19973
20379
  previousOrigin,
19974
20380
  origElement.width,
@@ -20009,7 +20415,7 @@ var resizeSingleTextElement = (origElement, element, scene, transformHandleType,
20009
20415
  element.lineHeight
20010
20416
  );
20011
20417
  const newHeight = metrics2.height;
20012
- const previousOrigin = pointFrom17(origElement.x, origElement.y);
20418
+ const previousOrigin = pointFrom16(origElement.x, origElement.y);
20013
20419
  const newOrigin = getResizedOrigin(
20014
20420
  previousOrigin,
20015
20421
  origElement.width,
@@ -20046,9 +20452,9 @@ var rotateMultipleElements = (originalElements, elements, scene, pointerX, point
20046
20452
  const cx = (x1 + x2) / 2;
20047
20453
  const cy = (y1 + y2) / 2;
20048
20454
  const origAngle = originalElements.get(element.id)?.angle ?? element.angle;
20049
- const [rotatedCX, rotatedCY] = pointRotateRads14(
20050
- pointFrom17(cx, cy),
20051
- pointFrom17(centerX, centerY),
20455
+ const [rotatedCX, rotatedCY] = pointRotateRads13(
20456
+ pointFrom16(cx, cy),
20457
+ pointFrom16(centerX, centerY),
20052
20458
  centerAngle + origAngle - element.angle
20053
20459
  );
20054
20460
  const updates = isElbowArrow(element) ? {
@@ -20096,45 +20502,45 @@ var getResizeOffsetXY = (transformHandleType, selectedElements, elementsMap, x,
20096
20502
  const [x1, y1, x2, y2] = selectedElements.length === 1 ? getElementAbsoluteCoords2(selectedElements[0], elementsMap) : getCommonBounds(selectedElements);
20097
20503
  const cx = (x1 + x2) / 2;
20098
20504
  const cy = (y1 + y2) / 2;
20099
- const angle = selectedElements.length === 1 ? selectedElements[0].angle : 0;
20100
- [x, y] = pointRotateRads14(
20101
- pointFrom17(x, y),
20102
- pointFrom17(cx, cy),
20103
- -angle
20505
+ const angle2 = selectedElements.length === 1 ? selectedElements[0].angle : 0;
20506
+ [x, y] = pointRotateRads13(
20507
+ pointFrom16(x, y),
20508
+ pointFrom16(cx, cy),
20509
+ -angle2
20104
20510
  );
20105
20511
  switch (transformHandleType) {
20106
20512
  case "n":
20107
- return pointRotateRads14(
20108
- pointFrom17(x - (x1 + x2) / 2, y - y1),
20109
- pointFrom17(0, 0),
20110
- angle
20513
+ return pointRotateRads13(
20514
+ pointFrom16(x - (x1 + x2) / 2, y - y1),
20515
+ pointFrom16(0, 0),
20516
+ angle2
20111
20517
  );
20112
20518
  case "s":
20113
- return pointRotateRads14(
20114
- pointFrom17(x - (x1 + x2) / 2, y - y2),
20115
- pointFrom17(0, 0),
20116
- angle
20519
+ return pointRotateRads13(
20520
+ pointFrom16(x - (x1 + x2) / 2, y - y2),
20521
+ pointFrom16(0, 0),
20522
+ angle2
20117
20523
  );
20118
20524
  case "w":
20119
- return pointRotateRads14(
20120
- pointFrom17(x - x1, y - (y1 + y2) / 2),
20121
- pointFrom17(0, 0),
20122
- angle
20525
+ return pointRotateRads13(
20526
+ pointFrom16(x - x1, y - (y1 + y2) / 2),
20527
+ pointFrom16(0, 0),
20528
+ angle2
20123
20529
  );
20124
20530
  case "e":
20125
- return pointRotateRads14(
20126
- pointFrom17(x - x2, y - (y1 + y2) / 2),
20127
- pointFrom17(0, 0),
20128
- angle
20531
+ return pointRotateRads13(
20532
+ pointFrom16(x - x2, y - (y1 + y2) / 2),
20533
+ pointFrom16(0, 0),
20534
+ angle2
20129
20535
  );
20130
20536
  case "nw":
20131
- return pointRotateRads14(pointFrom17(x - x1, y - y1), pointFrom17(0, 0), angle);
20537
+ return pointRotateRads13(pointFrom16(x - x1, y - y1), pointFrom16(0, 0), angle2);
20132
20538
  case "ne":
20133
- return pointRotateRads14(pointFrom17(x - x2, y - y1), pointFrom17(0, 0), angle);
20539
+ return pointRotateRads13(pointFrom16(x - x2, y - y1), pointFrom16(0, 0), angle2);
20134
20540
  case "sw":
20135
- return pointRotateRads14(pointFrom17(x - x1, y - y2), pointFrom17(0, 0), angle);
20541
+ return pointRotateRads13(pointFrom16(x - x1, y - y2), pointFrom16(0, 0), angle2);
20136
20542
  case "se":
20137
- return pointRotateRads14(pointFrom17(x - x2, y - y2), pointFrom17(0, 0), angle);
20543
+ return pointRotateRads13(pointFrom16(x - x2, y - y2), pointFrom16(0, 0), angle2);
20138
20544
  default:
20139
20545
  return [0, 0];
20140
20546
  }
@@ -20178,7 +20584,7 @@ var getResizeAnchor = (handleDirection, shouldMaintainAspectRatio, shouldResizeF
20178
20584
  }
20179
20585
  return "top-right";
20180
20586
  };
20181
- var getResizedOrigin = (prevOrigin, prevWidth, prevHeight, newWidth, newHeight, angle, handleDirection, shouldMaintainAspectRatio, shouldResizeFromCenter) => {
20587
+ var getResizedOrigin = (prevOrigin, prevWidth, prevHeight, newWidth, newHeight, angle2, handleDirection, shouldMaintainAspectRatio, shouldResizeFromCenter) => {
20182
20588
  const anchor = getResizeAnchor(
20183
20589
  handleDirection,
20184
20590
  shouldMaintainAspectRatio,
@@ -20188,23 +20594,23 @@ var getResizedOrigin = (prevOrigin, prevWidth, prevHeight, newWidth, newHeight,
20188
20594
  switch (anchor) {
20189
20595
  case "top-left":
20190
20596
  return {
20191
- x: x + (prevWidth - newWidth) / 2 + (newWidth - prevWidth) / 2 * Math.cos(angle) + (prevHeight - newHeight) / 2 * Math.sin(angle),
20192
- y: y + (prevHeight - newHeight) / 2 + (newWidth - prevWidth) / 2 * Math.sin(angle) + (newHeight - prevHeight) / 2 * Math.cos(angle)
20597
+ x: x + (prevWidth - newWidth) / 2 + (newWidth - prevWidth) / 2 * Math.cos(angle2) + (prevHeight - newHeight) / 2 * Math.sin(angle2),
20598
+ y: y + (prevHeight - newHeight) / 2 + (newWidth - prevWidth) / 2 * Math.sin(angle2) + (newHeight - prevHeight) / 2 * Math.cos(angle2)
20193
20599
  };
20194
20600
  case "top-right":
20195
20601
  return {
20196
- x: x + (prevWidth - newWidth) / 2 * (Math.cos(angle) + 1) + (prevHeight - newHeight) / 2 * Math.sin(angle),
20197
- y: y + (prevHeight - newHeight) / 2 + (prevWidth - newWidth) / 2 * Math.sin(angle) + (newHeight - prevHeight) / 2 * Math.cos(angle)
20602
+ x: x + (prevWidth - newWidth) / 2 * (Math.cos(angle2) + 1) + (prevHeight - newHeight) / 2 * Math.sin(angle2),
20603
+ y: y + (prevHeight - newHeight) / 2 + (prevWidth - newWidth) / 2 * Math.sin(angle2) + (newHeight - prevHeight) / 2 * Math.cos(angle2)
20198
20604
  };
20199
20605
  case "bottom-left":
20200
20606
  return {
20201
- x: x + (prevWidth - newWidth) / 2 * (1 - Math.cos(angle)) + (newHeight - prevHeight) / 2 * Math.sin(angle),
20202
- y: y + (prevHeight - newHeight) / 2 * (Math.cos(angle) + 1) + (newWidth - prevWidth) / 2 * Math.sin(angle)
20607
+ x: x + (prevWidth - newWidth) / 2 * (1 - Math.cos(angle2)) + (newHeight - prevHeight) / 2 * Math.sin(angle2),
20608
+ y: y + (prevHeight - newHeight) / 2 * (Math.cos(angle2) + 1) + (newWidth - prevWidth) / 2 * Math.sin(angle2)
20203
20609
  };
20204
20610
  case "bottom-right":
20205
20611
  return {
20206
- x: x + (prevWidth - newWidth) / 2 * (Math.cos(angle) + 1) + (newHeight - prevHeight) / 2 * Math.sin(angle),
20207
- y: y + (prevHeight - newHeight) / 2 * (Math.cos(angle) + 1) + (prevWidth - newWidth) / 2 * Math.sin(angle)
20612
+ x: x + (prevWidth - newWidth) / 2 * (Math.cos(angle2) + 1) + (newHeight - prevHeight) / 2 * Math.sin(angle2),
20613
+ y: y + (prevHeight - newHeight) / 2 * (Math.cos(angle2) + 1) + (prevWidth - newWidth) / 2 * Math.sin(angle2)
20208
20614
  };
20209
20615
  case "center":
20210
20616
  return {
@@ -20213,23 +20619,23 @@ var getResizedOrigin = (prevOrigin, prevWidth, prevHeight, newWidth, newHeight,
20213
20619
  };
20214
20620
  case "east-side":
20215
20621
  return {
20216
- x: x + (prevWidth - newWidth) / 2 * (Math.cos(angle) + 1),
20217
- y: y + (prevWidth - newWidth) / 2 * Math.sin(angle) + (prevHeight - newHeight) / 2
20622
+ x: x + (prevWidth - newWidth) / 2 * (Math.cos(angle2) + 1),
20623
+ y: y + (prevWidth - newWidth) / 2 * Math.sin(angle2) + (prevHeight - newHeight) / 2
20218
20624
  };
20219
20625
  case "west-side":
20220
20626
  return {
20221
- x: x + (prevWidth - newWidth) / 2 * (1 - Math.cos(angle)),
20222
- y: y + (newWidth - prevWidth) / 2 * Math.sin(angle) + (prevHeight - newHeight) / 2
20627
+ x: x + (prevWidth - newWidth) / 2 * (1 - Math.cos(angle2)),
20628
+ y: y + (newWidth - prevWidth) / 2 * Math.sin(angle2) + (prevHeight - newHeight) / 2
20223
20629
  };
20224
20630
  case "north-side":
20225
20631
  return {
20226
- x: x + (prevWidth - newWidth) / 2 + (prevHeight - newHeight) / 2 * Math.sin(angle),
20227
- y: y + (newHeight - prevHeight) / 2 * (Math.cos(angle) - 1)
20632
+ x: x + (prevWidth - newWidth) / 2 + (prevHeight - newHeight) / 2 * Math.sin(angle2),
20633
+ y: y + (newHeight - prevHeight) / 2 * (Math.cos(angle2) - 1)
20228
20634
  };
20229
20635
  case "south-side":
20230
20636
  return {
20231
- x: x + (prevWidth - newWidth) / 2 + (newHeight - prevHeight) / 2 * Math.sin(angle),
20232
- y: y + (prevHeight - newHeight) / 2 * (Math.cos(angle) + 1)
20637
+ x: x + (prevWidth - newWidth) / 2 + (newHeight - prevHeight) / 2 * Math.sin(angle2),
20638
+ y: y + (prevHeight - newHeight) / 2 * (Math.cos(angle2) + 1)
20233
20639
  };
20234
20640
  }
20235
20641
  };
@@ -20297,10 +20703,10 @@ var resizeSingleElement = (nextWidth, nextHeight, latestElement, origElement, or
20297
20703
  nextHeight,
20298
20704
  true
20299
20705
  );
20300
- let previousOrigin = pointFrom17(origElement.x, origElement.y);
20706
+ let previousOrigin = pointFrom16(origElement.x, origElement.y);
20301
20707
  if (isLinearElement(origElement)) {
20302
20708
  const [x1, y1] = getElementBounds(origElement, originalElementsMap);
20303
- previousOrigin = pointFrom17(x1, y1);
20709
+ previousOrigin = pointFrom16(x1, y1);
20304
20710
  }
20305
20711
  const newOrigin = getResizedOrigin(
20306
20712
  previousOrigin,
@@ -20323,7 +20729,7 @@ var resizeSingleElement = (nextWidth, nextHeight, latestElement, origElement, or
20323
20729
  newOrigin.x += scaledX;
20324
20730
  newOrigin.y += scaledY;
20325
20731
  rescaledPoints.points = rescaledPoints.points.map(
20326
- (p) => pointFrom17(p[0] - scaledX, p[1] - scaledY)
20732
+ (p) => pointFrom16(p[0] - scaledX, p[1] - scaledY)
20327
20733
  );
20328
20734
  }
20329
20735
  if (nextWidth < 0) {
@@ -20399,11 +20805,11 @@ var getNextSingleWidthAndHeightFromPointer = (latestElement, origElement, handle
20399
20805
  origElement.height,
20400
20806
  true
20401
20807
  );
20402
- const startTopLeft = pointFrom17(x1, y1);
20403
- const startBottomRight = pointFrom17(x2, y2);
20808
+ const startTopLeft = pointFrom16(x1, y1);
20809
+ const startBottomRight = pointFrom16(x2, y2);
20404
20810
  const startCenter = pointCenter3(startTopLeft, startBottomRight);
20405
- const rotatedPointer = pointRotateRads14(
20406
- pointFrom17(pointerX, pointerY),
20811
+ const rotatedPointer = pointRotateRads13(
20812
+ pointFrom16(pointerX, pointerY),
20407
20813
  startCenter,
20408
20814
  -origElement.angle
20409
20815
  );
@@ -20593,9 +20999,10 @@ var resizeMultipleElements = (selectedElements, elementsMap, handleDirection, sc
20593
20999
  }
20594
21000
  ];
20595
21001
  }, []);
20596
- boundingBox = getCommonBoundingBox(
20597
- targetElements.map(({ orig }) => orig).concat(boundTextElements)
20598
- );
21002
+ boundingBox = getCommonBoundingBox([
21003
+ ...targetElements.map(({ orig }) => orig),
21004
+ ...boundTextElements
21005
+ ]);
20599
21006
  }
20600
21007
  const { minX, minY, maxX, maxY, midX, midY } = boundingBox;
20601
21008
  const width = maxX - minX;
@@ -20651,7 +21058,7 @@ var resizeMultipleElements = (selectedElements, elementsMap, handleDirection, sc
20651
21058
  }
20652
21059
  const width2 = orig.width * scaleX;
20653
21060
  const height2 = orig.height * scaleY;
20654
- const angle = normalizeRadians2(
21061
+ const angle2 = normalizeRadians2(
20655
21062
  orig.angle * flipFactorX * flipFactorY
20656
21063
  );
20657
21064
  const isLinearOrFreeDraw = isLinearElement(orig) || isFreeDrawElement(orig);
@@ -20672,7 +21079,7 @@ var resizeMultipleElements = (selectedElements, elementsMap, handleDirection, sc
20672
21079
  y,
20673
21080
  width: width2,
20674
21081
  height: height2,
20675
- angle,
21082
+ angle: angle2,
20676
21083
  ...rescaledPoints
20677
21084
  };
20678
21085
  if (isElbowArrow(orig)) {
@@ -20740,7 +21147,7 @@ var resizeMultipleElements = (selectedElements, elementsMap, handleDirection, sc
20740
21147
  element,
20741
21148
  update: { boundTextFontSize, ...update }
20742
21149
  } of elementsAndUpdates) {
20743
- const { angle } = update;
21150
+ const { angle: angle2 } = update;
20744
21151
  scene.mutateElement(element, update);
20745
21152
  updateBoundElements(element, scene, {
20746
21153
  simultaneouslyUpdated: elementsToUpdate
@@ -20761,7 +21168,7 @@ var resizeMultipleElements = (selectedElements, elementsMap, handleDirection, sc
20761
21168
  if (boundTextElement && boundTextFontSize) {
20762
21169
  scene.mutateElement(boundTextElement, {
20763
21170
  fontSize: boundTextFontSize,
20764
- angle: isLinearElement(element) ? void 0 : angle
21171
+ angle: isLinearElement(element) ? void 0 : angle2
20765
21172
  });
20766
21173
  handleBindTextResize(element, scene, handleDirection, true);
20767
21174
  }
@@ -20773,9 +21180,9 @@ var resizeMultipleElements = (selectedElements, elementsMap, handleDirection, sc
20773
21180
  // src/resizeTest.ts
20774
21181
  init_define_import_meta_env();
20775
21182
  import {
20776
- pointFrom as pointFrom19,
21183
+ pointFrom as pointFrom18,
20777
21184
  pointOnLineSegment,
20778
- pointRotateRads as pointRotateRads16
21185
+ pointRotateRads as pointRotateRads15
20779
21186
  } from "@excalidraw/math";
20780
21187
  import {
20781
21188
  SIDE_RESIZING_THRESHOLD
@@ -20786,7 +21193,7 @@ init_define_import_meta_env();
20786
21193
  import {
20787
21194
  DEFAULT_TRANSFORM_HANDLE_SPACING
20788
21195
  } from "@excalidraw/common";
20789
- import { pointFrom as pointFrom18, pointRotateRads as pointRotateRads15 } from "@excalidraw/math";
21196
+ import { pointFrom as pointFrom17, pointRotateRads as pointRotateRads14 } from "@excalidraw/math";
20790
21197
  var transformHandleSizes = {
20791
21198
  mouse: 8,
20792
21199
  pen: 16,
@@ -20826,11 +21233,11 @@ var OMIT_SIDES_FOR_LINE_BACKSLASH = {
20826
21233
  n: true,
20827
21234
  w: true
20828
21235
  };
20829
- var generateTransformHandle = (x, y, width, height, cx, cy, angle) => {
20830
- const [xx, yy] = pointRotateRads15(
20831
- pointFrom18(x + width / 2, y + height / 2),
20832
- pointFrom18(cx, cy),
20833
- angle
21236
+ var generateTransformHandle = (x, y, width, height, cx, cy, angle2) => {
21237
+ const [xx, yy] = pointRotateRads14(
21238
+ pointFrom17(x + width / 2, y + height / 2),
21239
+ pointFrom17(cx, cy),
21240
+ angle2
20834
21241
  );
20835
21242
  return [xx - width / 2, yy - height / 2, width, height];
20836
21243
  };
@@ -20846,7 +21253,7 @@ var getOmitSidesForEditorInterface = (editorInterface) => {
20846
21253
  }
20847
21254
  return {};
20848
21255
  };
20849
- var getTransformHandlesFromCoords = ([x1, y1, x2, y2, cx, cy], angle, zoom, pointerType, omitSides = {}, margin = 4, spacing = DEFAULT_TRANSFORM_HANDLE_SPACING) => {
21256
+ var getTransformHandlesFromCoords = ([x1, y1, x2, y2, cx, cy], angle2, zoom, pointerType, omitSides = {}, margin = 4, spacing = DEFAULT_TRANSFORM_HANDLE_SPACING) => {
20850
21257
  const size = transformHandleSizes[pointerType];
20851
21258
  const handleWidth = size / zoom.value;
20852
21259
  const handleHeight = size / zoom.value;
@@ -20864,7 +21271,7 @@ var getTransformHandlesFromCoords = ([x1, y1, x2, y2, cx, cy], angle, zoom, poin
20864
21271
  handleHeight,
20865
21272
  cx,
20866
21273
  cy,
20867
- angle
21274
+ angle2
20868
21275
  ),
20869
21276
  ne: omitSides.ne ? void 0 : generateTransformHandle(
20870
21277
  x2 + dashedLineMargin - centeringOffset,
@@ -20873,7 +21280,7 @@ var getTransformHandlesFromCoords = ([x1, y1, x2, y2, cx, cy], angle, zoom, poin
20873
21280
  handleHeight,
20874
21281
  cx,
20875
21282
  cy,
20876
- angle
21283
+ angle2
20877
21284
  ),
20878
21285
  sw: omitSides.sw ? void 0 : generateTransformHandle(
20879
21286
  x1 - dashedLineMargin - handleMarginX + centeringOffset,
@@ -20882,7 +21289,7 @@ var getTransformHandlesFromCoords = ([x1, y1, x2, y2, cx, cy], angle, zoom, poin
20882
21289
  handleHeight,
20883
21290
  cx,
20884
21291
  cy,
20885
- angle
21292
+ angle2
20886
21293
  ),
20887
21294
  se: omitSides.se ? void 0 : generateTransformHandle(
20888
21295
  x2 + dashedLineMargin - centeringOffset,
@@ -20891,7 +21298,7 @@ var getTransformHandlesFromCoords = ([x1, y1, x2, y2, cx, cy], angle, zoom, poin
20891
21298
  handleHeight,
20892
21299
  cx,
20893
21300
  cy,
20894
- angle
21301
+ angle2
20895
21302
  ),
20896
21303
  rotation: omitSides.rotation ? void 0 : generateTransformHandle(
20897
21304
  x1 + width / 2 - handleWidth / 2,
@@ -20900,7 +21307,7 @@ var getTransformHandlesFromCoords = ([x1, y1, x2, y2, cx, cy], angle, zoom, poin
20900
21307
  handleHeight,
20901
21308
  cx,
20902
21309
  cy,
20903
- angle
21310
+ angle2
20904
21311
  )
20905
21312
  };
20906
21313
  const minimumSizeForEightHandles = 5 * transformHandleSizes.mouse / zoom.value;
@@ -20913,7 +21320,7 @@ var getTransformHandlesFromCoords = ([x1, y1, x2, y2, cx, cy], angle, zoom, poin
20913
21320
  handleHeight,
20914
21321
  cx,
20915
21322
  cy,
20916
- angle
21323
+ angle2
20917
21324
  );
20918
21325
  }
20919
21326
  if (!omitSides.s) {
@@ -20924,7 +21331,7 @@ var getTransformHandlesFromCoords = ([x1, y1, x2, y2, cx, cy], angle, zoom, poin
20924
21331
  handleHeight,
20925
21332
  cx,
20926
21333
  cy,
20927
- angle
21334
+ angle2
20928
21335
  );
20929
21336
  }
20930
21337
  }
@@ -20937,7 +21344,7 @@ var getTransformHandlesFromCoords = ([x1, y1, x2, y2, cx, cy], angle, zoom, poin
20937
21344
  handleHeight,
20938
21345
  cx,
20939
21346
  cy,
20940
- angle
21347
+ angle2
20941
21348
  );
20942
21349
  }
20943
21350
  if (!omitSides.e) {
@@ -20948,7 +21355,7 @@ var getTransformHandlesFromCoords = ([x1, y1, x2, y2, cx, cy], angle, zoom, poin
20948
21355
  handleHeight,
20949
21356
  cx,
20950
21357
  cy,
20951
- angle
21358
+ angle2
20952
21359
  );
20953
21360
  }
20954
21361
  }
@@ -21043,14 +21450,14 @@ var resizeTest = (element, elementsMap, appState, x, y, zoom, pointerType, edito
21043
21450
  const SPACING = isImageElement(element) ? 0 : SIDE_RESIZING_THRESHOLD / zoom.value;
21044
21451
  const ZOOMED_SIDE_RESIZING_THRESHOLD = SIDE_RESIZING_THRESHOLD / zoom.value;
21045
21452
  const sides = getSelectionBorders(
21046
- pointFrom19(x1 - SPACING, y1 - SPACING),
21047
- pointFrom19(x2 + SPACING, y2 + SPACING),
21048
- pointFrom19(cx, cy),
21453
+ pointFrom18(x1 - SPACING, y1 - SPACING),
21454
+ pointFrom18(x2 + SPACING, y2 + SPACING),
21455
+ pointFrom18(cx, cy),
21049
21456
  element.angle
21050
21457
  );
21051
21458
  for (const [dir, side] of Object.entries(sides)) {
21052
21459
  if (pointOnLineSegment(
21053
- pointFrom19(x, y),
21460
+ pointFrom18(x, y),
21054
21461
  side,
21055
21462
  ZOOMED_SIDE_RESIZING_THRESHOLD
21056
21463
  )) {
@@ -21099,14 +21506,14 @@ var getTransformHandleTypeFromCoords = ([x1, y1, x2, y2], scenePointerX, scenePo
21099
21506
  const cy = (y1 + y2) / 2;
21100
21507
  const SPACING = SIDE_RESIZING_THRESHOLD / zoom.value;
21101
21508
  const sides = getSelectionBorders(
21102
- pointFrom19(x1 - SPACING, y1 - SPACING),
21103
- pointFrom19(x2 + SPACING, y2 + SPACING),
21104
- pointFrom19(cx, cy),
21509
+ pointFrom18(x1 - SPACING, y1 - SPACING),
21510
+ pointFrom18(x2 + SPACING, y2 + SPACING),
21511
+ pointFrom18(cx, cy),
21105
21512
  0
21106
21513
  );
21107
21514
  for (const [dir, side] of Object.entries(sides)) {
21108
21515
  if (pointOnLineSegment(
21109
- pointFrom19(scenePointerX, scenePointerY),
21516
+ pointFrom18(scenePointerX, scenePointerY),
21110
21517
  side,
21111
21518
  SPACING
21112
21519
  )) {
@@ -21117,10 +21524,10 @@ var getTransformHandleTypeFromCoords = ([x1, y1, x2, y2], scenePointerX, scenePo
21117
21524
  return false;
21118
21525
  };
21119
21526
  var RESIZE_CURSORS = ["ns", "nesw", "ew", "nwse"];
21120
- var rotateResizeCursor = (cursor, angle) => {
21527
+ var rotateResizeCursor = (cursor, angle2) => {
21121
21528
  const index = RESIZE_CURSORS.indexOf(cursor);
21122
21529
  if (index >= 0) {
21123
- const a2 = Math.round(angle / (Math.PI / 4));
21530
+ const a2 = Math.round(angle2 / (Math.PI / 4));
21124
21531
  cursor = RESIZE_CURSORS[(index + a2) % RESIZE_CURSORS.length];
21125
21532
  }
21126
21533
  return cursor;
@@ -21162,11 +21569,11 @@ var getCursorForResizingElement = (resizingElement) => {
21162
21569
  }
21163
21570
  return cursor ? `${cursor}-resize` : "";
21164
21571
  };
21165
- var getSelectionBorders = ([x1, y1], [x2, y2], center, angle) => {
21166
- const topLeft = pointRotateRads16(pointFrom19(x1, y1), center, angle);
21167
- const topRight = pointRotateRads16(pointFrom19(x2, y1), center, angle);
21168
- const bottomLeft = pointRotateRads16(pointFrom19(x1, y2), center, angle);
21169
- const bottomRight = pointRotateRads16(pointFrom19(x2, y2), center, angle);
21572
+ var getSelectionBorders = ([x1, y1], [x2, y2], center, angle2) => {
21573
+ const topLeft = pointRotateRads15(pointFrom18(x1, y1), center, angle2);
21574
+ const topRight = pointRotateRads15(pointFrom18(x2, y1), center, angle2);
21575
+ const bottomLeft = pointRotateRads15(pointFrom18(x1, y2), center, angle2);
21576
+ const bottomRight = pointRotateRads15(pointFrom18(x2, y2), center, angle2);
21170
21577
  return {
21171
21578
  n: [topLeft, topRight],
21172
21579
  e: [topRight, bottomRight],
@@ -21183,7 +21590,7 @@ var showSelectedShapeActions = (appState, elements) => Boolean(
21183
21590
 
21184
21591
  // src/transform.ts
21185
21592
  init_define_import_meta_env();
21186
- import { pointFrom as pointFrom20 } from "@excalidraw/math";
21593
+ import { pointFrom as pointFrom19 } from "@excalidraw/math";
21187
21594
  import {
21188
21595
  DEFAULT_FONT_FAMILY as DEFAULT_FONT_FAMILY3,
21189
21596
  DEFAULT_FONT_SIZE as DEFAULT_FONT_SIZE4,
@@ -21421,7 +21828,9 @@ var ElementStore = class {
21421
21828
  this.excalidrawElements.set(ele.id, ele);
21422
21829
  };
21423
21830
  getElements = () => {
21424
- return syncInvalidIndices(Array.from(this.excalidrawElements.values()));
21831
+ return syncInvalidIndices(
21832
+ Array.from(this.excalidrawElements.values())
21833
+ );
21425
21834
  };
21426
21835
  getElementsMap = () => {
21427
21836
  return toBrandedType3(
@@ -21465,7 +21874,7 @@ var convertToExcalidrawElements = (elementsSkeleton, opts) => {
21465
21874
  excalidrawElement = newLinearElement({
21466
21875
  width,
21467
21876
  height,
21468
- points: [pointFrom20(0, 0), pointFrom20(width, height)],
21877
+ points: [pointFrom19(0, 0), pointFrom19(width, height)],
21469
21878
  ...element
21470
21879
  });
21471
21880
  break;
@@ -21477,7 +21886,7 @@ var convertToExcalidrawElements = (elementsSkeleton, opts) => {
21477
21886
  width,
21478
21887
  height,
21479
21888
  endArrowhead: "arrow",
21480
- points: [pointFrom20(0, 0), pointFrom20(width, height)],
21889
+ points: [pointFrom19(0, 0), pointFrom19(width, height)],
21481
21890
  ...element,
21482
21891
  type: "arrow"
21483
21892
  });
@@ -21764,11 +22173,11 @@ var hashString = (s) => {
21764
22173
  }
21765
22174
  return hash >>> 0;
21766
22175
  };
22176
+ var isNonDeletedElement = (element) => !element.isDeleted;
21767
22177
  var getVisibleElements = (elements) => elements.filter(
21768
- (el) => !el.isDeleted && !isInvisiblySmallElement(el)
22178
+ (el) => isNonDeletedElement(el) && !isInvisiblySmallElement(el)
21769
22179
  );
21770
- var getNonDeletedElements2 = (elements) => elements.filter((element) => !element.isDeleted);
21771
- var isNonDeletedElement2 = (element) => !element.isDeleted;
22180
+ var getNonDeletedElements = (elements) => elements.filter(isNonDeletedElement);
21772
22181
  export {
21773
22182
  AppStateDelta,
21774
22183
  BASE_ARROW_MIN_LENGTH,
@@ -21855,6 +22264,7 @@ export {
21855
22264
  elementWithCanvasCache,
21856
22265
  elementsAreInFrameBounds,
21857
22266
  elementsAreInSameGroup,
22267
+ elementsOverlappingBBox,
21858
22268
  embeddableURLValidator,
21859
22269
  excludeElementsInFramesFromSelection,
21860
22270
  filterElementsEligibleAsFrameChildren,
@@ -21883,7 +22293,6 @@ export {
21883
22293
  getBoundTextMaxWidth,
21884
22294
  getBoundsFromPoints,
21885
22295
  getCenterForBounds,
21886
- getClosestElementBounds,
21887
22296
  getCommonBoundingBox,
21888
22297
  getCommonBounds,
21889
22298
  getCommonFrameId,
@@ -21939,7 +22348,7 @@ export {
21939
22348
  getMinMaxXYFromCurvePathOps,
21940
22349
  getMinTextElementWidth,
21941
22350
  getNewGroupIdsForDuplication,
21942
- getNonDeletedElements2 as getNonDeletedElements,
22351
+ getNonDeletedElements,
21943
22352
  getNonDeletedGroupIds,
21944
22353
  getNormalizedDimensions,
21945
22354
  getObservedAppState,
@@ -21987,6 +22396,7 @@ export {
21987
22396
  hasBackground,
21988
22397
  hasBoundTextElement,
21989
22398
  hasBoundingBox,
22399
+ hasFreedrawMode,
21990
22400
  hasStrokeColor,
21991
22401
  hasStrokeStyle,
21992
22402
  hasStrokeWidth,
@@ -22043,7 +22453,7 @@ export {
22043
22453
  isMagicFrameElement,
22044
22454
  isMeasureTextSupported,
22045
22455
  isNodeInFlowchart,
22046
- isNonDeletedElement2 as isNonDeletedElement,
22456
+ isNonDeletedElement,
22047
22457
  isPathALoop,
22048
22458
  isPointInElement,
22049
22459
  isRectangularElement,