@excalidraw/excalidraw 0.17.1-7500-ac247a0 → 0.17.1-a38e82f

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 (251) hide show
  1. package/CHANGELOG.md +52 -2
  2. package/dist/browser/dev/excalidraw-assets-dev/chunk-5VWQDKDR.js +20279 -0
  3. package/dist/browser/dev/excalidraw-assets-dev/chunk-5VWQDKDR.js.map +7 -0
  4. package/dist/browser/dev/excalidraw-assets-dev/{chunk-2W5GQUR4.js → chunk-IM4WTX2M.js} +12 -6
  5. package/dist/browser/dev/excalidraw-assets-dev/chunk-IM4WTX2M.js.map +7 -0
  6. package/dist/browser/dev/excalidraw-assets-dev/{en-OC6JWP3X.js → en-IOBA4CS2.js} +4 -2
  7. package/dist/browser/dev/excalidraw-assets-dev/image-LK4UNFRZ.css +6 -0
  8. package/dist/browser/dev/excalidraw-assets-dev/image-LK4UNFRZ.css.map +7 -0
  9. package/dist/browser/dev/excalidraw-assets-dev/{image-5TVMINCA.js → image-VKDAL6BQ.js} +2 -4
  10. package/dist/browser/dev/excalidraw-assets-dev/roundRect-T5BX56ZF.js +161 -0
  11. package/dist/browser/dev/excalidraw-assets-dev/roundRect-T5BX56ZF.js.map +7 -0
  12. package/dist/browser/dev/index.css +189 -129
  13. package/dist/browser/dev/index.css.map +3 -3
  14. package/dist/browser/dev/index.js +34708 -37
  15. package/dist/browser/dev/index.js.map +4 -4
  16. package/dist/browser/prod/excalidraw-assets/chunk-LIG3S5TN.js +11 -0
  17. package/dist/browser/prod/excalidraw-assets/chunk-N2C5DK3B.js +55 -0
  18. package/dist/browser/prod/excalidraw-assets/en-WFZVQ7I6.js +1 -0
  19. package/dist/browser/prod/excalidraw-assets/image-4AT7LYMR.js +1 -0
  20. package/dist/browser/prod/excalidraw-assets/image-X66R2EM5.css +1 -0
  21. package/dist/browser/prod/excalidraw-assets/roundRect-2ACQK4DA.js +1 -0
  22. package/dist/browser/prod/index.css +1 -1
  23. package/dist/browser/prod/index.js +203 -1
  24. package/dist/{prod/en-RLIAOBCI.json → dev/en-TDNWCAOT.json} +9 -5
  25. package/dist/dev/index.css +189 -129
  26. package/dist/dev/index.css.map +3 -3
  27. package/dist/dev/index.js +39078 -40080
  28. package/dist/dev/index.js.map +4 -4
  29. package/dist/excalidraw/actions/actionAddToLibrary.d.ts +15 -15
  30. package/dist/excalidraw/actions/actionAlign.d.ts +6 -6
  31. package/dist/excalidraw/actions/actionAlign.js +2 -1
  32. package/dist/excalidraw/actions/actionBoundText.d.ts +10 -10
  33. package/dist/excalidraw/actions/actionBoundText.js +8 -8
  34. package/dist/excalidraw/actions/actionCanvas.d.ts +58 -58
  35. package/dist/excalidraw/actions/actionClipboard.d.ts +34 -34
  36. package/dist/excalidraw/actions/actionClipboard.js +9 -2
  37. package/dist/excalidraw/actions/actionDeleteSelected.d.ts +15 -15
  38. package/dist/excalidraw/actions/actionDeleteSelected.js +3 -2
  39. package/dist/excalidraw/actions/actionDistribute.d.ts +2 -2
  40. package/dist/excalidraw/actions/actionDistribute.js +1 -1
  41. package/dist/excalidraw/actions/actionDuplicateSelection.d.ts +1 -1
  42. package/dist/excalidraw/actions/actionDuplicateSelection.js +4 -3
  43. package/dist/excalidraw/actions/actionElementLock.d.ts +10 -10
  44. package/dist/excalidraw/actions/actionExport.d.ts +43 -43
  45. package/dist/excalidraw/actions/actionExport.js +4 -4
  46. package/dist/excalidraw/actions/actionFinalize.d.ts +9 -9
  47. package/dist/excalidraw/actions/actionFinalize.js +7 -6
  48. package/dist/excalidraw/actions/actionFlip.d.ts +2 -2
  49. package/dist/excalidraw/actions/actionFlip.js +11 -11
  50. package/dist/excalidraw/actions/actionFrame.d.ts +16 -16
  51. package/dist/excalidraw/actions/actionFrame.js +1 -1
  52. package/dist/excalidraw/actions/actionGroup.d.ts +10 -10
  53. package/dist/excalidraw/actions/actionGroup.js +3 -2
  54. package/dist/excalidraw/actions/actionLinearEditor.d.ts +5 -5
  55. package/dist/excalidraw/actions/actionLinearEditor.js +1 -1
  56. package/dist/excalidraw/{element/Hyperlink.d.ts → actions/actionLink.d.ts} +29 -51
  57. package/dist/excalidraw/actions/actionLink.js +40 -0
  58. package/dist/excalidraw/actions/actionMenu.d.ts +13 -13
  59. package/dist/excalidraw/actions/actionNavigate.d.ts +10 -10
  60. package/dist/excalidraw/actions/actionNavigate.js +1 -1
  61. package/dist/excalidraw/actions/actionProperties.d.ts +77 -77
  62. package/dist/excalidraw/actions/actionProperties.js +32 -27
  63. package/dist/excalidraw/actions/actionSelectAll.d.ts +5 -5
  64. package/dist/excalidraw/actions/actionSelectAll.js +1 -1
  65. package/dist/excalidraw/actions/actionStyles.d.ts +7 -7
  66. package/dist/excalidraw/actions/actionStyles.js +4 -4
  67. package/dist/excalidraw/actions/actionToggleGridMode.d.ts +5 -5
  68. package/dist/excalidraw/actions/actionToggleObjectsSnapMode.d.ts +5 -5
  69. package/dist/excalidraw/actions/actionToggleStats.d.ts +5 -5
  70. package/dist/excalidraw/actions/actionToggleViewMode.d.ts +5 -5
  71. package/dist/excalidraw/actions/actionToggleZenMode.d.ts +5 -5
  72. package/dist/excalidraw/actions/index.d.ts +1 -1
  73. package/dist/excalidraw/actions/index.js +1 -1
  74. package/dist/excalidraw/actions/manager.js +2 -1
  75. package/dist/excalidraw/align.d.ts +2 -2
  76. package/dist/excalidraw/align.js +2 -2
  77. package/dist/excalidraw/animated-trail.d.ts +33 -0
  78. package/dist/excalidraw/animated-trail.js +96 -0
  79. package/dist/excalidraw/animation-frame-handler.d.ts +16 -0
  80. package/dist/excalidraw/animation-frame-handler.js +55 -0
  81. package/dist/excalidraw/appState.d.ts +1 -1
  82. package/dist/excalidraw/appState.js +1 -3
  83. package/dist/excalidraw/clipboard.js +5 -5
  84. package/dist/excalidraw/components/Actions.d.ts +3 -3
  85. package/dist/excalidraw/components/Actions.js +18 -7
  86. package/dist/excalidraw/components/App.d.ts +23 -16
  87. package/dist/excalidraw/components/App.js +387 -272
  88. package/dist/excalidraw/components/Button.d.ts +1 -1
  89. package/dist/excalidraw/components/FilledButton.d.ts +2 -2
  90. package/dist/excalidraw/components/FilledButton.js +27 -3
  91. package/dist/excalidraw/components/FollowMode/FollowMode.js +1 -1
  92. package/dist/excalidraw/components/ImageExportDialog.d.ts +2 -1
  93. package/dist/excalidraw/components/ImageExportDialog.js +17 -13
  94. package/dist/excalidraw/components/JSONExportDialog.js +1 -1
  95. package/dist/excalidraw/components/{LaserTool/LaserPointerButton.d.ts → LaserPointerButton.d.ts} +1 -1
  96. package/dist/excalidraw/components/{LaserTool/LaserPointerButton.js → LaserPointerButton.js} +2 -2
  97. package/dist/excalidraw/components/LayerUI.js +3 -3
  98. package/dist/excalidraw/components/MobileMenu.js +1 -1
  99. package/dist/excalidraw/components/ProjectName.d.ts +0 -1
  100. package/dist/excalidraw/components/ProjectName.js +1 -1
  101. package/dist/excalidraw/components/PublishLibrary.js +1 -1
  102. package/dist/excalidraw/components/SVGLayer.d.ts +8 -0
  103. package/dist/excalidraw/components/SVGLayer.js +20 -0
  104. package/dist/excalidraw/components/ShareableLinkDialog.js +10 -10
  105. package/dist/excalidraw/components/Sidebar/Sidebar.d.ts +1 -1
  106. package/dist/excalidraw/components/Stack.d.ts +2 -2
  107. package/dist/excalidraw/components/TTDDialog/common.js +10 -1
  108. package/dist/excalidraw/components/TextField.d.ts +5 -2
  109. package/dist/excalidraw/components/TextField.js +6 -3
  110. package/dist/excalidraw/components/Toast.d.ts +3 -2
  111. package/dist/excalidraw/components/Toast.js +2 -2
  112. package/dist/excalidraw/components/ToolButton.js +2 -1
  113. package/dist/excalidraw/components/canvases/InteractiveCanvas.d.ts +2 -2
  114. package/dist/excalidraw/components/canvases/InteractiveCanvas.js +6 -5
  115. package/dist/excalidraw/components/canvases/StaticCanvas.d.ts +4 -3
  116. package/dist/excalidraw/components/canvases/StaticCanvas.js +7 -5
  117. package/dist/excalidraw/components/dropdownMenu/DropdownMenuContent.js +22 -2
  118. package/dist/excalidraw/components/hyperlink/Hyperlink.d.ts +19 -0
  119. package/dist/excalidraw/{element → components/hyperlink}/Hyperlink.js +40 -115
  120. package/dist/excalidraw/components/hyperlink/helpers.d.ts +7 -0
  121. package/dist/excalidraw/components/hyperlink/helpers.js +49 -0
  122. package/dist/excalidraw/components/icons.d.ts +2 -1
  123. package/dist/excalidraw/components/icons.js +2 -1
  124. package/dist/excalidraw/components/live-collaboration/LiveCollaborationTrigger.js +3 -2
  125. package/dist/excalidraw/components/main-menu/DefaultItems.js +5 -2
  126. package/dist/excalidraw/constants.d.ts +6 -0
  127. package/dist/excalidraw/constants.js +6 -0
  128. package/dist/excalidraw/data/blob.js +13 -14
  129. package/dist/excalidraw/data/filesystem.d.ts +1 -1
  130. package/dist/excalidraw/data/index.d.ts +2 -1
  131. package/dist/excalidraw/data/index.js +20 -16
  132. package/dist/excalidraw/data/json.d.ts +1 -1
  133. package/dist/excalidraw/data/json.js +5 -3
  134. package/dist/excalidraw/data/resave.d.ts +1 -1
  135. package/dist/excalidraw/data/resave.js +2 -2
  136. package/dist/excalidraw/data/restore.js +8 -13
  137. package/dist/excalidraw/data/transform.js +13 -9
  138. package/dist/excalidraw/distribute.d.ts +2 -2
  139. package/dist/excalidraw/distribute.js +2 -2
  140. package/dist/excalidraw/element/ElementCanvasButtons.d.ts +3 -2
  141. package/dist/excalidraw/element/ElementCanvasButtons.js +4 -4
  142. package/dist/excalidraw/element/binding.d.ts +9 -9
  143. package/dist/excalidraw/element/binding.js +61 -59
  144. package/dist/excalidraw/element/bounds.d.ts +5 -5
  145. package/dist/excalidraw/element/bounds.js +29 -32
  146. package/dist/excalidraw/element/collision.d.ts +11 -11
  147. package/dist/excalidraw/element/collision.js +49 -46
  148. package/dist/excalidraw/element/containerCache.d.ts +11 -0
  149. package/dist/excalidraw/element/containerCache.js +14 -0
  150. package/dist/excalidraw/element/dragElements.js +10 -19
  151. package/dist/excalidraw/element/embeddable.d.ts +12 -13
  152. package/dist/excalidraw/element/embeddable.js +17 -27
  153. package/dist/excalidraw/element/image.js +1 -2
  154. package/dist/excalidraw/element/index.d.ts +0 -1
  155. package/dist/excalidraw/element/index.js +0 -1
  156. package/dist/excalidraw/element/linearElementEditor.d.ts +36 -36
  157. package/dist/excalidraw/element/linearElementEditor.js +79 -80
  158. package/dist/excalidraw/element/newElement.d.ts +4 -6
  159. package/dist/excalidraw/element/newElement.js +11 -16
  160. package/dist/excalidraw/element/resizeElements.d.ts +6 -6
  161. package/dist/excalidraw/element/resizeElements.js +40 -46
  162. package/dist/excalidraw/element/resizeTest.d.ts +3 -3
  163. package/dist/excalidraw/element/resizeTest.js +4 -4
  164. package/dist/excalidraw/element/sizeHelpers.d.ts +2 -2
  165. package/dist/excalidraw/element/sizeHelpers.js +2 -2
  166. package/dist/excalidraw/element/textElement.d.ts +18 -20
  167. package/dist/excalidraw/element/textElement.js +80 -111
  168. package/dist/excalidraw/element/textWysiwyg.d.ts +1 -6
  169. package/dist/excalidraw/element/textWysiwyg.js +15 -37
  170. package/dist/excalidraw/element/transformHandles.d.ts +4 -4
  171. package/dist/excalidraw/element/transformHandles.js +6 -6
  172. package/dist/excalidraw/element/typeChecks.js +4 -1
  173. package/dist/excalidraw/element/types.d.ts +24 -11
  174. package/dist/excalidraw/frame.d.ts +26 -20
  175. package/dist/excalidraw/frame.js +157 -84
  176. package/dist/excalidraw/groups.d.ts +3 -3
  177. package/dist/excalidraw/groups.js +11 -3
  178. package/dist/excalidraw/history.d.ts +1 -1
  179. package/dist/excalidraw/hooks/useLibraryItemSvg.js +1 -1
  180. package/dist/excalidraw/index.d.ts +8 -9
  181. package/dist/excalidraw/index.js +15 -11
  182. package/dist/excalidraw/laser-trails.d.ts +19 -0
  183. package/dist/excalidraw/laser-trails.js +95 -0
  184. package/dist/excalidraw/locales/en.json +9 -5
  185. package/dist/excalidraw/reactUtils.d.ts +14 -0
  186. package/dist/excalidraw/reactUtils.js +45 -0
  187. package/dist/excalidraw/renderer/helpers.d.ts +13 -0
  188. package/dist/excalidraw/renderer/helpers.js +39 -0
  189. package/dist/excalidraw/renderer/interactiveScene.d.ts +20 -0
  190. package/dist/excalidraw/renderer/{renderScene.js → interactiveScene.js} +199 -474
  191. package/dist/excalidraw/renderer/renderElement.d.ts +6 -6
  192. package/dist/excalidraw/renderer/renderElement.js +54 -366
  193. package/dist/excalidraw/renderer/staticScene.d.ts +11 -0
  194. package/dist/excalidraw/renderer/staticScene.js +205 -0
  195. package/dist/excalidraw/renderer/staticSvgScene.d.ts +5 -0
  196. package/dist/excalidraw/renderer/staticSvgScene.js +385 -0
  197. package/dist/excalidraw/scene/Fonts.js +2 -1
  198. package/dist/excalidraw/scene/Renderer.d.ts +1 -1
  199. package/dist/excalidraw/scene/Renderer.js +32 -20
  200. package/dist/excalidraw/scene/Scene.d.ts +10 -9
  201. package/dist/excalidraw/scene/Scene.js +45 -21
  202. package/dist/excalidraw/scene/Shape.d.ts +3 -1
  203. package/dist/excalidraw/scene/Shape.js +7 -5
  204. package/dist/excalidraw/scene/ShapeCache.d.ts +2 -1
  205. package/dist/excalidraw/scene/ShapeCache.js +1 -0
  206. package/dist/excalidraw/scene/comparisons.js +2 -1
  207. package/dist/excalidraw/scene/export.d.ts +3 -0
  208. package/dist/excalidraw/scene/export.js +20 -40
  209. package/dist/excalidraw/scene/index.d.ts +0 -1
  210. package/dist/excalidraw/scene/index.js +0 -1
  211. package/dist/excalidraw/scene/scrollbars.d.ts +1 -1
  212. package/dist/excalidraw/scene/scrollbars.js +1 -1
  213. package/dist/excalidraw/scene/selection.d.ts +5 -5
  214. package/dist/excalidraw/scene/selection.js +16 -14
  215. package/dist/excalidraw/scene/types.d.ts +11 -5
  216. package/dist/excalidraw/snapping.d.ts +7 -7
  217. package/dist/excalidraw/snapping.js +21 -20
  218. package/dist/excalidraw/types.d.ts +10 -11
  219. package/dist/excalidraw/utility-types.d.ts +5 -0
  220. package/dist/excalidraw/utils.d.ts +18 -15
  221. package/dist/excalidraw/utils.js +37 -45
  222. package/dist/{dev/en-RLIAOBCI.json → prod/en-TDNWCAOT.json} +9 -5
  223. package/dist/prod/index.css +1 -1
  224. package/dist/prod/index.js +42 -42
  225. package/dist/utils/bbox.d.ts +2 -2
  226. package/dist/utils/export.d.ts +3 -3
  227. package/dist/utils/export.js +3 -13
  228. package/dist/utils/index.d.ts +2 -2
  229. package/dist/utils/index.js +2 -2
  230. package/dist/utils/withinBounds.d.ts +1 -1
  231. package/dist/utils/withinBounds.js +5 -2
  232. package/package.json +4 -4
  233. package/dist/browser/dev/excalidraw-assets-dev/chunk-2W5GQUR4.js.map +0 -7
  234. package/dist/browser/dev/excalidraw-assets-dev/chunk-KGZXLFLR.js +0 -53497
  235. package/dist/browser/dev/excalidraw-assets-dev/chunk-KGZXLFLR.js.map +0 -7
  236. package/dist/browser/dev/excalidraw-assets-dev/image-3MFRCKYM.css +0 -5797
  237. package/dist/browser/dev/excalidraw-assets-dev/image-3MFRCKYM.css.map +0 -7
  238. package/dist/browser/prod/excalidraw-assets/chunk-4YN2HN3S.js +0 -257
  239. package/dist/browser/prod/excalidraw-assets/chunk-OWLL6VOG.js +0 -11
  240. package/dist/browser/prod/excalidraw-assets/en-ERQOR3OC.js +0 -1
  241. package/dist/browser/prod/excalidraw-assets/image-LTLHTTSE.js +0 -1
  242. package/dist/browser/prod/excalidraw-assets/image-QBL334OA.css +0 -1
  243. package/dist/excalidraw/components/LaserTool/LaserPathManager.d.ts +0 -28
  244. package/dist/excalidraw/components/LaserTool/LaserPathManager.js +0 -225
  245. package/dist/excalidraw/components/LaserTool/LaserTool.d.ts +0 -8
  246. package/dist/excalidraw/components/LaserTool/LaserTool.js +0 -15
  247. package/dist/excalidraw/renderer/renderScene.d.ts +0 -25
  248. package/dist/excalidraw/vite.config.d.mts +0 -2
  249. package/dist/excalidraw/vite.config.mjs +0 -13
  250. /package/dist/browser/dev/excalidraw-assets-dev/{en-OC6JWP3X.js.map → en-IOBA4CS2.js.map} +0 -0
  251. /package/dist/browser/dev/excalidraw-assets-dev/{image-5TVMINCA.js.map → image-VKDAL6BQ.js.map} +0 -0
