@excalidraw/element 0.18.0-51ad895 → 0.18.0-6135548

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 (196) hide show
  1. package/dist/dev/index.js +1065 -175
  2. package/dist/dev/index.js.map +4 -4
  3. package/dist/prod/index.js +17 -17
  4. package/dist/types/common/src/bounds.d.ts +10 -0
  5. package/dist/types/common/src/colors.d.ts +59 -39
  6. package/dist/types/common/src/constants.d.ts +13 -11
  7. package/dist/types/common/src/editorInterface.d.ts +1 -1
  8. package/dist/types/common/src/font-metadata.d.ts +1 -3
  9. package/dist/types/common/src/index.d.ts +1 -1
  10. package/dist/types/common/src/keys.d.ts +1 -1
  11. package/dist/types/common/src/utility-types.d.ts +0 -1
  12. package/dist/types/common/src/utils.d.ts +43 -34
  13. package/dist/types/element/src/Scene.d.ts +3 -3
  14. package/dist/types/element/src/binding.d.ts +6 -4
  15. package/dist/types/element/src/bounds.d.ts +2 -10
  16. package/dist/types/element/src/collision.d.ts +2 -2
  17. package/dist/types/element/src/comparisons.d.ts +7 -7
  18. package/dist/types/element/src/dragElements.d.ts +3 -3
  19. package/dist/types/element/src/duplicate.d.ts +3 -3
  20. package/dist/types/element/src/fractionalIndex.d.ts +2 -2
  21. package/dist/types/element/src/frame.d.ts +5 -1
  22. package/dist/types/element/src/heading.d.ts +2 -1
  23. package/dist/types/element/src/image.d.ts +1 -11
  24. package/dist/types/element/src/index.d.ts +1 -0
  25. package/dist/types/element/src/linearElementEditor.d.ts +1 -2
  26. package/dist/types/element/src/mutateElement.d.ts +3 -1
  27. package/dist/types/element/src/newElement.d.ts +6 -6
  28. package/dist/types/element/src/renderElement.d.ts +0 -6
  29. package/dist/types/element/src/resizeElements.d.ts +10 -10
  30. package/dist/types/element/src/resizeTest.d.ts +1 -1
  31. package/dist/types/element/src/selection.d.ts +3 -7
  32. package/dist/types/element/src/shape.d.ts +8 -7
  33. package/dist/types/element/src/textMeasurements.d.ts +1 -3
  34. package/dist/types/{excalidraw/data → element/src}/transform.d.ts +3 -3
  35. package/dist/types/element/src/transformHandles.d.ts +3 -23
  36. package/dist/types/element/src/typeChecks.d.ts +2 -4
  37. package/dist/types/element/src/utils.d.ts +3 -1
  38. package/dist/types/{common → element}/src/visualdebug.d.ts +20 -2
  39. package/dist/types/excalidraw/actions/actionAddToLibrary.d.ts +62 -126
  40. package/dist/types/excalidraw/actions/actionAlign.d.ts +0 -1
  41. package/dist/types/excalidraw/actions/actionBoundText.d.ts +44 -87
  42. package/dist/types/excalidraw/actions/actionCanvas.d.ts +263 -510
  43. package/dist/types/excalidraw/actions/actionClipboard.d.ts +44 -87
  44. package/dist/types/excalidraw/actions/actionCropEditor.d.ts +21 -43
  45. package/dist/types/excalidraw/actions/actionDeleteSelected.d.ts +74 -142
  46. package/dist/types/excalidraw/actions/actionDistribute.d.ts +0 -1
  47. package/dist/types/excalidraw/actions/actionDuplicateSelection.d.ts +0 -1
  48. package/dist/types/excalidraw/actions/actionElementLink.d.ts +18 -40
  49. package/dist/types/excalidraw/actions/actionElementLock.d.ts +45 -88
  50. package/dist/types/excalidraw/actions/actionEmbeddable.d.ts +22 -44
  51. package/dist/types/excalidraw/actions/actionExport.d.ts +85 -170
  52. package/dist/types/excalidraw/actions/actionFinalize.d.ts +1 -2
  53. package/dist/types/excalidraw/actions/actionFlip.d.ts +0 -1
  54. package/dist/types/excalidraw/actions/actionFrame.d.ts +181 -302
  55. package/dist/types/excalidraw/actions/actionGroup.d.ts +48 -99
  56. package/dist/types/excalidraw/actions/actionLinearEditor.d.ts +122 -180
  57. package/dist/types/excalidraw/actions/actionLink.d.ts +22 -44
  58. package/dist/types/excalidraw/actions/actionMenu.d.ts +17 -39
  59. package/dist/types/excalidraw/actions/actionNavigate.d.ts +14 -17
  60. package/dist/types/excalidraw/actions/actionProperties.d.ts +59 -102
  61. package/dist/types/excalidraw/actions/actionSelectAll.d.ts +24 -50
  62. package/dist/types/excalidraw/actions/actionStyles.d.ts +20 -42
  63. package/dist/types/excalidraw/actions/actionToggleGridMode.d.ts +22 -44
  64. package/dist/types/excalidraw/actions/actionToggleObjectsSnapMode.d.ts +22 -44
  65. package/dist/types/excalidraw/actions/actionToggleSearchMenu.d.ts +16 -38
  66. package/dist/types/excalidraw/actions/actionToggleStats.d.ts +22 -44
  67. package/dist/types/excalidraw/actions/actionToggleViewMode.d.ts +22 -44
  68. package/dist/types/excalidraw/actions/actionToggleZenMode.d.ts +22 -44
  69. package/dist/types/excalidraw/actions/actionZindex.d.ts +0 -1
  70. package/dist/types/excalidraw/actions/manager.d.ts +1 -1
  71. package/dist/types/excalidraw/actions/register.d.ts +2 -2
  72. package/dist/types/excalidraw/appState.d.ts +3 -3
  73. package/dist/types/excalidraw/clipboard.d.ts +7 -31
  74. package/dist/types/excalidraw/components/Actions.d.ts +1 -1
  75. package/dist/types/excalidraw/components/App.d.ts +33 -41
  76. package/dist/types/excalidraw/components/Card.d.ts +1 -3
  77. package/dist/types/excalidraw/components/ColorPicker/ColorInput.d.ts +2 -4
  78. package/dist/types/excalidraw/components/ColorPicker/ColorPicker.d.ts +0 -1
  79. package/dist/types/excalidraw/components/ColorPicker/colorPickerUtils.d.ts +0 -1
  80. package/dist/types/excalidraw/components/ColorPicker/keyboardNavHandlers.d.ts +0 -1
  81. package/dist/types/excalidraw/components/CommandPalette/types.d.ts +0 -1
  82. package/dist/types/excalidraw/components/ConvertElementTypePopup.d.ts +2 -2
  83. package/dist/types/excalidraw/components/DarkModeToggle.d.ts +1 -1
  84. package/dist/types/excalidraw/components/DefaultSidebar.d.ts +9 -13
  85. package/dist/types/excalidraw/components/ElementLinkDialog.d.ts +1 -1
  86. package/dist/types/excalidraw/components/Ellipsify.d.ts +1 -2
  87. package/dist/types/excalidraw/components/ErrorDialog.d.ts +1 -1
  88. package/dist/types/excalidraw/components/ExcalidrawLogo.d.ts +0 -1
  89. package/dist/types/excalidraw/components/EyeDropper.d.ts +0 -1
  90. package/dist/types/excalidraw/components/FilledButton.d.ts +1 -0
  91. package/dist/types/excalidraw/components/FontPicker/keyboardNavHandlers.d.ts +0 -1
  92. package/dist/types/excalidraw/components/HelpDialog.d.ts +1 -1
  93. package/dist/types/excalidraw/components/InlineIcon.d.ts +2 -2
  94. package/dist/types/excalidraw/components/LibraryMenuControlButtons.d.ts +1 -1
  95. package/dist/types/excalidraw/components/LibraryMenuHeaderContent.d.ts +1 -2
  96. package/dist/types/excalidraw/components/LibraryUnit.d.ts +2 -3
  97. package/dist/types/excalidraw/components/LoadingMessage.d.ts +0 -1
  98. package/dist/types/excalidraw/components/MobileToolBar.d.ts +0 -1
  99. package/dist/types/excalidraw/components/Modal.d.ts +0 -1
  100. package/dist/types/excalidraw/components/OverwriteConfirm/OverwriteConfirm.d.ts +1 -1
  101. package/dist/types/excalidraw/components/RadioGroup.d.ts +0 -1
  102. package/dist/types/excalidraw/components/RadioSelection.d.ts +4 -4
  103. package/dist/types/excalidraw/components/ScrollableList.d.ts +0 -1
  104. package/dist/types/excalidraw/components/Sidebar/Sidebar.d.ts +15 -21
  105. package/dist/types/excalidraw/components/Sidebar/SidebarHeader.d.ts +1 -1
  106. package/dist/types/excalidraw/components/Sidebar/SidebarTab.d.ts +1 -2
  107. package/dist/types/excalidraw/components/Sidebar/SidebarTabTrigger.d.ts +1 -2
  108. package/dist/types/excalidraw/components/Sidebar/SidebarTabTriggers.d.ts +1 -2
  109. package/dist/types/excalidraw/components/Sidebar/SidebarTabs.d.ts +1 -2
  110. package/dist/types/excalidraw/components/Spinner.d.ts +4 -4
  111. package/dist/types/excalidraw/components/Stats/CanvasGrid.d.ts +0 -1
  112. package/dist/types/excalidraw/components/Stats/Collapsible.d.ts +0 -1
  113. package/dist/types/excalidraw/components/Stats/DragInput.d.ts +0 -1
  114. package/dist/types/excalidraw/components/Stats/index.d.ts +7 -8
  115. package/dist/types/excalidraw/components/TTDDialog/Chat/ChatHistoryMenu.d.ts +15 -0
  116. package/dist/types/excalidraw/components/TTDDialog/Chat/ChatInterface.d.ts +27 -0
  117. package/dist/types/excalidraw/components/TTDDialog/Chat/ChatMessage.d.ts +14 -0
  118. package/dist/types/excalidraw/components/TTDDialog/Chat/TTDChatPanel.d.ts +26 -0
  119. package/dist/types/excalidraw/components/TTDDialog/Chat/index.d.ts +3 -0
  120. package/dist/types/excalidraw/components/TTDDialog/Chat/useChatAgent.d.ts +8 -0
  121. package/dist/types/excalidraw/components/TTDDialog/MermaidToExcalidraw.d.ts +3 -2
  122. package/dist/types/excalidraw/components/TTDDialog/TTDContext.d.ts +13 -0
  123. package/dist/types/excalidraw/components/TTDDialog/TTDDialog.d.ts +4 -25
  124. package/dist/types/excalidraw/components/TTDDialog/TTDDialogOutput.d.ts +2 -2
  125. package/dist/types/excalidraw/components/TTDDialog/TTDDialogPanel.d.ts +13 -9
  126. package/dist/types/excalidraw/components/TTDDialog/TTDDialogTab.d.ts +1 -2
  127. package/dist/types/excalidraw/components/TTDDialog/TTDDialogTabTrigger.d.ts +1 -2
  128. package/dist/types/excalidraw/components/TTDDialog/TTDDialogTabTriggers.d.ts +1 -2
  129. package/dist/types/excalidraw/components/TTDDialog/TTDDialogTrigger.d.ts +1 -1
  130. package/dist/types/excalidraw/components/TTDDialog/TTDPreviewPanel.d.ts +9 -0
  131. package/dist/types/excalidraw/components/TTDDialog/TextToDiagram.d.ts +8 -0
  132. package/dist/types/excalidraw/components/TTDDialog/common.d.ts +16 -16
  133. package/dist/types/excalidraw/components/TTDDialog/hooks/useChatManagement.d.ts +13 -0
  134. package/dist/types/excalidraw/components/TTDDialog/hooks/useMermaidRenderer.d.ts +14 -0
  135. package/dist/types/excalidraw/components/TTDDialog/hooks/useTextGeneration.d.ts +7 -0
  136. package/dist/types/excalidraw/components/TTDDialog/types.d.ts +91 -0
  137. package/dist/types/excalidraw/components/TTDDialog/useTTDChatStorage.d.ts +22 -0
  138. package/dist/types/excalidraw/components/TTDDialog/utils/TTDStreamFetch.d.ts +24 -0
  139. package/dist/types/excalidraw/components/TTDDialog/utils/chat.d.ts +10 -0
  140. package/dist/types/excalidraw/components/TTDDialog/utils/mermaidValidation.d.ts +1 -0
  141. package/dist/types/excalidraw/components/Toast.d.ts +3 -3
  142. package/dist/types/excalidraw/components/Trans.d.ts +2 -2
  143. package/dist/types/excalidraw/components/dropdownMenu/DropdownMenu.d.ts +30 -33
  144. package/dist/types/excalidraw/components/dropdownMenu/DropdownMenuContent.d.ts +5 -5
  145. package/dist/types/excalidraw/components/dropdownMenu/DropdownMenuGroup.d.ts +3 -3
  146. package/dist/types/excalidraw/components/dropdownMenu/DropdownMenuItem.d.ts +12 -19
  147. package/dist/types/excalidraw/components/dropdownMenu/DropdownMenuItemContent.d.ts +5 -4
  148. package/dist/types/excalidraw/components/dropdownMenu/DropdownMenuItemContentRadio.d.ts +0 -1
  149. package/dist/types/excalidraw/components/dropdownMenu/DropdownMenuItemCustom.d.ts +2 -2
  150. package/dist/types/excalidraw/components/dropdownMenu/DropdownMenuItemLink.d.ts +6 -6
  151. package/dist/types/excalidraw/components/dropdownMenu/DropdownMenuTrigger.d.ts +3 -4
  152. package/dist/types/excalidraw/components/dropdownMenu/common.d.ts +1 -1
  153. package/dist/types/excalidraw/components/hoc/withInternalFallback.d.ts +1 -1
  154. package/dist/types/excalidraw/components/hyperlink/helpers.d.ts +1 -1
  155. package/dist/types/excalidraw/components/icons.d.ts +16 -12
  156. package/dist/types/excalidraw/components/live-collaboration/LiveCollaborationTrigger.d.ts +2 -13
  157. package/dist/types/excalidraw/components/main-menu/DefaultItems.d.ts +2 -2
  158. package/dist/types/excalidraw/components/main-menu/MainMenu.d.ts +26 -29
  159. package/dist/types/excalidraw/components/welcome-screen/WelcomeScreen.Center.d.ts +6 -6
  160. package/dist/types/excalidraw/components/welcome-screen/WelcomeScreen.d.ts +15 -16
  161. package/dist/types/excalidraw/data/blob.d.ts +321 -3
  162. package/dist/types/excalidraw/data/encode.d.ts +4 -4
  163. package/dist/types/excalidraw/data/encryption.d.ts +5 -5
  164. package/dist/types/excalidraw/data/filesystem.d.ts +2 -2
  165. package/dist/types/excalidraw/data/index.d.ts +3 -3
  166. package/dist/types/excalidraw/data/json.d.ts +159 -2
  167. package/dist/types/excalidraw/data/library.d.ts +24 -9
  168. package/dist/types/excalidraw/data/restore.d.ts +25 -10
  169. package/dist/types/excalidraw/editor-jotai.d.ts +11 -11
  170. package/dist/types/excalidraw/errors.d.ts +14 -0
  171. package/dist/types/excalidraw/hooks/useOutsideClick.d.ts +1 -2
  172. package/dist/types/excalidraw/hooks/useScrollPosition.d.ts +1 -2
  173. package/dist/types/excalidraw/i18n.d.ts +2 -2
  174. package/dist/types/excalidraw/index.d.ts +4 -4
  175. package/dist/types/excalidraw/renderer/helpers.d.ts +6 -4
  176. package/dist/types/excalidraw/renderer/interactiveScene.d.ts +8 -6
  177. package/dist/types/excalidraw/scene/Renderer.d.ts +5 -2
  178. package/dist/types/excalidraw/scene/export.d.ts +2 -2
  179. package/dist/types/excalidraw/scene/scroll.d.ts +1 -6
  180. package/dist/types/excalidraw/scene/types.d.ts +7 -2
  181. package/dist/types/excalidraw/snapping.d.ts +5 -5
  182. package/dist/types/excalidraw/subset/harfbuzz/harfbuzz-bindings.d.ts +1 -1
  183. package/dist/types/excalidraw/subset/harfbuzz/harfbuzz-loader.d.ts +1 -1
  184. package/dist/types/excalidraw/subset/harfbuzz/harfbuzz-wasm.d.ts +1 -1
  185. package/dist/types/excalidraw/subset/woff2/woff2-loader.d.ts +2 -2
  186. package/dist/types/excalidraw/subset/woff2/woff2-wasm.d.ts +1 -1
  187. package/dist/types/excalidraw/types.d.ts +1 -2
  188. package/dist/types/excalidraw/wysiwyg/textWysiwyg.d.ts +2 -2
  189. package/dist/types/math/src/polygon.d.ts +2 -2
  190. package/dist/types/math/src/range.d.ts +1 -3
  191. package/dist/types/math/src/segment.d.ts +3 -3
  192. package/dist/types/utils/src/bbox.d.ts +1 -1
  193. package/dist/types/utils/src/export.d.ts +5 -5
  194. package/dist/types/utils/src/shape.d.ts +6 -6
  195. package/dist/types/utils/src/withinBounds.d.ts +2 -2
  196. package/package.json +9 -3