@@ -1,7 +1,9 @@
1
1
  import type { RoughCanvas } from "roughjs/bin/canvas";
2
2
  import { Drawable } from "roughjs/bin/core";
3
- import { ExcalidrawTextElement, NonDeletedExcalidrawElement } from "../element/types";
4
- import { AppClassProperties, AppState, InteractiveCanvasAppState, StaticCanvasAppState } from "../types";
3
+ import { ExcalidrawTextElement, NonDeletedElementsMap, NonDeletedExcalidrawElement, NonDeletedSceneElementsMap } from "../element/types";
4
+ import { AppClassProperties, AppState, EmbedsValidationStatus, ElementsPendingErasure, InteractiveCanvasAppState, StaticCanvasAppState } from "../types";
5
+ import { MakeBrand } from "../utility-types";
6
+ export type RenderableElementsMap = NonDeletedElementsMap & MakeBrand<"RenderableElementsMap">;
5
7
  export type StaticCanvasRenderConfig = {
6
8
  canvasBackgroundColor: AppState["viewBackgroundColor"];
7
9
  imageCache: AppClassProperties["imageCache"];
@@ -9,6 +11,8 @@ export type StaticCanvasRenderConfig = {
9
11
  /** when exporting the behavior is slightly different (e.g. we can't use
10
12
  CSS filters), and we disable render optimizations for best output */
11
13
  isExporting: boolean;
14
+ embedsValidationStatus: EmbedsValidationStatus;
15
+ elementsPendingErasure: ElementsPendingErasure;
12
16
  };
13
17
  export type SVGRenderConfig = {
14
18
  offsetX: number;
@@ -18,6 +22,7 @@ export type SVGRenderConfig = {
18
22
  renderEmbeddables: boolean;
19
23
  frameRendering: AppState["frameRendering"];
20
24
  canvasBackgroundColor: AppState["viewBackgroundColor"];
25
+ embedsValidationStatus: EmbedsValidationStatus;
21
26
  };
22
27
  export type InteractiveCanvasRenderConfig = {
23
28
  remoteSelectedElementIds: {
@@ -43,13 +48,14 @@ export type InteractiveCanvasRenderConfig = {
43
48
  };
44
49
  export type RenderInteractiveSceneCallback = {
45
50
  atLeastOneVisibleElement: boolean;
46
- elements: readonly NonDeletedExcalidrawElement[];
51
+ elementsMap: RenderableElementsMap;
47
52
  scrollBars?: ScrollBars;
48
53
  };
49
54
  export type StaticSceneRenderConfig = {
50
55
  canvas: HTMLCanvasElement;
51
56
  rc: RoughCanvas;
52
- elements: readonly NonDeletedExcalidrawElement[];
57
+ elementsMap: RenderableElementsMap;
58
+ allElementsMap: NonDeletedSceneElementsMap;
53
59
  visibleElements: readonly NonDeletedExcalidrawElement[];
54
60
  scale: number;
55
61
  appState: StaticCanvasAppState;
@@ -57,7 +63,7 @@ export type StaticSceneRenderConfig = {
57
63
  };
58
64
  export type InteractiveSceneRenderConfig = {
59
65
  canvas: HTMLCanvasElement | null;
60
- elements: readonly NonDeletedExcalidrawElement[];
66
+ elementsMap: RenderableElementsMap;
61
67
  visibleElements: readonly NonDeletedExcalidrawElement[];
62
68
  selectedElements: readonly NonDeletedExcalidrawElement[];
63
69
  scale: number;
@@ -1,6 +1,6 @@
1
1
  import { Bounds } from "./element/bounds";
2
2
  import { MaybeTransformHandleType } from "./element/transformHandles";
3
- import { ExcalidrawElement, NonDeletedExcalidrawElement } from "./element/types";
3
+ import { ElementsMap, ExcalidrawElement, NonDeletedExcalidrawElement } from "./element/types";
4
4
  import { AppState, KeyboardModifiersObject, Point } from "./types";
5
5
  export declare const getSnapDistance: (zoomValue: number) => number;
6
6
  type Vector2D = {
@@ -66,17 +66,17 @@ export declare const isSnappingEnabled: ({ event, appState, selectedElements, }:
66
66
  selectedElements: NonDeletedExcalidrawElement[];
67
67
  }) => boolean;
68
68
  export declare const areRoughlyEqual: (a: number, b: number, precision?: number) => boolean;
69
- export declare const getElementsCorners: (elements: ExcalidrawElement[], { omitCenter, boundingBoxCorners, dragOffset, }?: {
69
+ export declare const getElementsCorners: (elements: ExcalidrawElement[], elementsMap: ElementsMap, { omitCenter, boundingBoxCorners, dragOffset, }?: {
70
70
  omitCenter?: boolean | undefined;
71
71
  boundingBoxCorners?: boolean | undefined;
72
72
  dragOffset?: Vector2D | undefined;
73
73
  }) => Point[];
74
- export declare const getVisibleGaps: (elements: readonly NonDeletedExcalidrawElement[], selectedElements: ExcalidrawElement[], appState: AppState) => {
74
+ export declare const getVisibleGaps: (elements: readonly NonDeletedExcalidrawElement[], selectedElements: ExcalidrawElement[], appState: AppState, elementsMap: ElementsMap) => {
75
75
  horizontalGaps: Gap[];
76
76
  verticalGaps: Gap[];
77
77
  };
78
- export declare const getReferenceSnapPoints: (elements: readonly NonDeletedExcalidrawElement[], selectedElements: ExcalidrawElement[], appState: AppState) => (readonly [number, number])[];
79
- export declare const snapDraggedElements: (selectedElements: ExcalidrawElement[], dragOffset: Vector2D, appState: AppState, event: KeyboardModifiersObject) => {
78
+ export declare const getReferenceSnapPoints: (elements: readonly NonDeletedExcalidrawElement[], selectedElements: ExcalidrawElement[], appState: AppState, elementsMap: ElementsMap) => (readonly [number, number])[];
79
+ export declare const snapDraggedElements: (elements: ExcalidrawElement[], dragOffset: Vector2D, appState: AppState, event: KeyboardModifiersObject, elementsMap: ElementsMap) => {
80
80
  snapOffset: {
81
81
  x: number;
82
82
  y: number;
@@ -90,14 +90,14 @@ export declare const snapResizingElements: (selectedElements: ExcalidrawElement[
90
90
  };
91
91
  snapLines: PointSnapLine[];
92
92
  };
93
- export declare const snapNewElement: (draggingElement: ExcalidrawElement, appState: AppState, event: KeyboardModifiersObject, origin: Vector2D, dragOffset: Vector2D) => {
93
+ export declare const snapNewElement: (draggingElement: ExcalidrawElement, appState: AppState, event: KeyboardModifiersObject, origin: Vector2D, dragOffset: Vector2D, elementsMap: ElementsMap) => {
94
94
  snapOffset: {
95
95
  x: number;
96
96
  y: number;
97
97
  };
98
98
  snapLines: PointSnapLine[];
99
99
  };
100
- export declare const getSnapLinesAtPointer: (elements: readonly ExcalidrawElement[], appState: AppState, pointer: Vector2D, event: KeyboardModifiersObject) => {
100
+ export declare const getSnapLinesAtPointer: (elements: readonly ExcalidrawElement[], appState: AppState, pointer: Vector2D, event: KeyboardModifiersObject, elementsMap: ElementsMap) => {
101
101
  originOffset: {
102
102
  x: number;
103
103
  y: number;
@@ -4,7 +4,7 @@ import { isBoundToContainer, isFrameLikeElement } from "./element/typeChecks";
4
4
  import { getMaximumGroups } from "./groups";
5
5
  import { KEYS } from "./keys";
6
6
  import { rangeIntersection, rangesOverlap, rotatePoint } from "./math";
7
- import { getVisibleAndNonSelectedElements } from "./scene/selection";
7
+ import { getSelectedElements, getVisibleAndNonSelectedElements, } from "./scene/selection";
8
8
  const SNAP_DISTANCE = 8;
9
9
  // do not comput more gaps per axis than this limit
10
10
  // TODO increase or remove once we optimize
@@ -51,14 +51,14 @@ export const isSnappingEnabled = ({ event, appState, selectedElements, }) => {
51
51
  export const areRoughlyEqual = (a, b, precision = 0.01) => {
52
52
  return Math.abs(a - b) <= precision;
53
53
  };
54
- export const getElementsCorners = (elements, { omitCenter, boundingBoxCorners, dragOffset, } = {
54
+ export const getElementsCorners = (elements, elementsMap, { omitCenter, boundingBoxCorners, dragOffset, } = {
55
55
  omitCenter: false,
56
56
  boundingBoxCorners: false,
57
57
  }) => {
58
58
  let result = [];
59
59
  if (elements.length === 1) {
60
60
  const element = elements[0];
61
- let [x1, y1, x2, y2, cx, cy] = getElementAbsoluteCoords(element);
61
+ let [x1, y1, x2, y2, cx, cy] = getElementAbsoluteCoords(element, elementsMap);
62
62
  if (dragOffset) {
63
63
  x1 += dragOffset.x;
64
64
  x2 += dragOffset.x;
@@ -106,15 +106,15 @@ export const getElementsCorners = (elements, { omitCenter, boundingBoxCorners, d
106
106
  }
107
107
  return result.map((point) => [round(point[0]), round(point[1])]);
108
108
  };
109
- const getReferenceElements = (elements, selectedElements, appState) => {
109
+ const getReferenceElements = (elements, selectedElements, appState, elementsMap) => {
110
110
  const selectedFrames = selectedElements
111
111
  .filter((element) => isFrameLikeElement(element))
112
112
  .map((frame) => frame.id);
113
- return getVisibleAndNonSelectedElements(elements, selectedElements, appState).filter((element) => !(element.frameId && selectedFrames.includes(element.frameId)));
113
+ return getVisibleAndNonSelectedElements(elements, selectedElements, appState, elementsMap).filter((element) => !(element.frameId && selectedFrames.includes(element.frameId)));
114
114
  };
115
- export const getVisibleGaps = (elements, selectedElements, appState) => {
116
- const referenceElements = getReferenceElements(elements, selectedElements, appState);
117
- const referenceBounds = getMaximumGroups(referenceElements)
115
+ export const getVisibleGaps = (elements, selectedElements, appState, elementsMap) => {
116
+ const referenceElements = getReferenceElements(elements, selectedElements, appState, elementsMap);
117
+ const referenceBounds = getMaximumGroups(referenceElements, elementsMap)
118
118
  .filter((elementsGroup) => !(elementsGroup.length === 1 && isBoundToContainer(elementsGroup[0])))
119
119
  .map((group) => getCommonBounds(group).map((bound) => round(bound)));
120
120
  const horizontallySorted = referenceBounds.sort((a, b) => a[0] - b[0]);
@@ -317,11 +317,11 @@ const getGapSnaps = (selectedElements, dragOffset, appState, event, nearestSnaps
317
317
  }
318
318
  }
319
319
  };
320
- export const getReferenceSnapPoints = (elements, selectedElements, appState) => {
321
- const referenceElements = getReferenceElements(elements, selectedElements, appState);
322
- return getMaximumGroups(referenceElements)
320
+ export const getReferenceSnapPoints = (elements, selectedElements, appState, elementsMap) => {
321
+ const referenceElements = getReferenceElements(elements, selectedElements, appState, elementsMap);
322
+ return getMaximumGroups(referenceElements, elementsMap)
323
323
  .filter((elementsGroup) => !(elementsGroup.length === 1 && isBoundToContainer(elementsGroup[0])))
324
- .flatMap((elementGroup) => getElementsCorners(elementGroup));
324
+ .flatMap((elementGroup) => getElementsCorners(elementGroup, elementsMap));
325
325
  };
326
326
  const getPointSnaps = (selectedElements, selectionSnapPoints, appState, event, nearestSnapsX, nearestSnapsY, minOffset) => {
327
327
  if (!isSnappingEnabled({ appState, event, selectedElements }) ||
@@ -360,7 +360,8 @@ const getPointSnaps = (selectedElements, selectionSnapPoints, appState, event, n
360
360
  }
361
361
  }
362
362
  };
363
- export const snapDraggedElements = (selectedElements, dragOffset, appState, event) => {
363
+ export const snapDraggedElements = (elements, dragOffset, appState, event, elementsMap) => {
364
+ const selectedElements = getSelectedElements(elements, appState);
364
365
  if (!isSnappingEnabled({ appState, event, selectedElements }) ||
365
366
  selectedElements.length === 0) {
366
367
  return {
@@ -380,7 +381,7 @@ export const snapDraggedElements = (selectedElements, dragOffset, appState, even
380
381
  x: snapDistance,
381
382
  y: snapDistance,
382
383
  };
383
- const selectionPoints = getElementsCorners(selectedElements, {
384
+ const selectionPoints = getElementsCorners(selectedElements, elementsMap, {
384
385
  dragOffset,
385
386
  });
386
387
  // get the nearest horizontal and vertical point and gap snaps
@@ -406,7 +407,7 @@ export const snapDraggedElements = (selectedElements, dragOffset, appState, even
406
407
  x: round(dragOffset.x + snapOffset.x),
407
408
  y: round(dragOffset.y + snapOffset.y),
408
409
  };
409
- getPointSnaps(selectedElements, getElementsCorners(selectedElements, {
410
+ getPointSnaps(selectedElements, getElementsCorners(selectedElements, elementsMap, {
410
411
  dragOffset: newDragOffset,
411
412
  }), appState, event, nearestSnapsX, nearestSnapsY, minOffset);
412
413
  getGapSnaps(selectedElements, newDragOffset, appState, event, nearestSnapsX, nearestSnapsY, minOffset);
@@ -735,7 +736,7 @@ selectedOriginalElements, appState, event, dragOffset, transformHandle) => {
735
736
  snapLines: pointSnapLines,
736
737
  };
737
738
  };
738
- export const snapNewElement = (draggingElement, appState, event, origin, dragOffset) => {
739
+ export const snapNewElement = (draggingElement, appState, event, origin, dragOffset, elementsMap) => {
739
740
  if (!isSnappingEnabled({ event, selectedElements: [draggingElement], appState })) {
740
741
  return {
741
742
  snapOffset: { x: 0, y: 0 },
@@ -761,7 +762,7 @@ export const snapNewElement = (draggingElement, appState, event, origin, dragOff
761
762
  minOffset.y = 0;
762
763
  nearestSnapsX.length = 0;
763
764
  nearestSnapsY.length = 0;
764
- const corners = getElementsCorners([draggingElement], {
765
+ const corners = getElementsCorners([draggingElement], elementsMap, {
765
766
  boundingBoxCorners: true,
766
767
  omitCenter: true,
767
768
  });
@@ -772,14 +773,14 @@ export const snapNewElement = (draggingElement, appState, event, origin, dragOff
772
773
  snapLines: pointSnapLines,
773
774
  };
774
775
  };
775
- export const getSnapLinesAtPointer = (elements, appState, pointer, event) => {
776
+ export const getSnapLinesAtPointer = (elements, appState, pointer, event, elementsMap) => {
776
777
  if (!isSnappingEnabled({ event, selectedElements: [], appState })) {
777
778
  return {
778
779
  originOffset: { x: 0, y: 0 },
779
780
  snapLines: [],
780
781
  };
781
782
  }
782
- const referenceElements = getVisibleAndNonSelectedElements(elements, [], appState);
783
+ const referenceElements = getVisibleAndNonSelectedElements(elements, [], appState, elementsMap);
783
784
  const snapDistance = getSnapDistance(appState.zoom.value);
784
785
  const minOffset = {
785
786
  x: snapDistance,
@@ -788,7 +789,7 @@ export const getSnapLinesAtPointer = (elements, appState, pointer, event) => {
788
789
  const horizontalSnapLines = [];
789
790
  const verticalSnapLines = [];
790
791
  for (const referenceElement of referenceElements) {
791
- const corners = getElementsCorners([referenceElement]);
792
+ const corners = getElementsCorners([referenceElement], elementsMap);
792
793
  for (const corner of corners) {
793
794
  const offsetX = corner[0] - pointer.x;
794
795
  if (Math.abs(offsetX) <= Math.abs(minOffset.x)) {
@@ -1,5 +1,5 @@
1
1
  import React from "react";
2
- import { PointerType, ExcalidrawLinearElement, NonDeletedExcalidrawElement, NonDeleted, TextAlign, ExcalidrawElement, GroupId, ExcalidrawBindableElement, Arrowhead, ChartType, FontFamilyValues, FileId, ExcalidrawImageElement, Theme, StrokeRoundness, ExcalidrawEmbeddableElement, ExcalidrawMagicFrameElement, ExcalidrawFrameLikeElement, ExcalidrawElementType } from "./element/types";
2
+ import { PointerType, ExcalidrawLinearElement, NonDeletedExcalidrawElement, NonDeleted, TextAlign, ExcalidrawElement, GroupId, ExcalidrawBindableElement, Arrowhead, ChartType, FontFamilyValues, FileId, ExcalidrawImageElement, Theme, StrokeRoundness, ExcalidrawEmbeddableElement, ExcalidrawMagicFrameElement, ExcalidrawFrameLikeElement, ExcalidrawElementType, ExcalidrawIframeLikeElement } from "./element/types";
3
3
  import { Action } from "./actions/types";
4
4
  import { Point as RoughPoint } from "roughjs/bin/geometry";
5
5
  import { LinearElementEditor } from "./element/linearElementEditor";
@@ -10,7 +10,7 @@ import type { throttleRAF } from "./utils";
10
10
  import { Spreadsheet } from "./charts";
11
11
  import { Language } from "./i18n";
12
12
  import { ClipboardData } from "./clipboard";
13
- import { isOverScrollBars } from "./scene";
13
+ import { isOverScrollBars } from "./scene/scrollbars";
14
14
  import { MaybeTransformHandleType } from "./element/transformHandles";
15
15
  import Library from "./data/library";
16
16
  import type { FileSystemHandle } from "./data/filesystem";
@@ -181,7 +181,7 @@ export interface AppState {
181
181
  scrollY: number;
182
182
  cursorButton: "up" | "down";
183
183
  scrolledOutside: boolean;
184
- name: string;
184
+ name: string | null;
185
185
  isResizing: boolean;
186
186
  isRotating: boolean;
187
187
  zoom: Zoom;
@@ -347,6 +347,7 @@ export interface ExcalidrawProps {
347
347
  nativeEvent: MouseEvent | React.PointerEvent<HTMLCanvasElement>;
348
348
  }>) => void;
349
349
  onPointerDown?: (activeTool: AppState["activeTool"], pointerDownState: PointerDownState) => void;
350
+ onPointerUp?: (activeTool: AppState["activeTool"], pointerDownState: PointerDownState) => void;
350
351
  onScrollChange?: (scrollX: number, scrollY: number, zoom: Zoom) => void;
351
352
  onUserFollow?: (payload: OnUserFollowedPayload) => void;
352
353
  children?: React.ReactNode;
@@ -367,7 +368,7 @@ export declare enum UserIdleState {
367
368
  }
368
369
  export type ExportOpts = {
369
370
  saveFileToDisk?: boolean;
370
- onExportToBackend?: (exportedElements: readonly NonDeletedExcalidrawElement[], appState: UIAppState, files: BinaryFiles, canvas: HTMLCanvasElement) => void;
371
+ onExportToBackend?: (exportedElements: readonly NonDeletedExcalidrawElement[], appState: UIAppState, files: BinaryFiles) => void;
371
372
  renderCustomUI?: (exportedElements: readonly NonDeletedExcalidrawElement[], appState: UIAppState, files: BinaryFiles, canvas: HTMLCanvasElement) => JSX.Element;
372
373
  };
373
374
  export type CanvasActions = Partial<{
@@ -429,6 +430,7 @@ export type AppClassProperties = {
429
430
  setOpenDialog: App["setOpenDialog"];
430
431
  insertEmbeddableElement: App["insertEmbeddableElement"];
431
432
  onMagicframeToolSelect: App["onMagicframeToolSelect"];
433
+ getName: App["getName"];
432
434
  };
433
435
  export type PointerDownState = Readonly<{
434
436
  origin: Readonly<{
@@ -482,12 +484,6 @@ export type PointerDownState = Readonly<{
482
484
  boxSelection: {
483
485
  hasOccurred: boolean;
484
486
  };
485
- elementIdsToErase: {
486
- [key: ExcalidrawElement["id"]]: {
487
- opacity: ExcalidrawElement["opacity"];
488
- erase: boolean;
489
- };
490
- };
491
487
  }>;
492
488
  export type UnsubscribeCallback = () => void;
493
489
  export type ExcalidrawImperativeAPI = {
@@ -498,10 +494,11 @@ export type ExcalidrawImperativeAPI = {
498
494
  history: {
499
495
  clear: InstanceType<typeof App>["resetHistory"];
500
496
  };
501
- scrollToContent: InstanceType<typeof App>["scrollToContent"];
502
497
  getSceneElements: InstanceType<typeof App>["getSceneElements"];
503
498
  getAppState: () => InstanceType<typeof App>["state"];
504
499
  getFiles: () => InstanceType<typeof App>["files"];
500
+ getName: InstanceType<typeof App>["getName"];
501
+ scrollToContent: InstanceType<typeof App>["scrollToContent"];
505
502
  registerAction: (action: Action) => void;
506
503
  refresh: InstanceType<typeof App>["refresh"];
507
504
  setToast: InstanceType<typeof App>["setToast"];
@@ -556,4 +553,6 @@ export type KeyboardModifiersObject = {
556
553
  };
557
554
  export type Primitive = number | string | boolean | bigint | symbol | null | undefined;
558
555
  export type JSONValue = string | number | boolean | null | object;
556
+ export type EmbedsValidationStatus = Map<ExcalidrawIframeLikeElement["id"], boolean>;
557
+ export type ElementsPendingErasure = Set<ExcalidrawElement["id"]>;
559
558
  export {};
@@ -23,3 +23,8 @@ export type ExtractSetType<T extends Set<any>> = T extends Set<infer U> ? U : ne
23
23
  export type SameType<T, U> = T extends U ? (U extends T ? true : false) : false;
24
24
  export type Assert<T extends true> = T;
25
25
  export type NestedKeyOf<T, K = keyof T> = K extends keyof T & (string | number) ? `${K}` | (T[K] extends object ? `${K}.${NestedKeyOf<T[K]>}` : never) : never;
26
+ export type SetLike<T> = Set<T> | T[];
27
+ export type ReadonlySetLike<T> = ReadonlySet<T> | readonly T[];
28
+ export type MakeBrand<T extends string> = {
29
+ [K in `~brand~${T}`]: T;
30
+ };
@@ -141,19 +141,6 @@ export type ResolvablePromise<T> = Promise<T> & {
141
141
  reject: (error: Error) => void;
142
142
  };
143
143
  export declare const resolvablePromise: <T>() => ResolvablePromise<T>;
144
- /**
145
- * @param func handler taking at most single parameter (event).
146
- */
147
- export declare const withBatchedUpdates: <TFunction extends ((event: any) => void) | (() => void)>(func: Parameters<TFunction>["length"] extends 0 | 1 ? TFunction : never) => TFunction;
148
- /**
149
- * barches React state updates and throttles the calls to a single call per
150
- * animation frame
151
- */
152
- export declare const withBatchedUpdatesThrottled: <TFunction extends ((event: any) => void) | (() => void)>(func: Parameters<TFunction>["length"] extends 0 | 1 ? TFunction : never) => {
153
- (...args: Parameters<TFunction>): void;
154
- flush(): void;
155
- cancel(): void;
156
- };
157
144
  export declare const nFormatter: (num: number, digits: number) => string;
158
145
  export declare const getVersion: () => string;
159
146
  export declare const supportsEmoji: () => boolean;
@@ -168,7 +155,7 @@ export declare const getUpdatedTimestamp: () => number;
168
155
  */
169
156
  export declare const arrayToMap: <T extends string | {
170
157
  id: string;
171
- }>(items: readonly T[]) => Map<string, T>;
158
+ }>(items: Map<string, T> | readonly T[]) => Map<string, T>;
172
159
  export declare const arrayToMapWithIndex: <T extends {
173
160
  id: string;
174
161
  }>(elements: readonly T[]) => Map<string, [element: T, index: number]>;
@@ -205,7 +192,6 @@ export declare const assertNever: (value: never, message: string | null, softAss
205
192
  export declare const memoize: <T extends Record<string, any>, R extends unknown>(func: (opts: T) => R) => ((opts: T) => R) & {
206
193
  clear: () => void;
207
194
  };
208
- export declare const isRenderThrottlingEnabled: () => boolean;
209
195
  /** Checks if value is inside given collection. Useful for type-safety. */
210
196
  export declare const isMemberOf: <T extends string>(collection: Set<T> | Record<T, any> | Map<T, any> | readonly T[], value: string) => value is T;
211
197
  export declare const cloneJSON: <T>(obj: T) => T;
@@ -217,3 +203,20 @@ export declare function addEventListener<K extends keyof DocumentEventMap>(targe
217
203
  export declare function addEventListener(target: Document, type: string, listener: (this: Document, ev: Event) => any, options?: boolean | AddEventListenerOptions): UnsubscribeCallback;
218
204
  export declare function addEventListener<K extends keyof FontFaceSetEventMap>(target: FontFaceSet, type: K, listener: (this: FontFaceSet, ev: FontFaceSetEventMap[K]) => any, options?: boolean | AddEventListenerOptions): UnsubscribeCallback;
219
205
  export declare function addEventListener<K extends keyof HTMLElementEventMap>(target: Document | (Window & typeof globalThis) | HTMLElement | undefined | null | false, type: K, listener: (this: HTMLDivElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): UnsubscribeCallback;
206
+ export declare function getSvgPathFromStroke(points: number[][], closed?: boolean): string;
207
+ export declare const normalizeEOL: (str: string) => string;
208
+ type HasBrand<T> = {
209
+ [K in keyof T]: K extends `~brand${infer _}` ? true : never;
210
+ }[keyof T];
211
+ type RemoveAllBrands<T> = HasBrand<T> extends true ? {
212
+ [K in keyof T as K extends `~brand~${infer _}` ? never : K]: T[K];
213
+ } : never;
214
+ type Unbrand<T> = T extends Map<infer E, infer F> ? Map<E, F> : T extends Set<infer E> ? Set<E> : T extends Array<infer E> ? Array<E> : RemoveAllBrands<T>;
215
+ /**
216
+ * Makes type into a branded type, ensuring that value is assignable to
217
+ * the base ubranded type. Optionally you can explicitly supply current value
218
+ * type to combine both (useful for composite branded types. Make sure you
219
+ * compose branded types which are not composite themselves.)
220
+ */
221
+ export declare const toBrandedType: <BrandedType, CurrentType = BrandedType>(value: Unbrand<BrandedType>) => CurrentType & BrandedType;
222
+ export {};
@@ -1,7 +1,5 @@
1
1
  import { COLOR_PALETTE } from "./colors";
2
2
  import { DEFAULT_VERSION, FONT_FAMILY, isDarwin, WINDOWS_EMOJI_FALLBACK_FONT, } from "./constants";
3
- import { unstable_batchedUpdates } from "react-dom";
4
- import React from "react";
5
3
  let mockDateTime = null;
6
4
  export const setDateTimeForTests = (dateTime) => {
7
5
  mockDateTime = dateTime;
@@ -354,22 +352,6 @@ export const resolvablePromise = () => {
354
352
  promise.reject = reject;
355
353
  return promise;
356
354
  };
357
- /**
358
- * @param func handler taking at most single parameter (event).
359
- */
360
- export const withBatchedUpdates = (func) => ((event) => {
361
- unstable_batchedUpdates(func, event);
362
- });
363
- /**
364
- * barches React state updates and throttles the calls to a single call per
365
- * animation frame
366
- */
367
- export const withBatchedUpdatesThrottled = (func) => {
368
- // @ts-ignore
369
- return throttleRAF(((event) => {
370
- unstable_batchedUpdates(func, event);
371
- }));
372
- };
373
355
  //https://stackoverflow.com/a/9462382/8418
374
356
  export const nFormatter = (num, digits) => {
375
357
  const si = [
@@ -451,6 +433,9 @@ export const getUpdatedTimestamp = () => (isTestEnv() ? 1 : Date.now());
451
433
  * or array of ids (strings), into a Map, keyd by `id`.
452
434
  */
453
435
  export const arrayToMap = (items) => {
436
+ if (items instanceof Map) {
437
+ return items;
438
+ }
454
439
  return items.reduce((acc, element) => {
455
440
  acc.set(typeof element === "string" ? element : element.id, element);
456
441
  return acc;
@@ -568,7 +553,7 @@ export const composeEventHandlers = (originalEventHandler, ourEventHandler, { ch
568
553
  return function handleEvent(event) {
569
554
  originalEventHandler?.(event);
570
555
  if (!checkForDefaultPrevented ||
571
- !event.defaultPrevented) {
556
+ !event?.defaultPrevented) {
572
557
  return ourEventHandler?.(event);
573
558
  }
574
559
  };
@@ -618,32 +603,6 @@ export const memoize = (func) => {
618
603
  };
619
604
  return ret;
620
605
  };
621
- export const isRenderThrottlingEnabled = (() => {
622
- // we don't want to throttle in react < 18 because of #5439 and it was
623
- // getting more complex to maintain the fix
624
- let IS_REACT_18_AND_UP;
625
- try {
626
- const version = React.version.split(".");
627
- IS_REACT_18_AND_UP = Number(version[0]) > 17;
628
- }
629
- catch {
630
- IS_REACT_18_AND_UP = false;
631
- }
632
- let hasWarned = false;
633
- return () => {
634
- if (window.EXCALIDRAW_THROTTLE_RENDER === true) {
635
- if (!IS_REACT_18_AND_UP) {
636
- if (!hasWarned) {
637
- hasWarned = true;
638
- console.warn("Excalidraw: render throttling is disabled on React versions < 18.");
639
- }
640
- return false;
641
- }
642
- return true;
643
- }
644
- return false;
645
- };
646
- })();
647
606
  /** Checks if value is inside given collection. Useful for type-safety. */
648
607
  export const isMemberOf = (
649
608
  /** Set/Map/Array/Object */
@@ -681,3 +640,36 @@ target, type, listener, options) {
681
640
  target?.removeEventListener?.(type, listener, options);
682
641
  };
683
642
  }
643
+ const average = (a, b) => (a + b) / 2;
644
+ export function getSvgPathFromStroke(points, closed = true) {
645
+ const len = points.length;
646
+ if (len < 4) {
647
+ return ``;
648
+ }
649
+ let a = points[0];
650
+ let b = points[1];
651
+ const c = points[2];
652
+ let result = `M${a[0].toFixed(2)},${a[1].toFixed(2)} Q${b[0].toFixed(2)},${b[1].toFixed(2)} ${average(b[0], c[0]).toFixed(2)},${average(b[1], c[1]).toFixed(2)} T`;
653
+ for (let i = 2, max = len - 1; i < max; i++) {
654
+ a = points[i];
655
+ b = points[i + 1];
656
+ result += `${average(a[0], b[0]).toFixed(2)},${average(a[1], b[1]).toFixed(2)} `;
657
+ }
658
+ if (closed) {
659
+ result += "Z";
660
+ }
661
+ return result;
662
+ }
663
+ export const normalizeEOL = (str) => {
664
+ return str.replace(/\r?\n|\r/g, "\n");
665
+ };
666
+ /**
667
+ * Makes type into a branded type, ensuring that value is assignable to
668
+ * the base ubranded type. Optionally you can explicitly supply current value
669
+ * type to combine both (useful for composite branded types. Make sure you
670
+ * compose branded types which are not composite themselves.)
671
+ */
672
+ export const toBrandedType = (value) => {
673
+ return value;
674
+ };
675
+ // -----------------------------------------------------------------------------
@@ -138,7 +138,9 @@
138
138
  "removeAllElementsFromFrame": "Remove all elements from frame",
139
139
  "eyeDropper": "Pick color from canvas",
140
140
  "textToDiagram": "Text to diagram",
141
- "prompt": "Prompt"
141
+ "prompt": "Prompt",
142
+ "followUs": "Follow us",
143
+ "discordChat": "Discord chat"
142
144
  },
143
145
  "library": {
144
146
  "noItems": "No items added yet...",
@@ -212,7 +214,6 @@
212
214
  "fileTooBig": "File is too big. Maximum allowed size is {{maxSize}}.",
213
215
  "svgImageInsertError": "Couldn't insert SVG image. The SVG markup looks invalid.",
214
216
  "failedToFetchImage": "Failed to fetch image.",
215
- "invalidSVGString": "Invalid SVG.",
216
217
  "cannotResolveCollabServer": "Couldn't connect to the collab server. Please reload the page and try again.",
217
218
  "importLibraryError": "Couldn't load library",
218
219
  "collabSaveFailed": "Couldn't save to the backend database. If problems persist, you should save your file locally to ensure you don't lose your work.",
@@ -246,7 +247,7 @@
246
247
  "library": "Library",
247
248
  "lock": "Keep selected tool active after drawing",
248
249
  "penMode": "Pen mode - prevent touch",
249
- "link": "Add/ Update link for a selected shape",
250
+ "link": "Add / Update link for a selected shape",
250
251
  "eraser": "Eraser",
251
252
  "frame": "Frame tool",
252
253
  "magicframe": "Wireframe to code",
@@ -299,9 +300,12 @@
299
300
  "openIssueMessage": "We were very cautious not to include your scene information on the error. If your scene is not private, please consider following up on our <button>bug tracker</button>. Please include information below by copying and pasting into the GitHub issue.",
300
301
  "sceneContent": "Scene content:"
301
302
  },
303
+ "shareDialog": {
304
+ "or": "Or"
305
+ },
302
306
  "roomDialog": {
303
- "desc_intro": "You can invite people to your current scene to collaborate with you.",
304
- "desc_privacy": "Don't worry, the session uses end-to-end encryption, so whatever you draw will stay private. Not even our server will be able to see what you come up with.",
307
+ "desc_intro": "Invite people to collaborate on your drawing.",
308
+ "desc_privacy": "Don't worry, the session is end-to-end encrypted, and fully private. Not even our server can see what you draw.",
305
309
  "button_startSession": "Start session",
306
310
  "button_stopSession": "Stop session",
307
311
  "desc_inProgressIntro": "Live-collaboration session is now in progress.",