package/dist/dev/index.js CHANGED
@@ -199,7 +199,7 @@ import {
199
199
  radiansBetweenAngles,
200
200
  radiansDifference
201
201
  } from "@excalidraw/math";
202
- import { pointsEqual as pointsEqual6 } from "@excalidraw/math";
202
+ import { pointsEqual as pointsEqual7 } from "@excalidraw/math";
203
203
 
204
204
  // src/bounds.ts
205
205
  init_define_import_meta_env();
@@ -2447,21 +2447,6 @@ var getClosedCurveShape = (element, roughShape, startingPoint = pointFrom(0, 0),
2447
2447
 
2448
2448
  // src/shape.ts
2449
2449
  init_define_import_meta_env();
2450
- import {
2451
- pointFrom as pointFrom13,
2452
- pointDistance as pointDistance6,
2453
- pointRotateRads as pointRotateRads12
2454
- } from "@excalidraw/math";
2455
- import {
2456
- ROUGHNESS,
2457
- isTransparent as isTransparent3,
2458
- assertNever as assertNever2,
2459
- COLOR_PALETTE,
2460
- LINE_POLYGON_POINT_MERGE_DISTANCE
2461
- } from "@excalidraw/common";
2462
-
2463
- // src/renderElement.ts
2464
- init_define_import_meta_env();
2465
2450
 
2466
2451
  // ../../node_modules/perfect-freehand/dist/esm/index.js
2467
2452
  init_define_import_meta_env();
@@ -2626,7 +2611,24 @@ function ae(e, t = {}) {
2626
2611
  return ce(me(e, t), t);
2627
2612
  }
2628
2613
 
2614
+ // src/shape.ts
2615
+ import {
2616
+ pointFrom as pointFrom13,
2617
+ pointDistance as pointDistance6,
2618
+ pointRotateRads as pointRotateRads12
2619
+ } from "@excalidraw/math";
2620
+ import {
2621
+ ROUGHNESS,
2622
+ THEME as THEME2,
2623
+ isTransparent as isTransparent3,
2624
+ assertNever as assertNever2,
2625
+ COLOR_PALETTE,
2626
+ LINE_POLYGON_POINT_MERGE_DISTANCE,
2627
+ applyDarkModeFilter as applyDarkModeFilter2
2628
+ } from "@excalidraw/common";
2629
+
2629
2630
  // src/renderElement.ts
2631
+ init_define_import_meta_env();
2630
2632
  import {
2631
2633
  isRightAngleRads,
2632
2634
  lineSegment as lineSegment6,
@@ -2644,7 +2646,8 @@ import {
2644
2646
  getFontString as getFontString3,
2645
2647
  isRTL,
2646
2648
  getVerticalOffset,
2647
- invariant as invariant9
2649
+ invariant as invariant9,
2650
+ applyDarkModeFilter
2648
2651
  } from "@excalidraw/common";
2649
2652
 
2650
2653
  // src/cropElement.ts
@@ -3111,7 +3114,7 @@ import {
3111
3114
  pointCenter as pointCenter2,
3112
3115
  pointFrom as pointFrom9,
3113
3116
  pointRotateRads as pointRotateRads9,
3114
- pointsEqual as pointsEqual5,
3117
+ pointsEqual as pointsEqual6,
3115
3118
  pointDistance as pointDistance5,
3116
3119
  vectorFromPoint as vectorFromPoint8,
3117
3120
  curveLength,
@@ -3129,7 +3132,6 @@ import {
3129
3132
  } from "@excalidraw/common";
3130
3133
  import {
3131
3134
  deconstructLinearOrFreeDrawElement as deconstructLinearOrFreeDrawElement2,
3132
- getHoveredElementForBinding as getHoveredElementForBinding2,
3133
3135
  isPathALoop as isPathALoop2,
3134
3136
  moveArrowAboveBindable,
3135
3137
  projectFixedPointOntoDiagonal as projectFixedPointOntoDiagonal2
@@ -3153,6 +3155,7 @@ import {
3153
3155
  pointFrom as pointFrom8,
3154
3156
  pointFromVector as pointFromVector6,
3155
3157
  pointRotateRads as pointRotateRads8,
3158
+ pointsEqual as pointsEqual5,
3156
3159
  vectorFromPoint as vectorFromPoint7,
3157
3160
  vectorNormalize as vectorNormalize4,
3158
3161
  vectorScale as vectorScale7
@@ -3350,7 +3353,6 @@ var getDefaultRoundnessTypeForElement = (element) => {
3350
3353
  }
3351
3354
  return null;
3352
3355
  };
3353
- var isBounds = (box) => Array.isArray(box) && box.length === 4 && typeof box[0] === "number" && typeof box[1] === "number" && typeof box[2] === "number" && typeof box[3] === "number";
3354
3356
  var getLinearElementSubType = (element) => {
3355
3357
  if (isSharpArrow(element)) {
3356
3358
  return "sharpArrow";
@@ -5177,7 +5179,11 @@ var isBindableElementInsideOtherBindable = (innerElement, outerElement, elements
5177
5179
 
5178
5180
  // src/heading.ts
5179
5181
  init_define_import_meta_env();
5180
- import { invariant as invariant5, isDevEnv as isDevEnv2, isTestEnv as isTestEnv3 } from "@excalidraw/common";
5182
+ import {
5183
+ invariant as invariant5,
5184
+ isDevEnv as isDevEnv2,
5185
+ isTestEnv as isTestEnv3
5186
+ } from "@excalidraw/common";
5181
5187
  import {
5182
5188
  pointFrom as pointFrom6,
5183
5189
  pointFromVector as pointFromVector5,
@@ -6955,10 +6961,12 @@ var shouldEnableBindingForPointerEvent = (event) => {
6955
6961
  var isBindingEnabled = (appState) => {
6956
6962
  return appState.isBindingEnabled;
6957
6963
  };
6958
- var bindOrUnbindBindingElement = (arrow, draggingPoints, scene, appState, opts) => {
6964
+ var bindOrUnbindBindingElement = (arrow, draggingPoints, scenePointerX, scenePointerY, scene, appState, opts) => {
6959
6965
  const { start, end } = getBindingStrategyForDraggingBindingElementEndpoints(
6960
6966
  arrow,
6961
6967
  draggingPoints,
6968
+ scenePointerX,
6969
+ scenePointerY,
6962
6970
  scene.getNonDeletedElementsMap(),
6963
6971
  scene.getNonDeletedElements(),
6964
6972
  appState,
@@ -7205,7 +7213,7 @@ var bindingStrategyForSimpleArrowEndpointDragging_complex = (point, currentBindi
7205
7213
  }
7206
7214
  return { current, other: isMultiPoint ? { mode: void 0 } : other };
7207
7215
  };
7208
- var getBindingStrategyForDraggingBindingElementEndpoints = (arrow, draggingPoints, elementsMap, elements, appState, opts) => {
7216
+ var getBindingStrategyForDraggingBindingElementEndpoints = (arrow, draggingPoints, screenPointerX, screenPointerY, elementsMap, elements, appState, opts) => {
7209
7217
  if (getFeatureFlag("COMPLEX_BINDINGS")) {
7210
7218
  return getBindingStrategyForDraggingBindingElementEndpoints_complex(
7211
7219
  arrow,
@@ -7219,13 +7227,15 @@ var getBindingStrategyForDraggingBindingElementEndpoints = (arrow, draggingPoint
7219
7227
  return getBindingStrategyForDraggingBindingElementEndpoints_simple(
7220
7228
  arrow,
7221
7229
  draggingPoints,
7230
+ screenPointerX,
7231
+ screenPointerY,
7222
7232
  elementsMap,
7223
7233
  elements,
7224
7234
  appState,
7225
7235
  opts
7226
7236
  );
7227
7237
  };
7228
- var getBindingStrategyForDraggingBindingElementEndpoints_simple = (arrow, draggingPoints, elementsMap, elements, appState, opts) => {
7238
+ var getBindingStrategyForDraggingBindingElementEndpoints_simple = (arrow, draggingPoints, scenePointerX, scenePointerY, elementsMap, elements, appState, opts) => {
7229
7239
  const startIdx = 0;
7230
7240
  const endIdx = arrow.points.length - 1;
7231
7241
  const startDragged = draggingPoints.has(startIdx);
@@ -7275,7 +7285,11 @@ var getBindingStrategyForDraggingBindingElementEndpoints_simple = (arrow, draggi
7275
7285
  elementsMap,
7276
7286
  (e) => maxBindingDistance_simple(appState.zoom)
7277
7287
  );
7278
- const pointInElement = hit && isPointInElement(globalPoint, hit, elementsMap);
7288
+ const pointInElement = hit && (opts?.angleLocked ? isPointInElement(
7289
+ pointFrom8(scenePointerX, scenePointerY),
7290
+ hit,
7291
+ elementsMap
7292
+ ) : isPointInElement(globalPoint, hit, elementsMap));
7279
7293
  const otherBindableElement = otherBinding ? elementsMap.get(
7280
7294
  otherBinding.elementId
7281
7295
  ) : void 0;
@@ -7345,10 +7359,25 @@ var getBindingStrategyForDraggingBindingElementEndpoints_simple = (arrow, draggi
7345
7359
  elementsMap
7346
7360
  ) || globalPoint
7347
7361
  } : { mode: null };
7362
+ const otherEndpoint = LinearElementEditor.getPointAtIndexGlobalCoordinates(
7363
+ arrow,
7364
+ startDragged ? -1 : 0,
7365
+ elementsMap
7366
+ );
7348
7367
  const other = otherBindableElement && !otherFocusPointIsInElement && appState.selectedLinearElement?.initialState.altFocusPoint ? {
7349
7368
  mode: "orbit",
7350
7369
  element: otherBindableElement,
7351
7370
  focusPoint: appState.selectedLinearElement.initialState.altFocusPoint
7371
+ } : opts?.angleLocked && otherBindableElement ? {
7372
+ mode: "orbit",
7373
+ element: otherBindableElement,
7374
+ focusPoint: projectFixedPointOntoDiagonal(
7375
+ arrow,
7376
+ otherEndpoint,
7377
+ otherBindableElement,
7378
+ startDragged ? "end" : "start",
7379
+ elementsMap
7380
+ ) || otherEndpoint
7352
7381
  } : { mode: void 0 };
7353
7382
  return {
7354
7383
  start: startDragged ? current : other,
@@ -7450,6 +7479,8 @@ var bindOrUnbindBindingElements = (selectedArrows, scene, appState) => {
7450
7479
  arrow,
7451
7480
  /* @__PURE__ */ new Map(),
7452
7481
  // No dragging points in this case
7482
+ Infinity,
7483
+ Infinity,
7453
7484
  scene,
7454
7485
  appState
7455
7486
  );
@@ -7578,7 +7609,14 @@ var updateBoundElements = (changedElement, scene, options) => {
7578
7609
  };
7579
7610
  var updateBindings = (latestElement, scene, appState, options) => {
7580
7611
  if (isArrowElement(latestElement)) {
7581
- bindOrUnbindBindingElement(latestElement, /* @__PURE__ */ new Map(), scene, appState);
7612
+ bindOrUnbindBindingElement(
7613
+ latestElement,
7614
+ /* @__PURE__ */ new Map(),
7615
+ Infinity,
7616
+ Infinity,
7617
+ scene,
7618
+ appState
7619
+ );
7582
7620
  } else {
7583
7621
  updateBoundElements(latestElement, scene, {
7584
7622
  ...options,
@@ -7854,7 +7892,11 @@ var snapToMid = (arrowElement, bindTarget, elementsMap, p, tolerance = 0.05) =>
7854
7892
  var compareElementArea = (a2, b2) => b2.width ** 2 + b2.height ** 2 - (a2.width ** 2 + a2.height ** 2);
7855
7893
  var updateBoundPoint = (arrow, startOrEnd, binding, bindableElement, elementsMap, customIntersector) => {
7856
7894
  if (binding == null || // We only need to update the other end if this is a 2 point line element
7857
- binding.elementId !== bindableElement.id && arrow.points.length > 2) {
7895
+ binding.elementId !== bindableElement.id && arrow.points.length > 2 || // Initial arrow created on pointer down needs to not update the points
7896
+ pointsEqual5(
7897
+ arrow.points[arrow.points.length - 1],
7898
+ pointFrom8(0, 0)
7899
+ )) {
7858
7900
  return null;
7859
7901
  }
7860
7902
  const global2 = getGlobalFixedPointForBindableElement(
@@ -8339,6 +8381,356 @@ var normalizeFixedPoint = (fixedPoint) => {
8339
8381
  }
8340
8382
  return fixedPoint;
8341
8383
  };
8384
+ var getShapeType = (element) => {
8385
+ if (element.type === "ellipse" || element.type === "diamond") {
8386
+ return element.type;
8387
+ }
8388
+ return "rectangle";
8389
+ };
8390
+ var SHAPE_CONFIGS = {
8391
+ // rectangle: 15° corners, 75° edges
8392
+ rectangle: [
8393
+ { centerAngle: 0, sectorWidth: 75, side: "right" },
8394
+ { centerAngle: 45, sectorWidth: 15, side: "bottom-right" },
8395
+ { centerAngle: 90, sectorWidth: 75, side: "bottom" },
8396
+ { centerAngle: 135, sectorWidth: 15, side: "bottom-left" },
8397
+ { centerAngle: 180, sectorWidth: 75, side: "left" },
8398
+ { centerAngle: 225, sectorWidth: 15, side: "top-left" },
8399
+ { centerAngle: 270, sectorWidth: 75, side: "top" },
8400
+ { centerAngle: 315, sectorWidth: 15, side: "top-right" }
8401
+ ],
8402
+ // diamond: 15° vertices, 75° edges
8403
+ diamond: [
8404
+ { centerAngle: 0, sectorWidth: 15, side: "right" },
8405
+ { centerAngle: 45, sectorWidth: 75, side: "bottom-right" },
8406
+ { centerAngle: 90, sectorWidth: 15, side: "bottom" },
8407
+ { centerAngle: 135, sectorWidth: 75, side: "bottom-left" },
8408
+ { centerAngle: 180, sectorWidth: 15, side: "left" },
8409
+ { centerAngle: 225, sectorWidth: 75, side: "top-left" },
8410
+ { centerAngle: 270, sectorWidth: 15, side: "top" },
8411
+ { centerAngle: 315, sectorWidth: 75, side: "top-right" }
8412
+ ],
8413
+ // ellipse: 15° cardinal points, 75° diagonals
8414
+ ellipse: [
8415
+ { centerAngle: 0, sectorWidth: 15, side: "right" },
8416
+ { centerAngle: 45, sectorWidth: 75, side: "bottom-right" },
8417
+ { centerAngle: 90, sectorWidth: 15, side: "bottom" },
8418
+ { centerAngle: 135, sectorWidth: 75, side: "bottom-left" },
8419
+ { centerAngle: 180, sectorWidth: 15, side: "left" },
8420
+ { centerAngle: 225, sectorWidth: 75, side: "top-left" },
8421
+ { centerAngle: 270, sectorWidth: 15, side: "top" },
8422
+ { centerAngle: 315, sectorWidth: 75, side: "top-right" }
8423
+ ]
8424
+ };
8425
+ var getSectorBoundaries = (config) => {
8426
+ return config.map((sector, index) => {
8427
+ const halfWidth = sector.sectorWidth / 2;
8428
+ let start = sector.centerAngle - halfWidth;
8429
+ let end = sector.centerAngle + halfWidth;
8430
+ start = (start % 360 + 360) % 360;
8431
+ end = (end % 360 + 360) % 360;
8432
+ return { start, end, side: sector.side };
8433
+ });
8434
+ };
8435
+ var getShapeSideAdaptive = (fixedPoint, shapeType) => {
8436
+ const [x, y] = fixedPoint;
8437
+ const centerX = x - 0.5;
8438
+ const centerY = y - 0.5;
8439
+ let angle = Math.atan2(centerY, centerX);
8440
+ if (angle < 0) {
8441
+ angle += 2 * Math.PI;
8442
+ }
8443
+ const degrees = angle * 180 / Math.PI;
8444
+ const config = SHAPE_CONFIGS[shapeType];
8445
+ const boundaries = getSectorBoundaries(config);
8446
+ for (const boundary of boundaries) {
8447
+ if (boundary.start <= boundary.end) {
8448
+ if (degrees >= boundary.start && degrees <= boundary.end) {
8449
+ return boundary.side;
8450
+ }
8451
+ } else if (degrees >= boundary.start || degrees <= boundary.end) {
8452
+ return boundary.side;
8453
+ }
8454
+ }
8455
+ let minDiff = Infinity;
8456
+ let nearestSide = config[0].side;
8457
+ for (const sector of config) {
8458
+ let diff = Math.abs(degrees - sector.centerAngle);
8459
+ if (diff > 180) {
8460
+ diff = 360 - diff;
8461
+ }
8462
+ if (diff < minDiff) {
8463
+ minDiff = diff;
8464
+ nearestSide = sector.side;
8465
+ }
8466
+ }
8467
+ return nearestSide;
8468
+ };
8469
+ var getBindingSideMidPoint = (binding, elementsMap) => {
8470
+ const bindableElement = elementsMap.get(binding.elementId);
8471
+ if (!bindableElement || bindableElement.isDeleted || !isBindableElement(bindableElement)) {
8472
+ return null;
8473
+ }
8474
+ const center = elementCenterPoint(bindableElement, elementsMap);
8475
+ const shapeType = getShapeType(bindableElement);
8476
+ const side = getShapeSideAdaptive(
8477
+ normalizeFixedPoint(binding.fixedPoint),
8478
+ shapeType
8479
+ );
8480
+ const OFFSET = 0.01;
8481
+ if (bindableElement.type === "diamond") {
8482
+ const [sides, corners] = deconstructDiamondElement(bindableElement);
8483
+ const [bottomRight, bottomLeft, topLeft, topRight] = sides;
8484
+ let x;
8485
+ let y;
8486
+ switch (side) {
8487
+ case "left": {
8488
+ if (corners.length >= 3) {
8489
+ const leftCorner = corners[2];
8490
+ const midPoint = leftCorner[1];
8491
+ x = midPoint[0] - OFFSET;
8492
+ y = midPoint[1];
8493
+ } else {
8494
+ const midPoint = getMidPoint(bottomLeft[1], topLeft[0]);
8495
+ x = midPoint[0] - OFFSET;
8496
+ y = midPoint[1];
8497
+ }
8498
+ break;
8499
+ }
8500
+ case "right": {
8501
+ if (corners.length >= 1) {
8502
+ const rightCorner = corners[0];
8503
+ const midPoint = rightCorner[1];
8504
+ x = midPoint[0] + OFFSET;
8505
+ y = midPoint[1];
8506
+ } else {
8507
+ const midPoint = getMidPoint(topRight[1], bottomRight[0]);
8508
+ x = midPoint[0] + OFFSET;
8509
+ y = midPoint[1];
8510
+ }
8511
+ break;
8512
+ }
8513
+ case "top": {
8514
+ if (corners.length >= 4) {
8515
+ const topCorner = corners[3];
8516
+ const midPoint = topCorner[1];
8517
+ x = midPoint[0];
8518
+ y = midPoint[1] - OFFSET;
8519
+ } else {
8520
+ const midPoint = getMidPoint(topLeft[1], topRight[0]);
8521
+ x = midPoint[0];
8522
+ y = midPoint[1] - OFFSET;
8523
+ }
8524
+ break;
8525
+ }
8526
+ case "bottom": {
8527
+ if (corners.length >= 2) {
8528
+ const bottomCorner = corners[1];
8529
+ const midPoint = bottomCorner[1];
8530
+ x = midPoint[0];
8531
+ y = midPoint[1] + OFFSET;
8532
+ } else {
8533
+ const midPoint = getMidPoint(bottomRight[1], bottomLeft[0]);
8534
+ x = midPoint[0];
8535
+ y = midPoint[1] + OFFSET;
8536
+ }
8537
+ break;
8538
+ }
8539
+ case "top-right": {
8540
+ const midPoint = getMidPoint(topRight[0], topRight[1]);
8541
+ x = midPoint[0] + OFFSET * 0.707;
8542
+ y = midPoint[1] - OFFSET * 0.707;
8543
+ break;
8544
+ }
8545
+ case "bottom-right": {
8546
+ const midPoint = getMidPoint(bottomRight[0], bottomRight[1]);
8547
+ x = midPoint[0] + OFFSET * 0.707;
8548
+ y = midPoint[1] + OFFSET * 0.707;
8549
+ break;
8550
+ }
8551
+ case "bottom-left": {
8552
+ const midPoint = getMidPoint(bottomLeft[0], bottomLeft[1]);
8553
+ x = midPoint[0] - OFFSET * 0.707;
8554
+ y = midPoint[1] + OFFSET * 0.707;
8555
+ break;
8556
+ }
8557
+ case "top-left": {
8558
+ const midPoint = getMidPoint(topLeft[0], topLeft[1]);
8559
+ x = midPoint[0] - OFFSET * 0.707;
8560
+ y = midPoint[1] - OFFSET * 0.707;
8561
+ break;
8562
+ }
8563
+ default: {
8564
+ return null;
8565
+ }
8566
+ }
8567
+ return pointRotateRads8(pointFrom8(x, y), center, bindableElement.angle);
8568
+ }
8569
+ if (bindableElement.type === "ellipse") {
8570
+ const ellipseCenterX = bindableElement.x + bindableElement.width / 2;
8571
+ const ellipseCenterY = bindableElement.y + bindableElement.height / 2;
8572
+ const radiusX = bindableElement.width / 2;
8573
+ const radiusY = bindableElement.height / 2;
8574
+ let x;
8575
+ let y;
8576
+ switch (side) {
8577
+ case "top": {
8578
+ x = ellipseCenterX;
8579
+ y = ellipseCenterY - radiusY - OFFSET;
8580
+ break;
8581
+ }
8582
+ case "right": {
8583
+ x = ellipseCenterX + radiusX + OFFSET;
8584
+ y = ellipseCenterY;
8585
+ break;
8586
+ }
8587
+ case "bottom": {
8588
+ x = ellipseCenterX;
8589
+ y = ellipseCenterY + radiusY + OFFSET;
8590
+ break;
8591
+ }
8592
+ case "left": {
8593
+ x = ellipseCenterX - radiusX - OFFSET;
8594
+ y = ellipseCenterY;
8595
+ break;
8596
+ }
8597
+ case "top-right": {
8598
+ const angle = -Math.PI / 4;
8599
+ const ellipseX = radiusX * Math.cos(angle);
8600
+ const ellipseY = radiusY * Math.sin(angle);
8601
+ x = ellipseCenterX + ellipseX + OFFSET * 0.707;
8602
+ y = ellipseCenterY + ellipseY - OFFSET * 0.707;
8603
+ break;
8604
+ }
8605
+ case "bottom-right": {
8606
+ const angle = Math.PI / 4;
8607
+ const ellipseX = radiusX * Math.cos(angle);
8608
+ const ellipseY = radiusY * Math.sin(angle);
8609
+ x = ellipseCenterX + ellipseX + OFFSET * 0.707;
8610
+ y = ellipseCenterY + ellipseY + OFFSET * 0.707;
8611
+ break;
8612
+ }
8613
+ case "bottom-left": {
8614
+ const angle = 3 * Math.PI / 4;
8615
+ const ellipseX = radiusX * Math.cos(angle);
8616
+ const ellipseY = radiusY * Math.sin(angle);
8617
+ x = ellipseCenterX + ellipseX - OFFSET * 0.707;
8618
+ y = ellipseCenterY + ellipseY + OFFSET * 0.707;
8619
+ break;
8620
+ }
8621
+ case "top-left": {
8622
+ const angle = -3 * Math.PI / 4;
8623
+ const ellipseX = radiusX * Math.cos(angle);
8624
+ const ellipseY = radiusY * Math.sin(angle);
8625
+ x = ellipseCenterX + ellipseX - OFFSET * 0.707;
8626
+ y = ellipseCenterY + ellipseY - OFFSET * 0.707;
8627
+ break;
8628
+ }
8629
+ default: {
8630
+ return null;
8631
+ }
8632
+ }
8633
+ return pointRotateRads8(pointFrom8(x, y), center, bindableElement.angle);
8634
+ }
8635
+ if (isRectangularElement(bindableElement)) {
8636
+ const [sides, corners] = deconstructRectanguloidElement(
8637
+ bindableElement
8638
+ );
8639
+ const [top, right, bottom, left] = sides;
8640
+ let x;
8641
+ let y;
8642
+ switch (side) {
8643
+ case "top": {
8644
+ const midPoint = getMidPoint(top[0], top[1]);
8645
+ x = midPoint[0];
8646
+ y = midPoint[1] - OFFSET;
8647
+ break;
8648
+ }
8649
+ case "right": {
8650
+ const midPoint = getMidPoint(right[0], right[1]);
8651
+ x = midPoint[0] + OFFSET;
8652
+ y = midPoint[1];
8653
+ break;
8654
+ }
8655
+ case "bottom": {
8656
+ const midPoint = getMidPoint(bottom[0], bottom[1]);
8657
+ x = midPoint[0];
8658
+ y = midPoint[1] + OFFSET;
8659
+ break;
8660
+ }
8661
+ case "left": {
8662
+ const midPoint = getMidPoint(left[0], left[1]);
8663
+ x = midPoint[0] - OFFSET;
8664
+ y = midPoint[1];
8665
+ break;
8666
+ }
8667
+ case "top-left": {
8668
+ if (corners.length >= 1) {
8669
+ const corner = corners[0];
8670
+ const p1 = corner[0];
8671
+ const p2 = corner[3];
8672
+ const midPoint = getMidPoint(p1, p2);
8673
+ x = midPoint[0] - OFFSET * 0.707;
8674
+ y = midPoint[1] - OFFSET * 0.707;
8675
+ } else {
8676
+ x = bindableElement.x - OFFSET;
8677
+ y = bindableElement.y - OFFSET;
8678
+ }
8679
+ break;
8680
+ }
8681
+ case "top-right": {
8682
+ if (corners.length >= 2) {
8683
+ const corner = corners[1];
8684
+ const p1 = corner[0];
8685
+ const p2 = corner[3];
8686
+ const midPoint = getMidPoint(p1, p2);
8687
+ x = midPoint[0] + OFFSET * 0.707;
8688
+ y = midPoint[1] - OFFSET * 0.707;
8689
+ } else {
8690
+ x = bindableElement.x + bindableElement.width + OFFSET;
8691
+ y = bindableElement.y - OFFSET;
8692
+ }
8693
+ break;
8694
+ }
8695
+ case "bottom-right": {
8696
+ if (corners.length >= 3) {
8697
+ const corner = corners[2];
8698
+ const p1 = corner[0];
8699
+ const p2 = corner[3];
8700
+ const midPoint = getMidPoint(p1, p2);
8701
+ x = midPoint[0] + OFFSET * 0.707;
8702
+ y = midPoint[1] + OFFSET * 0.707;
8703
+ } else {
8704
+ x = bindableElement.x + bindableElement.width + OFFSET;
8705
+ y = bindableElement.y + bindableElement.height + OFFSET;
8706
+ }
8707
+ break;
8708
+ }
8709
+ case "bottom-left": {
8710
+ if (corners.length >= 4) {
8711
+ const corner = corners[3];
8712
+ const p1 = corner[0];
8713
+ const p2 = corner[3];
8714
+ const midPoint = getMidPoint(p1, p2);
8715
+ x = midPoint[0] - OFFSET * 0.707;
8716
+ y = midPoint[1] + OFFSET * 0.707;
8717
+ } else {
8718
+ x = bindableElement.x - OFFSET;
8719
+ y = bindableElement.y + bindableElement.height + OFFSET;
8720
+ }
8721
+ break;
8722
+ }
8723
+ default: {
8724
+ return null;
8725
+ }
8726
+ }
8727
+ return pointRotateRads8(pointFrom8(x, y), center, bindableElement.angle);
8728
+ }
8729
+ return null;
8730
+ };
8731
+ var getMidPoint = (p1, p2) => {
8732
+ return pointFrom8((p1[0] + p2[0]) / 2, (p1[1] + p2[1]) / 2);
8733
+ };
8342
8734
 
8343
8735
  // src/linearElementEditor.ts
8344
8736
  var getNormalizedPoints = ({
@@ -8375,7 +8767,7 @@ var LinearElementEditor = class _LinearElementEditor {
8375
8767
  pointerDownState;
8376
8768
  constructor(element, elementsMap, isEditing = false) {
8377
8769
  this.elementId = element.id;
8378
- if (!pointsEqual5(element.points[0], pointFrom9(0, 0))) {
8770
+ if (!pointsEqual6(element.points[0], pointFrom9(0, 0))) {
8379
8771
  console.error("Linear element is not normalized", Error().stack);
8380
8772
  mutateElement(
8381
8773
  element,
@@ -8465,14 +8857,9 @@ var LinearElementEditor = class _LinearElementEditor {
8465
8857
  const point = element.points[idx];
8466
8858
  const pivotPoint = element.points[idx - 1];
8467
8859
  const customLineAngle = linearElementEditor.customLineAngle ?? determineCustomLinearAngle(pivotPoint, element.points[idx]);
8468
- const hoveredElement = getHoveredElementForBinding2(
8469
- pointFrom9(scenePointerX, scenePointerY),
8470
- elements,
8471
- elementsMap
8472
- );
8473
8860
  let deltaX = 0;
8474
8861
  let deltaY = 0;
8475
- if (shouldRotateWithDiscreteAngle(event) && !hoveredElement && !element.startBinding && !element.endBinding) {
8862
+ if (shouldRotateWithDiscreteAngle(event)) {
8476
8863
  const [width, height] = _LinearElementEditor._getShiftLockedDelta(
8477
8864
  element,
8478
8865
  elementsMap,
@@ -8503,11 +8890,13 @@ var LinearElementEditor = class _LinearElementEditor {
8503
8890
  [idx],
8504
8891
  deltaX,
8505
8892
  deltaY,
8893
+ scenePointerX,
8894
+ scenePointerY,
8506
8895
  elementsMap,
8507
8896
  element,
8508
8897
  elements,
8509
8898
  app,
8510
- event.shiftKey,
8899
+ shouldRotateWithDiscreteAngle(event),
8511
8900
  event.altKey
8512
8901
  );
8513
8902
  _LinearElementEditor.movePoints(element, app.scene, positions, {
@@ -8597,14 +8986,9 @@ var LinearElementEditor = class _LinearElementEditor {
8597
8986
  const endIsSelected = selectedPointsIndices.includes(
8598
8987
  element.points.length - 1
8599
8988
  );
8600
- const hoveredElement = getHoveredElementForBinding2(
8601
- pointFrom9(scenePointerX, scenePointerY),
8602
- elements,
8603
- elementsMap
8604
- );
8605
8989
  let deltaX = 0;
8606
8990
  let deltaY = 0;
8607
- if (shouldRotateWithDiscreteAngle(event) && singlePointDragged && !hoveredElement && !element.startBinding && !element.endBinding) {
8991
+ if (shouldRotateWithDiscreteAngle(event) && singlePointDragged) {
8608
8992
  const [width, height] = _LinearElementEditor._getShiftLockedDelta(
8609
8993
  element,
8610
8994
  elementsMap,
@@ -8635,11 +9019,13 @@ var LinearElementEditor = class _LinearElementEditor {
8635
9019
  selectedPointsIndices,
8636
9020
  deltaX,
8637
9021
  deltaY,
9022
+ scenePointerX,
9023
+ scenePointerY,
8638
9024
  elementsMap,
8639
9025
  element,
8640
9026
  elements,
8641
9027
  app,
8642
- event.shiftKey,
9028
+ shouldRotateWithDiscreteAngle(event) && singlePointDragged,
8643
9029
  event.altKey
8644
9030
  );
8645
9031
  _LinearElementEditor.movePoints(element, app.scene, positions, {
@@ -9060,7 +9446,7 @@ var LinearElementEditor = class _LinearElementEditor {
9060
9446
  if (!point1 || !point2) {
9061
9447
  return false;
9062
9448
  }
9063
- return pointsEqual5(point1, point2);
9449
+ return pointsEqual6(point1, point2);
9064
9450
  }
9065
9451
  static handlePointerMoveInEditMode(event, scenePointerX, scenePointerY, app) {
9066
9452
  const appState = app.state;
@@ -9713,7 +10099,7 @@ var normalizeSelectedPoints = (points) => {
9713
10099
  nextPoints = nextPoints.sort((a2, b2) => a2 - b2);
9714
10100
  return nextPoints.length ? nextPoints : null;
9715
10101
  };
9716
- var pointDraggingUpdates = (selectedPointsIndices, deltaX, deltaY, elementsMap, element, elements, app, shiftKey, altKey) => {
10102
+ var pointDraggingUpdates = (selectedPointsIndices, deltaX, deltaY, scenePointerX, scenePointerY, elementsMap, element, elements, app, angleLocked, altKey) => {
9717
10103
  const naiveDraggingPoints = new Map(
9718
10104
  selectedPointsIndices.map((pointIndex) => {
9719
10105
  return [
@@ -9740,12 +10126,14 @@ var pointDraggingUpdates = (selectedPointsIndices, deltaX, deltaY, elementsMap,
9740
10126
  const { start, end } = getBindingStrategyForDraggingBindingElementEndpoints(
9741
10127
  element,
9742
10128
  naiveDraggingPoints,
10129
+ scenePointerX,
10130
+ scenePointerY,
9743
10131
  elementsMap,
9744
10132
  elements,
9745
10133
  app.state,
9746
10134
  {
9747
10135
  newArrow: !!app.state.newElement,
9748
- shiftKey,
10136
+ angleLocked,
9749
10137
  altKey
9750
10138
  }
9751
10139
  );
@@ -9823,7 +10211,8 @@ var pointDraggingUpdates = (selectedPointsIndices, deltaX, deltaY, elementsMap,
9823
10211
  startBinding: updates.startBinding === void 0 ? element.startBinding : updates.startBinding === null ? null : updates.startBinding,
9824
10212
  endBinding: updates.endBinding === void 0 ? element.endBinding : updates.endBinding === null ? null : updates.endBinding
9825
10213
  };
9826
- const customIntersector = start.focusPoint && end.focusPoint ? lineSegment5(start.focusPoint, end.focusPoint) : void 0;
10214
+ const startCustomIntersector = start.focusPoint && end.focusPoint ? lineSegment5(start.focusPoint, end.focusPoint) : void 0;
10215
+ const endCustomIntersector = start.focusPoint && end.focusPoint ? lineSegment5(end.focusPoint, start.focusPoint) : void 0;
9827
10216
  const startIsDraggingOverEndElement = element.endBinding && nextArrow.startBinding && startIsDragged && nextArrow.startBinding.elementId === element.endBinding.elementId;
9828
10217
  const endIsDraggingOverStartElement = element.startBinding && nextArrow.endBinding && endIsDragged && element.startBinding.elementId === nextArrow.endBinding.elementId;
9829
10218
  const endBindable = nextArrow.endBinding ? end.element ?? elementsMap.get(
@@ -9835,7 +10224,7 @@ var pointDraggingUpdates = (selectedPointsIndices, deltaX, deltaY, elementsMap,
9835
10224
  nextArrow.endBinding,
9836
10225
  endBindable,
9837
10226
  elementsMap,
9838
- customIntersector
10227
+ endCustomIntersector
9839
10228
  ) || nextArrow.points[nextArrow.points.length - 1] : nextArrow.points[nextArrow.points.length - 1];
9840
10229
  nextArrow.points[nextArrow.points.length - 1] = endLocalPoint;
9841
10230
  const startBindable = nextArrow.startBinding ? start.element ?? elementsMap.get(
@@ -9847,7 +10236,7 @@ var pointDraggingUpdates = (selectedPointsIndices, deltaX, deltaY, elementsMap,
9847
10236
  nextArrow.startBinding,
9848
10237
  startBindable,
9849
10238
  elementsMap,
9850
- customIntersector
10239
+ startCustomIntersector
9851
10240
  ) || nextArrow.points[0] : nextArrow.points[0];
9852
10241
  const endChanged = pointDistance5(
9853
10242
  endLocalPoint,
@@ -11019,11 +11408,7 @@ var frameAndChildrenSelectedTogether = (selectedElements) => {
11019
11408
  };
11020
11409
 
11021
11410
  // src/renderElement.ts
11022
- var IMAGE_INVERT_FILTER = "invert(100%) hue-rotate(180deg) saturate(1.25)";
11023
11411
  var isPendingImageElement = (element, renderConfig) => isInitializedImageElement(element) && !renderConfig.imageCache.has(element.fileId);
11024
- var shouldResetImageFilter = (element, renderConfig, appState) => {
11025
- return appState.theme === THEME.DARK && isInitializedImageElement(element) && !isPendingImageElement(element, renderConfig) && renderConfig.imageCache.get(element.fileId)?.mimeType !== MIME_TYPES.svg;
11026
- };
11027
11412
  var getCanvasPadding = (element) => {
11028
11413
  switch (element.type) {
11029
11414
  case "freedraw":
@@ -11095,9 +11480,6 @@ var generateElementCanvas = (element, elementsMap, zoom, renderConfig, appState)
11095
11480
  window.devicePixelRatio * scale
11096
11481
  );
11097
11482
  const rc = rough_default.canvas(canvas);
11098
- if (shouldResetImageFilter(element, renderConfig, appState)) {
11099
- context.filter = IMAGE_INVERT_FILTER;
11100
- }
11101
11483
  drawElementOnCanvas(element, rc, context, renderConfig);
11102
11484
  context.restore();
11103
11485
  const boundTextElement = getBoundTextElement(element, elementsMap);
@@ -11186,28 +11568,31 @@ var drawElementOnCanvas = (element, rc, context, renderConfig) => {
11186
11568
  case "ellipse": {
11187
11569
  context.lineJoin = "round";
11188
11570
  context.lineCap = "round";
11189
- rc.draw(ShapeCache.get(element));
11571
+ rc.draw(ShapeCache.generateElementShape(element, renderConfig));
11190
11572
  break;
11191
11573
  }
11192
11574
  case "arrow":
11193
11575
  case "line": {
11194
11576
  context.lineJoin = "round";
11195
11577
  context.lineCap = "round";
11196
- ShapeCache.get(element).forEach((shape) => {
11197
- rc.draw(shape);
11198
- });
11578
+ ShapeCache.generateElementShape(element, renderConfig).forEach(
11579
+ (shape) => {
11580
+ rc.draw(shape);
11581
+ }
11582
+ );
11199
11583
  break;
11200
11584
  }
11201
11585
  case "freedraw": {
11202
11586
  context.save();
11203
- context.fillStyle = element.strokeColor;
11204
- const path = getFreeDrawPath2D(element);
11205
- const fillShape = ShapeCache.get(element);
11206
- if (fillShape) {
11207
- rc.draw(fillShape);
11208
- }
11209
- context.fillStyle = element.strokeColor;
11210
- context.fill(path);
11587
+ const shapes = ShapeCache.generateElementShape(element, renderConfig);
11588
+ for (const shape of shapes) {
11589
+ if (typeof shape === "string") {
11590
+ context.fillStyle = renderConfig.theme === THEME.DARK ? applyDarkModeFilter(element.strokeColor) : element.strokeColor;
11591
+ context.fill(new Path2D(shape));
11592
+ } else {
11593
+ rc.draw(shape);
11594
+ }
11595
+ }
11211
11596
  context.restore();
11212
11597
  break;
11213
11598
  }
@@ -11257,7 +11642,7 @@ var drawElementOnCanvas = (element, rc, context, renderConfig) => {
11257
11642
  context.canvas.setAttribute("dir", rtl ? "rtl" : "ltr");
11258
11643
  context.save();
11259
11644
  context.font = getFontString3(element);
11260
- context.fillStyle = element.strokeColor;
11645
+ context.fillStyle = renderConfig.theme === THEME.DARK ? applyDarkModeFilter(element.strokeColor) : element.strokeColor;
11261
11646
  context.textAlign = element.textAlign;
11262
11647
  const lines = element.text.replace(/\r\n?/g, "\n").split("\n");
11263
11648
  const horizontalOffset = element.textAlign === "center" ? element.width / 2 : element.textAlign === "right" ? element.width : 0;
@@ -11405,9 +11790,9 @@ var renderElement = (element, elementsMap, allElementsMap, rc, context, renderCo
11405
11790
  );
11406
11791
  context.fillStyle = "rgba(0, 0, 200, 0.04)";
11407
11792
  context.lineWidth = FRAME_STYLE.strokeWidth / appState.zoom.value;
11408
- context.strokeStyle = FRAME_STYLE.strokeColor;
11793
+ context.strokeStyle = appState.theme === THEME.DARK ? applyDarkModeFilter(FRAME_STYLE.strokeColor) : FRAME_STYLE.strokeColor;
11409
11794
  if (isMagicFrameElement(element)) {
11410
- context.strokeStyle = appState.theme === THEME.LIGHT ? "#7affd7" : "#1d8264";
11795
+ context.strokeStyle = appState.theme === THEME.LIGHT ? "#7affd7" : applyDarkModeFilter("#1d8264");
11411
11796
  }
11412
11797
  if (FRAME_STYLE.radius && context.roundRect) {
11413
11798
  context.beginPath();
@@ -11428,7 +11813,6 @@ var renderElement = (element, elementsMap, allElementsMap, rc, context, renderCo
11428
11813
  break;
11429
11814
  }
11430
11815
  case "freedraw": {
11431
- ShapeCache.generateElementShape(element, null);
11432
11816
  if (renderConfig.isExporting) {
11433
11817
  const [x1, y1, x2, y2] = getElementAbsoluteCoords2(element, elementsMap);
11434
11818
  const cx = (x1 + x2) / 2 + appState.scrollX;
@@ -11470,7 +11854,6 @@ var renderElement = (element, elementsMap, allElementsMap, rc, context, renderCo
11470
11854
  case "text":
11471
11855
  case "iframe":
11472
11856
  case "embeddable": {
11473
- ShapeCache.generateElementShape(element, renderConfig);
11474
11857
  if (renderConfig.isExporting) {
11475
11858
  const [x1, y1, x2, y2] = getElementAbsoluteCoords2(element, elementsMap);
11476
11859
  const cx = (x1 + x2) / 2 + appState.scrollX;
@@ -11491,9 +11874,6 @@ var renderElement = (element, elementsMap, allElementsMap, rc, context, renderCo
11491
11874
  }
11492
11875
  context.save();
11493
11876
  context.translate(cx, cy);
11494
- if (shouldResetImageFilter(element, renderConfig, appState)) {
11495
- context.filter = "none";
11496
- }
11497
11877
  const boundTextElement = getBoundTextElement(element, elementsMap);
11498
11878
  if (isArrowElement(element) && boundTextElement) {
11499
11879
  const tempCanvas = document.createElement("canvas");
@@ -11605,19 +11985,6 @@ var renderElement = (element, elementsMap, allElementsMap, rc, context, renderCo
11605
11985
  }
11606
11986
  context.globalAlpha = 1;
11607
11987
  };
11608
- var pathsCache = /* @__PURE__ */ new WeakMap([]);
11609
- function generateFreeDrawShape(element) {
11610
- const svgPathData = getFreeDrawSvgPath(element);
11611
- const path = new Path2D(svgPathData);
11612
- pathsCache.set(element, path);
11613
- return path;
11614
- }
11615
- function getFreeDrawPath2D(element) {
11616
- return pathsCache.get(element);
11617
- }
11618
- function getFreeDrawSvgPath(element) {
11619
- return getSvgPathFromStroke(getFreedrawOutlinePoints(element));
11620
- }
11621
11988
  function getFreedrawOutlineAsSegments(element, points, elementsMap) {
11622
11989
  const bounds = getElementBounds(
11623
11990
  {
@@ -11667,46 +12034,11 @@ function getFreedrawOutlineAsSegments(element, points, elementsMap) {
11667
12034
  ]
11668
12035
  );
11669
12036
  }
11670
- function getFreedrawOutlinePoints(element) {
11671
- const inputPoints = element.simulatePressure ? element.points : element.points.length ? element.points.map(([x, y], i) => [x, y, element.pressures[i]]) : [[0, 0, 0.5]];
11672
- const options = {
11673
- simulatePressure: element.simulatePressure,
11674
- size: element.strokeWidth * 4.25,
11675
- thinning: 0.6,
11676
- smoothing: 0.5,
11677
- streamline: 0.5,
11678
- easing: (t) => Math.sin(t * Math.PI / 2),
11679
- // https://easings.net/#easeOutSine
11680
- last: true
11681
- };
11682
- return ae(inputPoints, options);
11683
- }
11684
- function med(A2, B2) {
11685
- return [(A2[0] + B2[0]) / 2, (A2[1] + B2[1]) / 2];
11686
- }
11687
- var TO_FIXED_PRECISION = /(\s?[A-Z]?,?-?[0-9]*\.[0-9]{0,2})(([0-9]|e|-)*)/g;
11688
- function getSvgPathFromStroke(points) {
11689
- if (!points.length) {
11690
- return "";
11691
- }
11692
- const max = points.length - 1;
11693
- return points.reduce(
11694
- (acc, point, i, arr) => {
11695
- if (i === max) {
11696
- acc.push(point, med(point, arr[0]), "L", arr[0], "Z");
11697
- } else {
11698
- acc.push(point, med(point, arr[i + 1]));
11699
- }
11700
- return acc;
11701
- },
11702
- ["M", points[0], "Q"]
11703
- ).join(" ").replace(TO_FIXED_PRECISION, "$1");
11704
- }
11705
12037
 
11706
12038
  // src/comparisons.ts
11707
12039
  init_define_import_meta_env();
11708
12040
  var hasBackground = (type) => type === "rectangle" || type === "iframe" || type === "embeddable" || type === "ellipse" || type === "diamond" || type === "line" || type === "freedraw";
11709
- var hasStrokeColor = (type) => type === "rectangle" || type === "ellipse" || type === "diamond" || type === "freedraw" || type === "arrow" || type === "line" || type === "text";
12041
+ var hasStrokeColor = (type) => type === "rectangle" || type === "ellipse" || type === "diamond" || type === "freedraw" || type === "arrow" || type === "line" || type === "text" || type === "embeddable";
11710
12042
  var hasStrokeWidth = (type) => type === "rectangle" || type === "iframe" || type === "embeddable" || type === "ellipse" || type === "diamond" || type === "freedraw" || type === "arrow" || type === "line";
11711
12043
  var hasStrokeStyle = (type) => type === "rectangle" || type === "iframe" || type === "embeddable" || type === "ellipse" || type === "diamond" || type === "arrow" || type === "line";
11712
12044
  var canChangeRoundness = (type) => type === "rectangle" || type === "iframe" || type === "embeddable" || type === "line" || type === "diamond" || type === "image";
@@ -11721,13 +12053,17 @@ var ShapeCache = class _ShapeCache {
11721
12053
  * Retrieves shape from cache if available. Use this only if shape
11722
12054
  * is optional and you have a fallback in case it's not cached.
11723
12055
  */
11724
- static get = (element) => {
11725
- return _ShapeCache.cache.get(
11726
- element
11727
- );
12056
+ static get = (element, theme) => {
12057
+ const cached = _ShapeCache.cache.get(element);
12058
+ if (cached && (theme === null || cached.theme === theme)) {
12059
+ return cached.shape;
12060
+ }
12061
+ return void 0;
12062
+ };
12063
+ static delete = (element) => {
12064
+ _ShapeCache.cache.delete(element);
12065
+ elementWithCanvasCache.delete(element);
11728
12066
  };
11729
- static set = (element, shape) => _ShapeCache.cache.set(element, shape);
11730
- static delete = (element) => _ShapeCache.cache.delete(element);
11731
12067
  static destroy = () => {
11732
12068
  _ShapeCache.cache = /* @__PURE__ */ new WeakMap();
11733
12069
  };
@@ -11736,21 +12072,27 @@ var ShapeCache = class _ShapeCache {
11736
12072
  * returns cached shape.
11737
12073
  */
11738
12074
  static generateElementShape = (element, renderConfig) => {
11739
- const cachedShape = renderConfig?.isExporting ? void 0 : _ShapeCache.get(element);
12075
+ const cachedShape = renderConfig?.isExporting ? void 0 : _ShapeCache.get(element, renderConfig ? renderConfig.theme : null);
11740
12076
  if (cachedShape !== void 0) {
11741
12077
  return cachedShape;
11742
12078
  }
11743
12079
  elementWithCanvasCache.delete(element);
11744
- const shape = generateElementShape(
12080
+ const shape = _generateElementShape(
11745
12081
  element,
11746
12082
  _ShapeCache.rg,
11747
12083
  renderConfig || {
11748
12084
  isExporting: false,
11749
12085
  canvasBackgroundColor: COLOR_PALETTE.white,
11750
- embedsValidationStatus: null
12086
+ embedsValidationStatus: null,
12087
+ theme: THEME2.LIGHT
11751
12088
  }
11752
12089
  );
11753
- _ShapeCache.cache.set(element, shape);
12090
+ if (!renderConfig?.isExporting) {
12091
+ _ShapeCache.cache.set(element, {
12092
+ shape,
12093
+ theme: renderConfig?.theme || THEME2.LIGHT
12094
+ });
12095
+ }
11754
12096
  return shape;
11755
12097
  };
11756
12098
  };
@@ -11770,7 +12112,7 @@ function adjustRoughness(element) {
11770
12112
  }
11771
12113
  return Math.min(roughness / (maxSize < 10 ? 3 : 2), 2.5);
11772
12114
  }
11773
- var generateRoughOptions = (element, continuousPath = false) => {
12115
+ var generateRoughOptions = (element, continuousPath = false, isDarkMode = false) => {
11774
12116
  const options = {
11775
12117
  seed: element.seed,
11776
12118
  strokeLineDash: element.strokeStyle === "dashed" ? getDashArrayDashed(element.strokeWidth) : element.strokeStyle === "dotted" ? getDashArrayDotted(element.strokeWidth) : void 0,
@@ -11786,7 +12128,7 @@ var generateRoughOptions = (element, continuousPath = false) => {
11786
12128
  fillWeight: element.strokeWidth / 2,
11787
12129
  hachureGap: element.strokeWidth * 4,
11788
12130
  roughness: adjustRoughness(element),
11789
- stroke: element.strokeColor,
12131
+ stroke: isDarkMode ? applyDarkModeFilter2(element.strokeColor) : element.strokeColor,
11790
12132
  preserveVertices: continuousPath || element.roughness < ROUGHNESS.cartoonist
11791
12133
  };
11792
12134
  switch (element.type) {
@@ -11796,7 +12138,7 @@ var generateRoughOptions = (element, continuousPath = false) => {
11796
12138
  case "diamond":
11797
12139
  case "ellipse": {
11798
12140
  options.fillStyle = element.fillStyle;
11799
- options.fill = isTransparent3(element.backgroundColor) ? void 0 : element.backgroundColor;
12141
+ options.fill = isTransparent3(element.backgroundColor) ? void 0 : isDarkMode ? applyDarkModeFilter2(element.backgroundColor) : element.backgroundColor;
11800
12142
  if (element.type === "ellipse") {
11801
12143
  options.curveFitting = 1;
11802
12144
  }
@@ -11806,7 +12148,7 @@ var generateRoughOptions = (element, continuousPath = false) => {
11806
12148
  case "freedraw": {
11807
12149
  if (isPathALoop(element.points)) {
11808
12150
  options.fillStyle = element.fillStyle;
11809
- options.fill = element.backgroundColor === "transparent" ? void 0 : element.backgroundColor;
12151
+ options.fill = element.backgroundColor === "transparent" ? void 0 : isDarkMode ? applyDarkModeFilter2(element.backgroundColor) : element.backgroundColor;
11810
12152
  }
11811
12153
  return options;
11812
12154
  }
@@ -11834,7 +12176,7 @@ var modifyIframeLikeForRoughOptions = (element, isExporting, embedsValidationSta
11834
12176
  }
11835
12177
  return element;
11836
12178
  };
11837
- var getArrowheadShapes = (element, shape, position, arrowhead, generator, options, canvasBackgroundColor) => {
12179
+ var getArrowheadShapes = (element, shape, position, arrowhead, generator, options, canvasBackgroundColor, isDarkMode) => {
11838
12180
  const arrowheadPoints = getArrowheadPoints(
11839
12181
  element,
11840
12182
  shape,
@@ -11851,6 +12193,7 @@ var getArrowheadShapes = (element, shape, position, arrowhead, generator, option
11851
12193
  const [, , x3, y3, x4, y4] = arrowheadPoints2;
11852
12194
  return [generator.line(x3, y3, x4, y4, options2)];
11853
12195
  };
12196
+ const strokeColor = isDarkMode ? applyDarkModeFilter2(element.strokeColor) : element.strokeColor;
11854
12197
  switch (arrowhead) {
11855
12198
  case "dot":
11856
12199
  case "circle":
@@ -11860,9 +12203,9 @@ var getArrowheadShapes = (element, shape, position, arrowhead, generator, option
11860
12203
  return [
11861
12204
  generator.circle(x, y, diameter, {
11862
12205
  ...options,
11863
- fill: arrowhead === "circle_outline" ? canvasBackgroundColor : element.strokeColor,
12206
+ fill: arrowhead === "circle_outline" ? canvasBackgroundColor : strokeColor,
11864
12207
  fillStyle: "solid",
11865
- stroke: element.strokeColor,
12208
+ stroke: strokeColor,
11866
12209
  roughness: Math.min(0.5, options.roughness || 0)
11867
12210
  })
11868
12211
  ];
@@ -11881,7 +12224,7 @@ var getArrowheadShapes = (element, shape, position, arrowhead, generator, option
11881
12224
  ],
11882
12225
  {
11883
12226
  ...options,
11884
- fill: arrowhead === "triangle_outline" ? canvasBackgroundColor : element.strokeColor,
12227
+ fill: arrowhead === "triangle_outline" ? canvasBackgroundColor : strokeColor,
11885
12228
  fillStyle: "solid",
11886
12229
  roughness: Math.min(1, options.roughness || 0)
11887
12230
  }
@@ -11903,7 +12246,7 @@ var getArrowheadShapes = (element, shape, position, arrowhead, generator, option
11903
12246
  ],
11904
12247
  {
11905
12248
  ...options,
11906
- fill: arrowhead === "diamond_outline" ? canvasBackgroundColor : element.strokeColor,
12249
+ fill: arrowhead === "diamond_outline" ? canvasBackgroundColor : strokeColor,
11907
12250
  fillStyle: "solid",
11908
12251
  roughness: Math.min(1, options.roughness || 0)
11909
12252
  }
@@ -12084,11 +12427,13 @@ var generateLinearCollisionShape = (element) => {
12084
12427
  }
12085
12428
  }
12086
12429
  };
12087
- var generateElementShape = (element, generator, {
12430
+ var _generateElementShape = (element, generator, {
12088
12431
  isExporting,
12089
12432
  canvasBackgroundColor,
12090
- embedsValidationStatus
12433
+ embedsValidationStatus,
12434
+ theme
12091
12435
  }) => {
12436
+ const isDarkMode = theme === THEME2.DARK;
12092
12437
  switch (element.type) {
12093
12438
  case "rectangle":
12094
12439
  case "iframe":
@@ -12106,7 +12451,8 @@ var generateElementShape = (element, generator, {
12106
12451
  isExporting,
12107
12452
  embedsValidationStatus
12108
12453
  ),
12109
- true
12454
+ true,
12455
+ isDarkMode
12110
12456
  )
12111
12457
  );
12112
12458
  } else {
@@ -12121,7 +12467,8 @@ var generateElementShape = (element, generator, {
12121
12467
  isExporting,
12122
12468
  embedsValidationStatus
12123
12469
  ),
12124
- false
12470
+ false,
12471
+ isDarkMode
12125
12472
  )
12126
12473
  );
12127
12474
  }
@@ -12145,7 +12492,7 @@ var generateElementShape = (element, generator, {
12145
12492
  C ${leftX} ${leftY}, ${leftX} ${leftY}, ${leftX + verticalRadius} ${leftY - horizontalRadius}
12146
12493
  L ${topX - verticalRadius} ${topY + horizontalRadius}
12147
12494
  C ${topX} ${topY}, ${topX} ${topY}, ${topX + verticalRadius} ${topY + horizontalRadius}`,
12148
- generateRoughOptions(element, true)
12495
+ generateRoughOptions(element, true, isDarkMode)
12149
12496
  );
12150
12497
  } else {
12151
12498
  shape = generator.polygon(
@@ -12155,7 +12502,7 @@ var generateElementShape = (element, generator, {
12155
12502
  [bottomX, bottomY],
12156
12503
  [leftX, leftY]
12157
12504
  ],
12158
- generateRoughOptions(element)
12505
+ generateRoughOptions(element, false, isDarkMode)
12159
12506
  );
12160
12507
  }
12161
12508
  return shape;
@@ -12166,14 +12513,14 @@ var generateElementShape = (element, generator, {
12166
12513
  element.height / 2,
12167
12514
  element.width,
12168
12515
  element.height,
12169
- generateRoughOptions(element)
12516
+ generateRoughOptions(element, false, isDarkMode)
12170
12517
  );
12171
12518
  return shape;
12172
12519
  }
12173
12520
  case "line":
12174
12521
  case "arrow": {
12175
12522
  let shape;
12176
- const options = generateRoughOptions(element);
12523
+ const options = generateRoughOptions(element, false, isDarkMode);
12177
12524
  const points = element.points.length ? element.points : [pointFrom13(0, 0)];
12178
12525
  if (isElbowArrow(element)) {
12179
12526
  if (!points.every(
@@ -12189,7 +12536,7 @@ var generateElementShape = (element, generator, {
12189
12536
  shape = [
12190
12537
  generator.path(
12191
12538
  generateElbowArrowShape(points, 16),
12192
- generateRoughOptions(element, true)
12539
+ generateRoughOptions(element, true, isDarkMode)
12193
12540
  )
12194
12541
  ];
12195
12542
  }
@@ -12216,7 +12563,8 @@ var generateElementShape = (element, generator, {
12216
12563
  startArrowhead,
12217
12564
  generator,
12218
12565
  options,
12219
- canvasBackgroundColor
12566
+ canvasBackgroundColor,
12567
+ isDarkMode
12220
12568
  );
12221
12569
  shape.push(...shapes);
12222
12570
  }
@@ -12230,7 +12578,8 @@ var generateElementShape = (element, generator, {
12230
12578
  endArrowhead,
12231
12579
  generator,
12232
12580
  options,
12233
- canvasBackgroundColor
12581
+ canvasBackgroundColor,
12582
+ isDarkMode
12234
12583
  );
12235
12584
  shape.push(...shapes);
12236
12585
  }
@@ -12238,21 +12587,21 @@ var generateElementShape = (element, generator, {
12238
12587
  return shape;
12239
12588
  }
12240
12589
  case "freedraw": {
12241
- let shape;
12242
- generateFreeDrawShape(element);
12590
+ const shapes = [];
12243
12591
  if (isPathALoop(element.points)) {
12244
12592
  const simplifiedPoints = simplify(
12245
12593
  element.points,
12246
12594
  0.75
12247
12595
  );
12248
- shape = generator.curve(simplifiedPoints, {
12249
- ...generateRoughOptions(element),
12250
- stroke: "none"
12251
- });
12252
- } else {
12253
- shape = null;
12596
+ shapes.push(
12597
+ generator.curve(simplifiedPoints, {
12598
+ ...generateRoughOptions(element, false, isDarkMode),
12599
+ stroke: "none"
12600
+ })
12601
+ );
12254
12602
  }
12255
- return shape;
12603
+ shapes.push(getFreeDrawSvgPath(element));
12604
+ return shapes;
12256
12605
  }
12257
12606
  case "frame":
12258
12607
  case "magicframe":
@@ -12331,7 +12680,7 @@ var getElementShape = (element, elementsMap) => {
12331
12680
  return getPolygonShape(element);
12332
12681
  case "arrow":
12333
12682
  case "line": {
12334
- const roughShape = ShapeCache.get(element)?.[0] ?? ShapeCache.generateElementShape(element, null)[0];
12683
+ const roughShape = ShapeCache.generateElementShape(element, null)[0];
12335
12684
  const [, , , , cx, cy] = getElementAbsoluteCoords2(element, elementsMap);
12336
12685
  return shouldTestInside(element) ? getClosedCurveShape(
12337
12686
  element,
@@ -12385,6 +12734,45 @@ var toggleLinePolygonState = (element, nextPolygonState) => {
12385
12734
  };
12386
12735
  return ret;
12387
12736
  };
12737
+ var getFreeDrawSvgPath = (element) => {
12738
+ return getSvgPathFromStroke(
12739
+ getFreedrawOutlinePoints(element)
12740
+ );
12741
+ };
12742
+ var getFreedrawOutlinePoints = (element) => {
12743
+ const inputPoints = element.simulatePressure ? element.points : element.points.length ? element.points.map(([x, y], i) => [x, y, element.pressures[i]]) : [[0, 0, 0.5]];
12744
+ return ae(inputPoints, {
12745
+ simulatePressure: element.simulatePressure,
12746
+ size: element.strokeWidth * 4.25,
12747
+ thinning: 0.6,
12748
+ smoothing: 0.5,
12749
+ streamline: 0.5,
12750
+ easing: (t) => Math.sin(t * Math.PI / 2),
12751
+ // https://easings.net/#easeOutSine
12752
+ last: true
12753
+ });
12754
+ };
12755
+ var med = (A2, B2) => {
12756
+ return [(A2[0] + B2[0]) / 2, (A2[1] + B2[1]) / 2];
12757
+ };
12758
+ var TO_FIXED_PRECISION = /(\s?[A-Z]?,?-?[0-9]*\.[0-9]{0,2})(([0-9]|e|-)*)/g;
12759
+ var getSvgPathFromStroke = (points) => {
12760
+ if (!points.length) {
12761
+ return "";
12762
+ }
12763
+ const max = points.length - 1;
12764
+ return points.reduce(
12765
+ (acc, point, i, arr) => {
12766
+ if (i === max) {
12767
+ acc.push(point, med(point, arr[0]), "L", arr[0], "Z");
12768
+ } else {
12769
+ acc.push(point, med(point, arr[i + 1]));
12770
+ }
12771
+ return acc;
12772
+ },
12773
+ ["M", points[0], "Q"]
12774
+ ).join(" ").replace(TO_FIXED_PRECISION, "$1");
12775
+ };
12388
12776
 
12389
12777
  // src/bounds.ts
12390
12778
  var ElementBounds = class _ElementBounds {
@@ -12983,7 +13371,7 @@ var getLinearElementRotatedBounds = (element, cx, cy, elementsMap) => {
12983
13371
  }
12984
13372
  return coords2;
12985
13373
  }
12986
- const cachedShape = ShapeCache.get(element)?.[0];
13374
+ const cachedShape = ShapeCache.get(element, null)?.[0];
12987
13375
  const shape = cachedShape ?? generateLinearElementShape(element);
12988
13376
  const ops = getCurvePathOps(shape);
12989
13377
  const transformXY = ([x, y]) => pointRotateRads13(
@@ -13210,7 +13598,7 @@ var elementCenterPoint = (element, elementsMap, xOffset = 0, yOffset = 0) => {
13210
13598
  var INVISIBLY_SMALL_ELEMENT_SIZE = 0.1;
13211
13599
  var isInvisiblySmallElement = (element) => {
13212
13600
  if (isLinearElement(element) || isFreeDrawElement(element)) {
13213
- return element.points.length < 2 || element.points.length === 2 && isArrowElement(element) && pointsEqual6(
13601
+ return element.points.length < 2 || element.points.length === 2 && isArrowElement(element) && pointsEqual7(
13214
13602
  element.points[0],
13215
13603
  element.points[element.points.length - 1],
13216
13604
  INVISIBLY_SMALL_ELEMENT_SIZE
@@ -19499,9 +19887,515 @@ var showSelectedShapeActions = (appState, elements) => Boolean(
19499
19887
  !appState.viewModeEnabled && appState.openDialog?.name !== "elementLinkSelector" && (appState.activeTool.type !== "custom" && (appState.editingTextElement || appState.activeTool.type !== "selection" && appState.activeTool.type !== "lasso" && appState.activeTool.type !== "eraser" && appState.activeTool.type !== "hand" && appState.activeTool.type !== "laser") || getSelectedElements(elements, appState).length)
19500
19888
  );
19501
19889
 
19890
+ // src/transform.ts
19891
+ init_define_import_meta_env();
19892
+ import { pointFrom as pointFrom19 } from "@excalidraw/math";
19893
+ import {
19894
+ DEFAULT_FONT_FAMILY as DEFAULT_FONT_FAMILY3,
19895
+ DEFAULT_FONT_SIZE as DEFAULT_FONT_SIZE4,
19896
+ TEXT_ALIGN as TEXT_ALIGN2,
19897
+ VERTICAL_ALIGN as VERTICAL_ALIGN4,
19898
+ getSizeFromPoints as getSizeFromPoints3,
19899
+ randomId as randomId4,
19900
+ arrayToMap as arrayToMap11,
19901
+ assertNever as assertNever5,
19902
+ cloneJSON,
19903
+ getFontString as getFontString8,
19904
+ isDevEnv as isDevEnv7,
19905
+ toBrandedType as toBrandedType3,
19906
+ getLineHeight as getLineHeight2
19907
+ } from "@excalidraw/common";
19908
+ var DEFAULT_LINEAR_ELEMENT_PROPS = {
19909
+ width: 100,
19910
+ height: 0
19911
+ };
19912
+ var DEFAULT_DIMENSION = 100;
19913
+ var bindTextToContainer = (container, textProps, scene) => {
19914
+ const textElement = newTextElement({
19915
+ x: 0,
19916
+ y: 0,
19917
+ textAlign: TEXT_ALIGN2.CENTER,
19918
+ verticalAlign: VERTICAL_ALIGN4.MIDDLE,
19919
+ ...textProps,
19920
+ containerId: container.id,
19921
+ strokeColor: textProps.strokeColor || container.strokeColor
19922
+ });
19923
+ Object.assign(container, {
19924
+ boundElements: (container.boundElements || []).concat({
19925
+ type: "text",
19926
+ id: textElement.id
19927
+ })
19928
+ });
19929
+ redrawTextBoundingBox(textElement, container, scene);
19930
+ return [container, textElement];
19931
+ };
19932
+ var bindLinearElementToElement = (linearElement, start, end, elementStore, scene) => {
19933
+ let startBoundElement;
19934
+ let endBoundElement;
19935
+ Object.assign(linearElement, {
19936
+ startBinding: linearElement?.startBinding || null,
19937
+ endBinding: linearElement.endBinding || null
19938
+ });
19939
+ if (start) {
19940
+ const width = start?.width ?? DEFAULT_DIMENSION;
19941
+ const height = start?.height ?? DEFAULT_DIMENSION;
19942
+ let existingElement;
19943
+ if (start.id) {
19944
+ existingElement = elementStore.getElement(start.id);
19945
+ if (!existingElement) {
19946
+ console.error(`No element for start binding with id ${start.id} found`);
19947
+ }
19948
+ }
19949
+ const startX = start.x || linearElement.x - width;
19950
+ const startY = start.y || linearElement.y - height / 2;
19951
+ const startType = existingElement ? existingElement.type : start.type;
19952
+ if (startType) {
19953
+ if (startType === "text") {
19954
+ let text = "";
19955
+ if (existingElement && existingElement.type === "text") {
19956
+ text = existingElement.text;
19957
+ } else if (start.type === "text") {
19958
+ text = start.text;
19959
+ }
19960
+ if (!text) {
19961
+ console.error(
19962
+ `No text found for start binding text element for ${linearElement.id}`
19963
+ );
19964
+ }
19965
+ startBoundElement = newTextElement({
19966
+ x: startX,
19967
+ y: startY,
19968
+ type: "text",
19969
+ ...existingElement,
19970
+ ...start,
19971
+ text
19972
+ });
19973
+ Object.assign(startBoundElement, {
19974
+ x: start.x || linearElement.x - startBoundElement.width,
19975
+ y: start.y || linearElement.y - startBoundElement.height / 2
19976
+ });
19977
+ } else {
19978
+ switch (startType) {
19979
+ case "rectangle":
19980
+ case "ellipse":
19981
+ case "diamond": {
19982
+ startBoundElement = newElement({
19983
+ x: startX,
19984
+ y: startY,
19985
+ width,
19986
+ height,
19987
+ ...existingElement,
19988
+ ...start,
19989
+ type: startType
19990
+ });
19991
+ break;
19992
+ }
19993
+ default: {
19994
+ assertNever5(
19995
+ linearElement,
19996
+ `Unhandled element start type "${start.type}"`,
19997
+ true
19998
+ );
19999
+ }
20000
+ }
20001
+ }
20002
+ bindBindingElement(
20003
+ linearElement,
20004
+ startBoundElement,
20005
+ "orbit",
20006
+ "start",
20007
+ scene
20008
+ );
20009
+ }
20010
+ }
20011
+ if (end) {
20012
+ const height = end?.height ?? DEFAULT_DIMENSION;
20013
+ const width = end?.width ?? DEFAULT_DIMENSION;
20014
+ let existingElement;
20015
+ if (end.id) {
20016
+ existingElement = elementStore.getElement(end.id);
20017
+ if (!existingElement) {
20018
+ console.error(`No element for end binding with id ${end.id} found`);
20019
+ }
20020
+ }
20021
+ const endX = end.x || linearElement.x + linearElement.width;
20022
+ const endY = end.y || linearElement.y - height / 2;
20023
+ const endType = existingElement ? existingElement.type : end.type;
20024
+ if (endType) {
20025
+ if (endType === "text") {
20026
+ let text = "";
20027
+ if (existingElement && existingElement.type === "text") {
20028
+ text = existingElement.text;
20029
+ } else if (end.type === "text") {
20030
+ text = end.text;
20031
+ }
20032
+ if (!text) {
20033
+ console.error(
20034
+ `No text found for end binding text element for ${linearElement.id}`
20035
+ );
20036
+ }
20037
+ endBoundElement = newTextElement({
20038
+ x: endX,
20039
+ y: endY,
20040
+ type: "text",
20041
+ ...existingElement,
20042
+ ...end,
20043
+ text
20044
+ });
20045
+ Object.assign(endBoundElement, {
20046
+ y: end.y || linearElement.y - endBoundElement.height / 2
20047
+ });
20048
+ } else {
20049
+ switch (endType) {
20050
+ case "rectangle":
20051
+ case "ellipse":
20052
+ case "diamond": {
20053
+ endBoundElement = newElement({
20054
+ x: endX,
20055
+ y: endY,
20056
+ width,
20057
+ height,
20058
+ ...existingElement,
20059
+ ...end,
20060
+ type: endType
20061
+ });
20062
+ break;
20063
+ }
20064
+ default: {
20065
+ assertNever5(
20066
+ linearElement,
20067
+ `Unhandled element end type "${endType}"`,
20068
+ true
20069
+ );
20070
+ }
20071
+ }
20072
+ }
20073
+ bindBindingElement(
20074
+ linearElement,
20075
+ endBoundElement,
20076
+ "orbit",
20077
+ "end",
20078
+ scene
20079
+ );
20080
+ }
20081
+ }
20082
+ if (linearElement.points.length < 2) {
20083
+ return {
20084
+ linearElement,
20085
+ startBoundElement,
20086
+ endBoundElement
20087
+ };
20088
+ }
20089
+ const endPointIndex = linearElement.points.length - 1;
20090
+ const delta = 0.5;
20091
+ const newPoints = cloneJSON(linearElement.points);
20092
+ if (linearElement.points[endPointIndex][0] > linearElement.points[endPointIndex - 1][0]) {
20093
+ newPoints[0][0] = delta;
20094
+ newPoints[endPointIndex][0] -= delta;
20095
+ }
20096
+ if (linearElement.points[endPointIndex][0] < linearElement.points[endPointIndex - 1][0]) {
20097
+ newPoints[0][0] = -delta;
20098
+ newPoints[endPointIndex][0] += delta;
20099
+ }
20100
+ if (linearElement.points[endPointIndex][1] > linearElement.points[endPointIndex - 1][1]) {
20101
+ newPoints[0][1] = delta;
20102
+ newPoints[endPointIndex][1] -= delta;
20103
+ }
20104
+ if (linearElement.points[endPointIndex][1] < linearElement.points[endPointIndex - 1][1]) {
20105
+ newPoints[0][1] = -delta;
20106
+ newPoints[endPointIndex][1] += delta;
20107
+ }
20108
+ Object.assign(
20109
+ linearElement,
20110
+ LinearElementEditor.getNormalizeElementPointsAndCoords({
20111
+ ...linearElement,
20112
+ points: newPoints
20113
+ })
20114
+ );
20115
+ return {
20116
+ linearElement,
20117
+ startBoundElement,
20118
+ endBoundElement
20119
+ };
20120
+ };
20121
+ var ElementStore = class {
20122
+ excalidrawElements = /* @__PURE__ */ new Map();
20123
+ add = (ele) => {
20124
+ if (!ele) {
20125
+ return;
20126
+ }
20127
+ this.excalidrawElements.set(ele.id, ele);
20128
+ };
20129
+ getElements = () => {
20130
+ return syncInvalidIndices(Array.from(this.excalidrawElements.values()));
20131
+ };
20132
+ getElementsMap = () => {
20133
+ return toBrandedType3(
20134
+ arrayToMap11(this.getElements())
20135
+ );
20136
+ };
20137
+ getElement = (id) => {
20138
+ return this.excalidrawElements.get(id);
20139
+ };
20140
+ };
20141
+ var convertToExcalidrawElements = (elementsSkeleton, opts) => {
20142
+ if (!elementsSkeleton) {
20143
+ return [];
20144
+ }
20145
+ const elements = cloneJSON(elementsSkeleton);
20146
+ const elementStore = new ElementStore();
20147
+ const elementsWithIds = /* @__PURE__ */ new Map();
20148
+ const oldToNewElementIdMap = /* @__PURE__ */ new Map();
20149
+ for (const element of elements) {
20150
+ let excalidrawElement;
20151
+ const originalId = element.id;
20152
+ if (opts?.regenerateIds !== false) {
20153
+ Object.assign(element, { id: randomId4() });
20154
+ }
20155
+ switch (element.type) {
20156
+ case "rectangle":
20157
+ case "ellipse":
20158
+ case "diamond": {
20159
+ const width = element?.label?.text && element.width === void 0 ? 0 : element?.width || DEFAULT_DIMENSION;
20160
+ const height = element?.label?.text && element.height === void 0 ? 0 : element?.height || DEFAULT_DIMENSION;
20161
+ excalidrawElement = newElement({
20162
+ ...element,
20163
+ width,
20164
+ height
20165
+ });
20166
+ break;
20167
+ }
20168
+ case "line": {
20169
+ const width = element.width || DEFAULT_LINEAR_ELEMENT_PROPS.width;
20170
+ const height = element.height || DEFAULT_LINEAR_ELEMENT_PROPS.height;
20171
+ excalidrawElement = newLinearElement({
20172
+ width,
20173
+ height,
20174
+ points: [pointFrom19(0, 0), pointFrom19(width, height)],
20175
+ ...element
20176
+ });
20177
+ break;
20178
+ }
20179
+ case "arrow": {
20180
+ const width = element.width || DEFAULT_LINEAR_ELEMENT_PROPS.width;
20181
+ const height = element.height || DEFAULT_LINEAR_ELEMENT_PROPS.height;
20182
+ excalidrawElement = newArrowElement({
20183
+ width,
20184
+ height,
20185
+ endArrowhead: "arrow",
20186
+ points: [pointFrom19(0, 0), pointFrom19(width, height)],
20187
+ ...element,
20188
+ type: "arrow"
20189
+ });
20190
+ Object.assign(
20191
+ excalidrawElement,
20192
+ getSizeFromPoints3(excalidrawElement.points)
20193
+ );
20194
+ break;
20195
+ }
20196
+ case "text": {
20197
+ const fontFamily = element?.fontFamily || DEFAULT_FONT_FAMILY3;
20198
+ const fontSize = element?.fontSize || DEFAULT_FONT_SIZE4;
20199
+ const lineHeight = element?.lineHeight || getLineHeight2(fontFamily);
20200
+ const text = element.text ?? "";
20201
+ const normalizedText = normalizeText(text);
20202
+ const metrics = measureText(
20203
+ normalizedText,
20204
+ getFontString8({ fontFamily, fontSize }),
20205
+ lineHeight
20206
+ );
20207
+ excalidrawElement = newTextElement({
20208
+ width: metrics.width,
20209
+ height: metrics.height,
20210
+ fontFamily,
20211
+ fontSize,
20212
+ ...element
20213
+ });
20214
+ break;
20215
+ }
20216
+ case "image": {
20217
+ excalidrawElement = newImageElement({
20218
+ width: element?.width || DEFAULT_DIMENSION,
20219
+ height: element?.height || DEFAULT_DIMENSION,
20220
+ ...element
20221
+ });
20222
+ break;
20223
+ }
20224
+ case "frame": {
20225
+ excalidrawElement = newFrameElement({
20226
+ x: 0,
20227
+ y: 0,
20228
+ ...element
20229
+ });
20230
+ break;
20231
+ }
20232
+ case "magicframe": {
20233
+ excalidrawElement = newMagicFrameElement({
20234
+ x: 0,
20235
+ y: 0,
20236
+ ...element
20237
+ });
20238
+ break;
20239
+ }
20240
+ case "freedraw":
20241
+ case "iframe":
20242
+ case "embeddable": {
20243
+ excalidrawElement = element;
20244
+ break;
20245
+ }
20246
+ default: {
20247
+ excalidrawElement = element;
20248
+ assertNever5(
20249
+ element,
20250
+ `Unhandled element type "${element.type}"`,
20251
+ true
20252
+ );
20253
+ }
20254
+ }
20255
+ const existingElement = elementStore.getElement(excalidrawElement.id);
20256
+ if (existingElement) {
20257
+ console.error(`Duplicate id found for ${excalidrawElement.id}`);
20258
+ } else {
20259
+ elementStore.add(excalidrawElement);
20260
+ elementsWithIds.set(excalidrawElement.id, element);
20261
+ if (originalId) {
20262
+ oldToNewElementIdMap.set(originalId, excalidrawElement.id);
20263
+ }
20264
+ }
20265
+ }
20266
+ const elementsMap = elementStore.getElementsMap();
20267
+ const scene = new Scene(elementsMap);
20268
+ for (const [id, element] of elementsWithIds) {
20269
+ const excalidrawElement = elementStore.getElement(id);
20270
+ switch (element.type) {
20271
+ case "rectangle":
20272
+ case "ellipse":
20273
+ case "diamond":
20274
+ case "arrow": {
20275
+ if (element.label?.text) {
20276
+ let [container, text] = bindTextToContainer(
20277
+ excalidrawElement,
20278
+ element?.label,
20279
+ scene
20280
+ );
20281
+ elementStore.add(container);
20282
+ elementStore.add(text);
20283
+ if (isArrowElement(container)) {
20284
+ const originalStart = element.type === "arrow" ? element?.start : void 0;
20285
+ const originalEnd = element.type === "arrow" ? element?.end : void 0;
20286
+ if (originalStart && originalStart.id) {
20287
+ const newStartId = oldToNewElementIdMap.get(originalStart.id);
20288
+ if (newStartId) {
20289
+ Object.assign(originalStart, { id: newStartId });
20290
+ }
20291
+ }
20292
+ if (originalEnd && originalEnd.id) {
20293
+ const newEndId = oldToNewElementIdMap.get(originalEnd.id);
20294
+ if (newEndId) {
20295
+ Object.assign(originalEnd, { id: newEndId });
20296
+ }
20297
+ }
20298
+ const { linearElement, startBoundElement, endBoundElement } = bindLinearElementToElement(
20299
+ container,
20300
+ originalStart,
20301
+ originalEnd,
20302
+ elementStore,
20303
+ scene
20304
+ );
20305
+ container = linearElement;
20306
+ elementStore.add(linearElement);
20307
+ elementStore.add(startBoundElement);
20308
+ elementStore.add(endBoundElement);
20309
+ }
20310
+ } else {
20311
+ switch (element.type) {
20312
+ case "arrow": {
20313
+ const { start, end } = element;
20314
+ if (start && start.id) {
20315
+ const newStartId = oldToNewElementIdMap.get(start.id);
20316
+ Object.assign(start, { id: newStartId });
20317
+ }
20318
+ if (end && end.id) {
20319
+ const newEndId = oldToNewElementIdMap.get(end.id);
20320
+ Object.assign(end, { id: newEndId });
20321
+ }
20322
+ const { linearElement, startBoundElement, endBoundElement } = bindLinearElementToElement(
20323
+ excalidrawElement,
20324
+ start,
20325
+ end,
20326
+ elementStore,
20327
+ scene
20328
+ );
20329
+ elementStore.add(linearElement);
20330
+ elementStore.add(startBoundElement);
20331
+ elementStore.add(endBoundElement);
20332
+ break;
20333
+ }
20334
+ }
20335
+ }
20336
+ break;
20337
+ }
20338
+ }
20339
+ }
20340
+ for (const [id, element] of elementsWithIds) {
20341
+ if (element.type !== "frame" && element.type !== "magicframe") {
20342
+ continue;
20343
+ }
20344
+ const frame = elementStore.getElement(id);
20345
+ if (!frame) {
20346
+ throw new Error(`Excalidraw element with id ${id} doesn't exist`);
20347
+ }
20348
+ const childrenElements = [];
20349
+ element.children.forEach((id2) => {
20350
+ const newElementId = oldToNewElementIdMap.get(id2);
20351
+ if (!newElementId) {
20352
+ throw new Error(`Element with ${id2} wasn't mapped correctly`);
20353
+ }
20354
+ const elementInFrame = elementStore.getElement(newElementId);
20355
+ if (!elementInFrame) {
20356
+ throw new Error(`Frame element with id ${newElementId} doesn't exist`);
20357
+ }
20358
+ Object.assign(elementInFrame, { frameId: frame.id });
20359
+ elementInFrame?.boundElements?.forEach((boundElement) => {
20360
+ const ele = elementStore.getElement(boundElement.id);
20361
+ if (!ele) {
20362
+ throw new Error(
20363
+ `Bound element with id ${boundElement.id} doesn't exist`
20364
+ );
20365
+ }
20366
+ Object.assign(ele, { frameId: frame.id });
20367
+ childrenElements.push(ele);
20368
+ });
20369
+ childrenElements.push(elementInFrame);
20370
+ });
20371
+ let [minX, minY, maxX, maxY] = getCommonBounds(childrenElements);
20372
+ const PADDING = 10;
20373
+ minX = minX - PADDING;
20374
+ minY = minY - PADDING;
20375
+ maxX = maxX + PADDING;
20376
+ maxY = maxY + PADDING;
20377
+ const frameX = frame?.x || minX;
20378
+ const frameY = frame?.y || minY;
20379
+ const frameWidth = frame?.width || maxX - minX;
20380
+ const frameHeight = frame?.height || maxY - minY;
20381
+ Object.assign(frame, {
20382
+ x: frameX,
20383
+ y: frameY,
20384
+ width: frameWidth,
20385
+ height: frameHeight
20386
+ });
20387
+ if (isDevEnv7() && element.children.length && (frame?.x || frame?.y || frame?.width || frame?.height)) {
20388
+ console.info(
20389
+ "User provided frame attributes are being considered, if you find this inaccurate, please remove any of the attributes - x, y, width and height so frame coordinates and dimensions are calculated automatically"
20390
+ );
20391
+ }
20392
+ }
20393
+ return elementStore.getElements();
20394
+ };
20395
+
19502
20396
  // src/zindex.ts
19503
20397
  init_define_import_meta_env();
19504
- import { arrayToMap as arrayToMap11, findIndex, findLastIndex as findLastIndex2 } from "@excalidraw/common";
20398
+ import { arrayToMap as arrayToMap12, findIndex, findLastIndex as findLastIndex2 } from "@excalidraw/common";
19505
20399
  var isOfTargetFrame = (element, frameId) => {
19506
20400
  return element.frameId === frameId || element.id === frameId;
19507
20401
  };
@@ -19510,7 +20404,7 @@ var getIndicesToMove = (elements, appState, elementsToBeMoved) => {
19510
20404
  let deletedIndices = [];
19511
20405
  let includeDeletedIndex = null;
19512
20406
  let index = -1;
19513
- const selectedElementIds = arrayToMap11(
20407
+ const selectedElementIds = arrayToMap12(
19514
20408
  elementsToBeMoved ? elementsToBeMoved : getSelectedElements(elements, appState, {
19515
20409
  includeBoundTextElement: true,
19516
20410
  includeElementsInFrames: true
@@ -19804,7 +20698,7 @@ var shiftElementsToEnd = (elements, appState, direction, containingFrame, elemen
19804
20698
  return nextElements;
19805
20699
  };
19806
20700
  function shiftElementsAccountingForFrames(allElements, appState, direction, shiftFunction) {
19807
- const elementsToMove = arrayToMap11(
20701
+ const elementsToMove = arrayToMap12(
19808
20702
  getSelectedElements(allElements, appState, {
19809
20703
  includeBoundTextElement: true,
19810
20704
  includeElementsInFrames: true
@@ -19922,7 +20816,6 @@ export {
19922
20816
  HEADING_LEFT,
19923
20817
  HEADING_RIGHT,
19924
20818
  HEADING_UP,
19925
- IMAGE_INVERT_FILTER,
19926
20819
  INVISIBLY_SMALL_ELEMENT_SIZE,
19927
20820
  InvalidFractionalIndexError,
19928
20821
  LinearElementEditor,
@@ -19962,6 +20855,7 @@ export {
19962
20855
  computeBoundTextPosition,
19963
20856
  computeContainerDimensionForBoundText,
19964
20857
  containsCJK,
20858
+ convertToExcalidrawElements,
19965
20859
  createPlaceholderEmbeddableLabel,
19966
20860
  createSrcDoc,
19967
20861
  cropElement,
@@ -19991,7 +20885,6 @@ export {
19991
20885
  fixDuplicatedBindingsAfterDuplication,
19992
20886
  flipHeading,
19993
20887
  frameAndChildrenSelectedTogether,
19994
- generateFreeDrawShape,
19995
20888
  generateLinearCollisionShape,
19996
20889
  generateRoughOptions,
19997
20890
  getAllHoveredElementAtPoint,
@@ -20002,6 +20895,7 @@ export {
20002
20895
  getArrowheadPoints,
20003
20896
  getArrowheadSize,
20004
20897
  getBindingGap,
20898
+ getBindingSideMidPoint,
20005
20899
  getBindingStrategyForDraggingBindingElementEndpoints,
20006
20900
  getBoundTextElement,
20007
20901
  getBoundTextElementId,
@@ -20043,8 +20937,6 @@ export {
20043
20937
  getFrameChildren,
20044
20938
  getFrameLikeElements,
20045
20939
  getFrameLikeTitle,
20046
- getFreeDrawPath2D,
20047
- getFreeDrawSvgPath,
20048
20940
  getFreedrawOutlineAsSegments,
20049
20941
  getFreedrawOutlinePoints,
20050
20942
  getGlobalFixedPointForBindableElement,
@@ -20129,7 +21021,6 @@ export {
20129
21021
  isBindingElementType,
20130
21022
  isBindingEnabled,
20131
21023
  isBoundToContainer,
20132
- isBounds,
20133
21024
  isCursorInFrame,
20134
21025
  isCurvedArrow,
20135
21026
  isElbowArrow,
@@ -20208,7 +21099,6 @@ export {
20208
21099
  originalContainerCache,
20209
21100
  parseElementLinkFromURL,
20210
21101
  parseTokens,
20211
- pathsCache,
20212
21102
  pointInsideBounds,
20213
21103
  positionElementsOnGrid,
20214
21104
  projectFixedPointOntoDiagonal,