@excalidraw/excalidraw 0.17.1-890ed9f → 0.17.1-96eeec5

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 (451) hide show
  1. package/CHANGELOG.md +15 -2
  2. package/dist/browser/dev/excalidraw-assets-dev/{blockDiagram-91b80b7a-ACFH36JV.js → blockDiagram-91b80b7a-H47FTXHA.js} +5 -5
  3. package/dist/browser/dev/excalidraw-assets-dev/{c4Diagram-b2a90758-QZ27YR47.js → c4Diagram-b2a90758-NNJK6GKC.js} +3 -3
  4. package/dist/browser/dev/excalidraw-assets-dev/{chunk-HO2HMSK7.js → chunk-4KQVEBHW.js} +3 -3
  5. package/dist/browser/dev/excalidraw-assets-dev/{chunk-USGV265L.js → chunk-53YI56GV.js} +4 -4
  6. package/dist/browser/dev/excalidraw-assets-dev/{chunk-EDFX3S7X.js → chunk-A2WCJI4I.js} +3 -3
  7. package/dist/browser/dev/excalidraw-assets-dev/{chunk-WQFMSDPT.js → chunk-DEYXWPUO.js} +7503 -2575
  8. package/dist/browser/dev/excalidraw-assets-dev/chunk-DEYXWPUO.js.map +7 -0
  9. package/dist/browser/dev/excalidraw-assets-dev/{chunk-IX4V72YG.js → chunk-EFLPX7NE.js} +6 -6
  10. package/dist/browser/dev/excalidraw-assets-dev/{chunk-XOM7LNOU.js → chunk-EM6LVGFW.js} +27 -4
  11. package/dist/browser/dev/excalidraw-assets-dev/chunk-EM6LVGFW.js.map +7 -0
  12. package/dist/browser/dev/excalidraw-assets-dev/{chunk-MXVETLVM.js → chunk-JYIQCNWV.js} +2 -2
  13. package/dist/browser/dev/excalidraw-assets-dev/{chunk-YZIOORVX.js → chunk-LVIQQW6F.js} +2 -2
  14. package/dist/browser/dev/excalidraw-assets-dev/{chunk-6U7GQNJT.js → chunk-PXLO3FOU.js} +2 -2
  15. package/dist/browser/dev/excalidraw-assets-dev/{chunk-7DACDEY3.js → chunk-TO2AW5PW.js} +2 -2
  16. package/dist/browser/dev/excalidraw-assets-dev/{chunk-NJ77ZFNJ.js → chunk-VURILHLY.js} +2 -2
  17. package/dist/browser/dev/excalidraw-assets-dev/{chunk-2T2GU7NF.js → chunk-ZAYGSUHF.js} +2 -2
  18. package/dist/browser/dev/excalidraw-assets-dev/{chunk-Z3PH3V2B.js → chunk-ZQR5ML6Y.js} +26 -26
  19. package/dist/browser/dev/excalidraw-assets-dev/chunk-ZQR5ML6Y.js.map +7 -0
  20. package/dist/browser/dev/excalidraw-assets-dev/{classDiagram-30eddba6-QSLMH4JW.js → classDiagram-30eddba6-CUYIJICN.js} +5 -5
  21. package/dist/browser/dev/excalidraw-assets-dev/{classDiagram-v2-f2df5561-DY4DYQ5P.js → classDiagram-v2-f2df5561-K6WW6K73.js} +8 -8
  22. package/dist/browser/dev/excalidraw-assets-dev/{dist-Z46EOVOL.js → dist-6QVAH5JA.js} +37 -15
  23. package/dist/browser/dev/excalidraw-assets-dev/dist-6QVAH5JA.js.map +7 -0
  24. package/dist/browser/dev/excalidraw-assets-dev/{en-TR4QLF5E.js → en-AZFA5HJJ.js} +4 -2
  25. package/dist/browser/dev/excalidraw-assets-dev/{erDiagram-47591fe2-SOOJRTCB.js → erDiagram-47591fe2-XGAD7EEP.js} +4 -4
  26. package/dist/browser/dev/excalidraw-assets-dev/{flowDiagram-5540d9b9-AHGL4KPK.js → flowDiagram-5540d9b9-B6EOVNNO.js} +9 -9
  27. package/dist/browser/dev/excalidraw-assets-dev/{flowDiagram-v2-3b53844e-56LDZZWY.js → flowDiagram-v2-3b53844e-NUG24FJH.js} +9 -9
  28. package/dist/browser/dev/excalidraw-assets-dev/{flowchart-elk-definition-5fe447d6-27LUKRI6.js → flowchart-elk-definition-5fe447d6-25Y7PCBL.js} +5 -5
  29. package/dist/browser/dev/excalidraw-assets-dev/{ganttDiagram-9a3bba1f-EHGYGNG6.js → ganttDiagram-9a3bba1f-GNL6ZDTC.js} +2 -2
  30. package/dist/browser/dev/excalidraw-assets-dev/{gitGraphDiagram-96e6b4ee-AJQNBDW5.js → gitGraphDiagram-96e6b4ee-HNW52NVO.js} +2 -2
  31. package/dist/browser/dev/excalidraw-assets-dev/{image-OIPMBJGR.js → image-5XCR4WHS.js} +2 -2
  32. package/dist/browser/dev/excalidraw-assets-dev/{image-OFRRV5MB.css → image-O66MQ7WQ.css} +1 -1
  33. package/dist/browser/dev/excalidraw-assets-dev/image-O66MQ7WQ.css.map +7 -0
  34. package/dist/browser/dev/excalidraw-assets-dev/{infoDiagram-bcd20f53-SWLLQVES.js → infoDiagram-bcd20f53-FWEUVFLT.js} +2 -2
  35. package/dist/browser/dev/excalidraw-assets-dev/{journeyDiagram-4fe6b3dc-7UAVCWOZ.js → journeyDiagram-4fe6b3dc-RZIUI7UG.js} +3 -3
  36. package/dist/browser/dev/excalidraw-assets-dev/{mindmap-definition-f354de21-SROW5KGM.js → mindmap-definition-f354de21-GBVN45GU.js} +3 -3
  37. package/dist/browser/dev/excalidraw-assets-dev/{pieDiagram-79897490-QKCI6NCB.js → pieDiagram-79897490-ECENNII6.js} +2 -2
  38. package/dist/browser/dev/excalidraw-assets-dev/{quadrantDiagram-62f64e94-LNYJZFC5.js → quadrantDiagram-62f64e94-ZMEOFVNL.js} +2 -2
  39. package/dist/browser/dev/excalidraw-assets-dev/{requirementDiagram-05bf5f74-ZZD7ZHFA.js → requirementDiagram-05bf5f74-FHZSFHCR.js} +4 -4
  40. package/dist/browser/dev/excalidraw-assets-dev/{sankeyDiagram-97764748-L75ZZ4UM.js → sankeyDiagram-97764748-VDKIKTA6.js} +2 -2
  41. package/dist/browser/dev/excalidraw-assets-dev/{sequenceDiagram-acc0e65c-6PCU7TDK.js → sequenceDiagram-acc0e65c-6JUSPVKX.js} +3 -3
  42. package/dist/browser/dev/excalidraw-assets-dev/{stateDiagram-0ff1cf1a-WM76WOPR.js → stateDiagram-0ff1cf1a-L3AKWENF.js} +5 -5
  43. package/dist/browser/dev/excalidraw-assets-dev/{stateDiagram-v2-9a9d610d-N4HZW3O2.js → stateDiagram-v2-9a9d610d-NU3GGMCH.js} +8 -8
  44. package/dist/browser/dev/excalidraw-assets-dev/{timeline-definition-fea2a41d-ZHGCAXGP.js → timeline-definition-fea2a41d-JGP7XCHW.js} +2 -2
  45. package/dist/browser/dev/excalidraw-assets-dev/{xychartDiagram-ab372869-2DLOVRAZ.js → xychartDiagram-ab372869-HLFHHF2I.js} +3 -3
  46. package/dist/browser/dev/index.css +199 -77
  47. package/dist/browser/dev/index.css.map +3 -3
  48. package/dist/browser/dev/index.js +12477 -8028
  49. package/dist/browser/dev/index.js.map +4 -4
  50. package/dist/browser/prod/excalidraw-assets/{blockDiagram-91b80b7a-ONPS22AM.js → blockDiagram-91b80b7a-FVCRVGN5.js} +1 -1
  51. package/dist/browser/prod/excalidraw-assets/{c4Diagram-b2a90758-XMIQY7ZT.js → c4Diagram-b2a90758-56CXO7GA.js} +1 -1
  52. package/dist/browser/prod/excalidraw-assets/{chunk-GCHQBOKV.js → chunk-635MQ3CK.js} +1 -1
  53. package/dist/browser/prod/excalidraw-assets/{chunk-5SYIAZGL.js → chunk-7DXALCB2.js} +5 -5
  54. package/dist/browser/prod/excalidraw-assets/{chunk-P5M3G2RP.js → chunk-AIKXYJX3.js} +1 -1
  55. package/dist/browser/prod/excalidraw-assets/{chunk-E2YLWFZX.js → chunk-CR7VMNWC.js} +1 -1
  56. package/dist/browser/prod/excalidraw-assets/{chunk-WEYK4A2L.js → chunk-FFF2CSVG.js} +1 -1
  57. package/dist/browser/prod/excalidraw-assets/{chunk-R3HAIP6R.js → chunk-G4WDCSPE.js} +1 -1
  58. package/dist/browser/prod/excalidraw-assets/{chunk-HFOXJM22.js → chunk-HKZSHFLX.js} +1 -1
  59. package/dist/browser/prod/excalidraw-assets/{chunk-XIMFFJTE.js → chunk-IKCDYWMW.js} +1 -1
  60. package/dist/browser/prod/excalidraw-assets/{chunk-AHLLBBVJ.js → chunk-L5DS24G6.js} +1 -1
  61. package/dist/browser/prod/excalidraw-assets/{chunk-CQJF3C6G.js → chunk-MUNOKHUD.js} +1 -1
  62. package/dist/browser/prod/excalidraw-assets/chunk-ODWTVSS7.js +68 -0
  63. package/dist/browser/prod/excalidraw-assets/{chunk-NI6SYCUG.js → chunk-QOQYOOQ4.js} +1 -1
  64. package/dist/browser/prod/excalidraw-assets/{chunk-I2PZFXTK.js → chunk-ZTIWFPBM.js} +21 -21
  65. package/dist/browser/prod/excalidraw-assets/{classDiagram-30eddba6-IEJXXCVX.js → classDiagram-30eddba6-BCUTAUMD.js} +1 -1
  66. package/dist/browser/prod/excalidraw-assets/{classDiagram-v2-f2df5561-7LZDSWOS.js → classDiagram-v2-f2df5561-6SOXSGQ2.js} +1 -1
  67. package/dist/browser/prod/excalidraw-assets/dist-567JAXHK.js +7 -0
  68. package/dist/browser/prod/excalidraw-assets/en-6E7MYLWO.js +1 -0
  69. package/dist/browser/prod/excalidraw-assets/{erDiagram-47591fe2-E5V666CF.js → erDiagram-47591fe2-RE6HB7RM.js} +1 -1
  70. package/dist/browser/prod/excalidraw-assets/{flowDiagram-5540d9b9-GMBRCYVF.js → flowDiagram-5540d9b9-ZNJZBERW.js} +1 -1
  71. package/dist/browser/prod/excalidraw-assets/{flowDiagram-v2-3b53844e-Z4HUWP6B.js → flowDiagram-v2-3b53844e-LY44JLQJ.js} +1 -1
  72. package/dist/browser/prod/excalidraw-assets/{flowchart-elk-definition-5fe447d6-5ZCYTX5N.js → flowchart-elk-definition-5fe447d6-TMTJ6Z7O.js} +1 -1
  73. package/dist/browser/prod/excalidraw-assets/{ganttDiagram-9a3bba1f-WM32OMT5.js → ganttDiagram-9a3bba1f-5O6EA6LX.js} +1 -1
  74. package/dist/browser/prod/excalidraw-assets/{gitGraphDiagram-96e6b4ee-CAKZ2U6E.js → gitGraphDiagram-96e6b4ee-UHYNM5DI.js} +1 -1
  75. package/dist/browser/prod/excalidraw-assets/image-LQAMCFQI.js +1 -0
  76. package/dist/browser/prod/excalidraw-assets/{infoDiagram-bcd20f53-MUIKXGC4.js → infoDiagram-bcd20f53-BP77NQEH.js} +1 -1
  77. package/dist/browser/prod/excalidraw-assets/{journeyDiagram-4fe6b3dc-NYRV4HK2.js → journeyDiagram-4fe6b3dc-XMGKCMES.js} +1 -1
  78. package/dist/browser/prod/excalidraw-assets/{mindmap-definition-f354de21-MY55DRSM.js → mindmap-definition-f354de21-ZQRRBRWF.js} +1 -1
  79. package/dist/browser/prod/excalidraw-assets/{pieDiagram-79897490-47L6J6L2.js → pieDiagram-79897490-IGXEC2KX.js} +1 -1
  80. package/dist/browser/prod/excalidraw-assets/{quadrantDiagram-62f64e94-DF5C2GDT.js → quadrantDiagram-62f64e94-WTHHDYJL.js} +1 -1
  81. package/dist/browser/prod/excalidraw-assets/{requirementDiagram-05bf5f74-C4IMUBDN.js → requirementDiagram-05bf5f74-MV4OFRVW.js} +1 -1
  82. package/dist/browser/prod/excalidraw-assets/{sankeyDiagram-97764748-YHW7EUST.js → sankeyDiagram-97764748-ZGYUHEJT.js} +1 -1
  83. package/dist/browser/prod/excalidraw-assets/{sequenceDiagram-acc0e65c-H3XEHT32.js → sequenceDiagram-acc0e65c-IBSENK6W.js} +1 -1
  84. package/dist/browser/prod/excalidraw-assets/{stateDiagram-0ff1cf1a-Z5WB6Q3P.js → stateDiagram-0ff1cf1a-DB73XNZH.js} +1 -1
  85. package/dist/browser/prod/excalidraw-assets/{stateDiagram-v2-9a9d610d-T7OZETQC.js → stateDiagram-v2-9a9d610d-2OOBUPNR.js} +1 -1
  86. package/dist/browser/prod/excalidraw-assets/{timeline-definition-fea2a41d-VVC22BWF.js → timeline-definition-fea2a41d-P3NQQVDU.js} +1 -1
  87. package/dist/browser/prod/excalidraw-assets/{xychartDiagram-ab372869-JAXODQF7.js → xychartDiagram-ab372869-HI3XLK3Y.js} +1 -1
  88. package/dist/browser/prod/index.css +1 -1
  89. package/dist/browser/prod/index.js +69 -51
  90. package/dist/{prod/en-XW4JO6VX.json → dev/en-EB2MBPAV.json} +24 -3
  91. package/dist/dev/index.css +199 -77
  92. package/dist/dev/index.css.map +3 -3
  93. package/dist/dev/index.js +15120 -11334
  94. package/dist/dev/index.js.map +4 -4
  95. package/dist/excalidraw/actions/actionAddToLibrary.d.ts +16 -7
  96. package/dist/excalidraw/actions/actionAddToLibrary.js +4 -3
  97. package/dist/excalidraw/actions/actionAlign.d.ts +22 -22
  98. package/dist/excalidraw/actions/actionAlign.js +7 -6
  99. package/dist/excalidraw/actions/actionBoundText.d.ts +18 -12
  100. package/dist/excalidraw/actions/actionBoundText.js +7 -4
  101. package/dist/excalidraw/actions/actionCanvas.d.ts +100 -64
  102. package/dist/excalidraw/actions/actionCanvas.js +17 -14
  103. package/dist/excalidraw/actions/actionClipboard.d.ts +52 -31
  104. package/dist/excalidraw/actions/actionClipboard.js +14 -13
  105. package/dist/excalidraw/actions/actionDeleteSelected.d.ts +22 -13
  106. package/dist/excalidraw/actions/actionDeleteSelected.js +6 -3
  107. package/dist/excalidraw/actions/actionDistribute.d.ts +10 -10
  108. package/dist/excalidraw/actions/actionDistribute.js +3 -2
  109. package/dist/excalidraw/actions/actionDuplicateSelection.d.ts +7 -8
  110. package/dist/excalidraw/actions/actionDuplicateSelection.js +4 -4
  111. package/dist/excalidraw/actions/actionElementLock.d.ts +17 -11
  112. package/dist/excalidraw/actions/actionElementLock.js +3 -2
  113. package/dist/excalidraw/actions/actionExport.d.ts +68 -41
  114. package/dist/excalidraw/actions/actionExport.js +15 -11
  115. package/dist/excalidraw/actions/actionFinalize.d.ts +17 -11
  116. package/dist/excalidraw/actions/actionFinalize.js +7 -3
  117. package/dist/excalidraw/actions/actionFlip.d.ts +10 -10
  118. package/dist/excalidraw/actions/actionFlip.js +9 -9
  119. package/dist/excalidraw/actions/actionFrame.d.ts +186 -21
  120. package/dist/excalidraw/actions/actionFrame.js +7 -6
  121. package/dist/excalidraw/actions/actionGroup.d.ts +24 -18
  122. package/dist/excalidraw/actions/actionGroup.js +7 -11
  123. package/dist/excalidraw/actions/actionHistory.d.ts +4 -3
  124. package/dist/excalidraw/actions/actionHistory.js +27 -31
  125. package/dist/excalidraw/actions/actionLinearEditor.d.ts +10 -5
  126. package/dist/excalidraw/actions/actionLinearEditor.js +21 -5
  127. package/dist/excalidraw/actions/actionLink.d.ts +9 -6
  128. package/dist/excalidraw/actions/actionLink.js +2 -1
  129. package/dist/excalidraw/actions/actionMenu.d.ts +20 -11
  130. package/dist/excalidraw/actions/actionMenu.js +4 -3
  131. package/dist/excalidraw/actions/actionNavigate.d.ts +12 -6
  132. package/dist/excalidraw/actions/actionNavigate.js +3 -2
  133. package/dist/excalidraw/actions/actionProperties.d.ts +86 -47
  134. package/dist/excalidraw/actions/actionProperties.js +19 -14
  135. package/dist/excalidraw/actions/actionSelectAll.d.ts +9 -6
  136. package/dist/excalidraw/actions/actionSelectAll.js +2 -1
  137. package/dist/excalidraw/actions/actionStyles.d.ts +15 -12
  138. package/dist/excalidraw/actions/actionStyles.js +4 -3
  139. package/dist/excalidraw/actions/actionTextAutoResize.d.ts +17 -0
  140. package/dist/excalidraw/actions/actionTextAutoResize.js +38 -0
  141. package/dist/excalidraw/actions/actionToggleGridMode.d.ts +9 -6
  142. package/dist/excalidraw/actions/actionToggleGridMode.js +2 -1
  143. package/dist/excalidraw/actions/actionToggleObjectsSnapMode.d.ts +8 -5
  144. package/dist/excalidraw/actions/actionToggleObjectsSnapMode.js +2 -1
  145. package/dist/excalidraw/actions/actionToggleStats.d.ts +9 -5
  146. package/dist/excalidraw/actions/actionToggleStats.js +6 -4
  147. package/dist/excalidraw/actions/actionToggleViewMode.d.ts +8 -5
  148. package/dist/excalidraw/actions/actionToggleViewMode.js +2 -1
  149. package/dist/excalidraw/actions/actionToggleZenMode.d.ts +8 -5
  150. package/dist/excalidraw/actions/actionToggleZenMode.js +2 -1
  151. package/dist/excalidraw/actions/actionZindex.d.ts +20 -16
  152. package/dist/excalidraw/actions/actionZindex.js +9 -4
  153. package/dist/excalidraw/actions/manager.d.ts +5 -5
  154. package/dist/excalidraw/actions/register.d.ts +1 -1
  155. package/dist/excalidraw/actions/shortcuts.d.ts +2 -2
  156. package/dist/excalidraw/actions/types.d.ts +8 -8
  157. package/dist/excalidraw/align.d.ts +1 -1
  158. package/dist/excalidraw/animated-trail.d.ts +2 -2
  159. package/dist/excalidraw/appState.d.ts +9 -6
  160. package/dist/excalidraw/appState.js +6 -3
  161. package/dist/excalidraw/change.d.ts +191 -0
  162. package/dist/excalidraw/change.js +901 -0
  163. package/dist/excalidraw/charts.d.ts +1 -1
  164. package/dist/excalidraw/clients.d.ts +2 -2
  165. package/dist/excalidraw/clients.js +1 -1
  166. package/dist/excalidraw/clipboard.d.ts +3 -3
  167. package/dist/excalidraw/colors.d.ts +1 -1
  168. package/dist/excalidraw/components/Actions.d.ts +3 -3
  169. package/dist/excalidraw/components/Actions.js +9 -6
  170. package/dist/excalidraw/components/App.d.ts +19 -20
  171. package/dist/excalidraw/components/App.js +323 -195
  172. package/dist/excalidraw/components/ButtonIconSelect.js +1 -1
  173. package/dist/excalidraw/components/CheckboxItem.js +1 -1
  174. package/dist/excalidraw/components/ColorPicker/ColorInput.d.ts +1 -1
  175. package/dist/excalidraw/components/ColorPicker/ColorInput.js +1 -1
  176. package/dist/excalidraw/components/ColorPicker/ColorPicker.d.ts +4 -4
  177. package/dist/excalidraw/components/ColorPicker/ColorPicker.js +1 -1
  178. package/dist/excalidraw/components/ColorPicker/Picker.d.ts +3 -3
  179. package/dist/excalidraw/components/ColorPicker/PickerColorList.d.ts +1 -1
  180. package/dist/excalidraw/components/ColorPicker/PickerHeading.d.ts +1 -1
  181. package/dist/excalidraw/components/ColorPicker/ShadeList.d.ts +1 -1
  182. package/dist/excalidraw/components/ColorPicker/TopPicks.d.ts +1 -1
  183. package/dist/excalidraw/components/ColorPicker/colorPickerUtils.d.ts +2 -2
  184. package/dist/excalidraw/components/ColorPicker/colorPickerUtils.js +1 -1
  185. package/dist/excalidraw/components/ColorPicker/keyboardNavHandlers.d.ts +2 -2
  186. package/dist/excalidraw/components/ColorPicker/keyboardNavHandlers.js +1 -1
  187. package/dist/excalidraw/components/CommandPalette/CommandPalette.d.ts +1 -1
  188. package/dist/excalidraw/components/CommandPalette/CommandPalette.js +5 -5
  189. package/dist/excalidraw/components/CommandPalette/defaultCommandPaletteItems.d.ts +1 -1
  190. package/dist/excalidraw/components/CommandPalette/types.d.ts +3 -3
  191. package/dist/excalidraw/components/ConfirmDialog.d.ts +1 -1
  192. package/dist/excalidraw/components/ContextMenu.d.ts +2 -2
  193. package/dist/excalidraw/components/ContextMenu.js +2 -2
  194. package/dist/excalidraw/components/DarkModeToggle.d.ts +1 -1
  195. package/dist/excalidraw/components/DefaultSidebar.d.ts +2 -2
  196. package/dist/excalidraw/components/Dialog.js +1 -1
  197. package/dist/excalidraw/components/DialogActionButton.d.ts +1 -1
  198. package/dist/excalidraw/components/EyeDropper.d.ts +2 -2
  199. package/dist/excalidraw/components/FollowMode/FollowMode.d.ts +1 -1
  200. package/dist/excalidraw/components/FollowMode/FollowMode.js +1 -1
  201. package/dist/excalidraw/components/HelpDialog.js +1 -1
  202. package/dist/excalidraw/components/HintViewer.d.ts +1 -1
  203. package/dist/excalidraw/components/IconPicker.js +2 -2
  204. package/dist/excalidraw/components/ImageExportDialog.d.ts +1 -1
  205. package/dist/excalidraw/components/InitializeApp.d.ts +2 -2
  206. package/dist/excalidraw/components/JSONExportDialog.d.ts +3 -3
  207. package/dist/excalidraw/components/LayerUI.d.ts +4 -4
  208. package/dist/excalidraw/components/LayerUI.js +10 -7
  209. package/dist/excalidraw/components/LibraryMenu.d.ts +2 -2
  210. package/dist/excalidraw/components/LibraryMenuBrowseButton.d.ts +1 -1
  211. package/dist/excalidraw/components/LibraryMenuControlButtons.d.ts +1 -1
  212. package/dist/excalidraw/components/LibraryMenuHeaderContent.d.ts +2 -2
  213. package/dist/excalidraw/components/LibraryMenuItems.d.ts +1 -1
  214. package/dist/excalidraw/components/LibraryMenuSection.d.ts +5 -4
  215. package/dist/excalidraw/components/LibraryUnit.d.ts +2 -2
  216. package/dist/excalidraw/components/LoadingMessage.d.ts +1 -1
  217. package/dist/excalidraw/components/MagicSettings.js +2 -2
  218. package/dist/excalidraw/components/MobileMenu.d.ts +3 -3
  219. package/dist/excalidraw/components/MobileMenu.js +2 -6
  220. package/dist/excalidraw/components/Modal.d.ts +1 -1
  221. package/dist/excalidraw/components/OverwriteConfirm/OverwriteConfirmState.d.ts +1 -1
  222. package/dist/excalidraw/components/PasteChartDialog.d.ts +1 -1
  223. package/dist/excalidraw/components/PasteChartDialog.js +1 -1
  224. package/dist/excalidraw/components/PublishLibrary.d.ts +1 -1
  225. package/dist/excalidraw/components/SVGLayer.d.ts +1 -1
  226. package/dist/excalidraw/components/Sidebar/Sidebar.d.ts +2 -2
  227. package/dist/excalidraw/components/Sidebar/Sidebar.js +1 -1
  228. package/dist/excalidraw/components/Sidebar/SidebarTab.d.ts +1 -1
  229. package/dist/excalidraw/components/Sidebar/SidebarTabTrigger.d.ts +1 -1
  230. package/dist/excalidraw/components/Sidebar/SidebarTrigger.d.ts +1 -1
  231. package/dist/excalidraw/components/Sidebar/common.d.ts +1 -1
  232. package/dist/excalidraw/components/Stack.d.ts +2 -2
  233. package/dist/excalidraw/components/Stats/Angle.d.ts +12 -0
  234. package/dist/excalidraw/components/Stats/Angle.js +52 -0
  235. package/dist/excalidraw/components/Stats/Collapsible.d.ts +9 -0
  236. package/dist/excalidraw/components/Stats/Collapsible.js +12 -0
  237. package/dist/excalidraw/components/Stats/Dimension.d.ts +12 -0
  238. package/dist/excalidraw/components/Stats/Dimension.js +67 -0
  239. package/dist/excalidraw/components/Stats/DragInput.d.ts +32 -0
  240. package/dist/excalidraw/components/Stats/DragInput.js +174 -0
  241. package/dist/excalidraw/components/Stats/FontSize.d.ts +12 -0
  242. package/dist/excalidraw/components/Stats/FontSize.js +50 -0
  243. package/dist/excalidraw/components/Stats/MultiAngle.d.ts +12 -0
  244. package/dist/excalidraw/components/Stats/MultiAngle.js +66 -0
  245. package/dist/excalidraw/components/Stats/MultiDimension.d.ts +15 -0
  246. package/dist/excalidraw/components/Stats/MultiDimension.js +197 -0
  247. package/dist/excalidraw/components/Stats/MultiFontSize.d.ts +13 -0
  248. package/dist/excalidraw/components/Stats/MultiFontSize.js +72 -0
  249. package/dist/excalidraw/components/Stats/MultiPosition.d.ts +15 -0
  250. package/dist/excalidraw/components/Stats/MultiPosition.js +100 -0
  251. package/dist/excalidraw/components/Stats/Position.d.ts +13 -0
  252. package/dist/excalidraw/components/Stats/Position.js +39 -0
  253. package/dist/excalidraw/components/Stats/index.d.ts +16 -0
  254. package/dist/excalidraw/components/Stats/index.js +78 -0
  255. package/dist/excalidraw/components/Stats/utils.d.ts +25 -0
  256. package/dist/excalidraw/components/Stats/utils.js +158 -0
  257. package/dist/excalidraw/components/TTDDialog/MermaidToExcalidraw.d.ts +1 -1
  258. package/dist/excalidraw/components/TTDDialog/TTDDialog.js +2 -2
  259. package/dist/excalidraw/components/TTDDialog/TTDDialogInput.d.ts +1 -1
  260. package/dist/excalidraw/components/TTDDialog/TTDDialogPanel.d.ts +1 -1
  261. package/dist/excalidraw/components/TTDDialog/TTDDialogPanels.d.ts +1 -1
  262. package/dist/excalidraw/components/TTDDialog/TTDDialogTabs.d.ts +1 -1
  263. package/dist/excalidraw/components/TTDDialog/TTDDialogTrigger.d.ts +1 -1
  264. package/dist/excalidraw/components/TTDDialog/common.d.ts +4 -4
  265. package/dist/excalidraw/components/TextField.d.ts +1 -1
  266. package/dist/excalidraw/components/Toast.d.ts +1 -1
  267. package/dist/excalidraw/components/ToolButton.d.ts +4 -2
  268. package/dist/excalidraw/components/ToolButton.js +1 -1
  269. package/dist/excalidraw/components/Trans.d.ts +1 -1
  270. package/dist/excalidraw/components/UserList.d.ts +1 -1
  271. package/dist/excalidraw/components/canvases/InteractiveCanvas.d.ts +5 -3
  272. package/dist/excalidraw/components/canvases/InteractiveCanvas.js +5 -2
  273. package/dist/excalidraw/components/canvases/StaticCanvas.d.ts +2 -2
  274. package/dist/excalidraw/components/canvases/StaticCanvas.js +2 -2
  275. package/dist/excalidraw/components/dropdownMenu/DropdownMenuItem.js +2 -2
  276. package/dist/excalidraw/components/footer/Footer.d.ts +2 -2
  277. package/dist/excalidraw/components/hyperlink/Hyperlink.d.ts +2 -2
  278. package/dist/excalidraw/components/hyperlink/helpers.d.ts +3 -3
  279. package/dist/excalidraw/components/icons.d.ts +6 -2
  280. package/dist/excalidraw/components/icons.js +22 -6
  281. package/dist/excalidraw/constants.d.ts +11 -2
  282. package/dist/excalidraw/constants.js +14 -1
  283. package/dist/excalidraw/context/ui-appState.d.ts +1 -1
  284. package/dist/excalidraw/cursor.d.ts +1 -1
  285. package/dist/excalidraw/data/EditorLocalStorage.d.ts +2 -2
  286. package/dist/excalidraw/data/blob.d.ts +5 -5
  287. package/dist/excalidraw/data/filesystem.d.ts +2 -1
  288. package/dist/excalidraw/data/index.d.ts +4 -4
  289. package/dist/excalidraw/data/json.d.ts +3 -3
  290. package/dist/excalidraw/data/library.d.ts +3 -3
  291. package/dist/excalidraw/data/magic.d.ts +3 -3
  292. package/dist/excalidraw/data/reconcile.d.ts +3 -3
  293. package/dist/excalidraw/data/reconcile.js +1 -1
  294. package/dist/excalidraw/data/resave.d.ts +2 -2
  295. package/dist/excalidraw/data/restore.d.ts +3 -3
  296. package/dist/excalidraw/data/restore.js +17 -2
  297. package/dist/excalidraw/data/transform.d.ts +3 -3
  298. package/dist/excalidraw/data/types.d.ts +3 -3
  299. package/dist/excalidraw/element/ElementCanvasButtons.d.ts +1 -1
  300. package/dist/excalidraw/element/binding.d.ts +48 -20
  301. package/dist/excalidraw/element/binding.js +354 -168
  302. package/dist/excalidraw/element/bounds.d.ts +3 -3
  303. package/dist/excalidraw/element/collision.d.ts +3 -3
  304. package/dist/excalidraw/element/collision.js +1 -1
  305. package/dist/excalidraw/element/containerCache.d.ts +1 -1
  306. package/dist/excalidraw/element/dragElements.d.ts +4 -4
  307. package/dist/excalidraw/element/dragElements.js +27 -3
  308. package/dist/excalidraw/element/embeddable.d.ts +10 -7
  309. package/dist/excalidraw/element/embeddable.js +2 -1
  310. package/dist/excalidraw/element/image.d.ts +2 -2
  311. package/dist/excalidraw/element/index.d.ts +2 -2
  312. package/dist/excalidraw/element/index.js +1 -1
  313. package/dist/excalidraw/element/linearElementEditor.d.ts +10 -7
  314. package/dist/excalidraw/element/linearElementEditor.js +9 -6
  315. package/dist/excalidraw/element/mutateElement.d.ts +3 -4
  316. package/dist/excalidraw/element/mutateElement.js +1 -1
  317. package/dist/excalidraw/element/newElement.d.ts +5 -8
  318. package/dist/excalidraw/element/newElement.js +16 -14
  319. package/dist/excalidraw/element/resizeElements.d.ts +12 -4
  320. package/dist/excalidraw/element/resizeElements.js +174 -98
  321. package/dist/excalidraw/element/resizeTest.d.ts +7 -7
  322. package/dist/excalidraw/element/resizeTest.js +53 -8
  323. package/dist/excalidraw/element/showSelectedShapeActions.d.ts +2 -2
  324. package/dist/excalidraw/element/sizeHelpers.d.ts +2 -2
  325. package/dist/excalidraw/element/sizeHelpers.js +3 -0
  326. package/dist/excalidraw/element/sortElements.d.ts +1 -1
  327. package/dist/excalidraw/element/textElement.d.ts +6 -5
  328. package/dist/excalidraw/element/textElement.js +16 -7
  329. package/dist/excalidraw/element/textWysiwyg.d.ts +12 -6
  330. package/dist/excalidraw/element/textWysiwyg.js +38 -17
  331. package/dist/excalidraw/element/transformHandles.d.ts +24 -6
  332. package/dist/excalidraw/element/transformHandles.js +22 -11
  333. package/dist/excalidraw/element/typeChecks.d.ts +5 -5
  334. package/dist/excalidraw/element/types.d.ts +16 -8
  335. package/dist/excalidraw/emitter.d.ts +1 -1
  336. package/dist/excalidraw/fractionalIndex.d.ts +1 -1
  337. package/dist/excalidraw/fractionalIndex.js +2 -4
  338. package/dist/excalidraw/frame.d.ts +3 -3
  339. package/dist/excalidraw/gatransforms.d.ts +1 -1
  340. package/dist/excalidraw/gesture.d.ts +1 -1
  341. package/dist/excalidraw/groups.d.ts +6 -4
  342. package/dist/excalidraw/groups.js +17 -0
  343. package/dist/excalidraw/history.d.ts +35 -47
  344. package/dist/excalidraw/history.js +100 -167
  345. package/dist/excalidraw/hooks/useEmitter.d.ts +2 -0
  346. package/dist/excalidraw/hooks/useEmitter.js +13 -0
  347. package/dist/excalidraw/hooks/useLibraryItemSvg.d.ts +1 -1
  348. package/dist/excalidraw/i18n.d.ts +1 -1
  349. package/dist/excalidraw/index.d.ts +3 -1
  350. package/dist/excalidraw/index.js +2 -0
  351. package/dist/excalidraw/jotai.d.ts +1 -1
  352. package/dist/excalidraw/laser-trails.d.ts +3 -2
  353. package/dist/excalidraw/locales/en.json +24 -3
  354. package/dist/excalidraw/math.d.ts +4 -2
  355. package/dist/excalidraw/math.js +6 -0
  356. package/dist/excalidraw/mermaid.d.ts +2 -0
  357. package/dist/excalidraw/mermaid.js +28 -0
  358. package/dist/excalidraw/points.d.ts +1 -1
  359. package/dist/excalidraw/queue.d.ts +1 -1
  360. package/dist/excalidraw/renderer/helpers.d.ts +2 -2
  361. package/dist/excalidraw/renderer/interactiveScene.d.ts +2 -2
  362. package/dist/excalidraw/renderer/interactiveScene.js +38 -11
  363. package/dist/excalidraw/renderer/renderElement.d.ts +4 -4
  364. package/dist/excalidraw/renderer/renderElement.js +5 -5
  365. package/dist/excalidraw/renderer/renderSnaps.d.ts +1 -1
  366. package/dist/excalidraw/renderer/staticScene.d.ts +1 -1
  367. package/dist/excalidraw/renderer/staticScene.js +1 -1
  368. package/dist/excalidraw/renderer/staticSvgScene.d.ts +4 -4
  369. package/dist/excalidraw/scene/Fonts.d.ts +2 -4
  370. package/dist/excalidraw/scene/Fonts.js +12 -15
  371. package/dist/excalidraw/scene/Renderer.d.ts +4 -4
  372. package/dist/excalidraw/scene/Renderer.js +2 -3
  373. package/dist/excalidraw/scene/Scene.d.ts +17 -8
  374. package/dist/excalidraw/scene/Scene.js +19 -10
  375. package/dist/excalidraw/scene/Shape.d.ts +1 -1
  376. package/dist/excalidraw/scene/ShapeCache.d.ts +4 -4
  377. package/dist/excalidraw/scene/comparisons.d.ts +2 -2
  378. package/dist/excalidraw/scene/export.d.ts +2 -2
  379. package/dist/excalidraw/scene/export.js +2 -2
  380. package/dist/excalidraw/scene/scroll.d.ts +2 -2
  381. package/dist/excalidraw/scene/scrollbars.d.ts +3 -3
  382. package/dist/excalidraw/scene/selection.d.ts +2 -2
  383. package/dist/excalidraw/scene/types.d.ts +7 -8
  384. package/dist/excalidraw/scene/zoom.d.ts +1 -1
  385. package/dist/excalidraw/shapes.d.ts +7 -0
  386. package/dist/excalidraw/shapes.js +40 -0
  387. package/dist/excalidraw/snapping.d.ts +4 -4
  388. package/dist/excalidraw/snapping.js +2 -1
  389. package/dist/excalidraw/store.d.ts +129 -0
  390. package/dist/excalidraw/store.js +296 -0
  391. package/dist/excalidraw/types.d.ts +38 -20
  392. package/dist/excalidraw/utils.d.ts +10 -4
  393. package/dist/excalidraw/utils.js +7 -0
  394. package/dist/excalidraw/zindex.d.ts +2 -2
  395. package/dist/{dev/en-XW4JO6VX.json → prod/en-EB2MBPAV.json} +24 -3
  396. package/dist/prod/index.css +1 -1
  397. package/dist/prod/index.js +39 -39
  398. package/dist/utils/bbox.d.ts +2 -2
  399. package/dist/utils/collision.d.ts +1 -1
  400. package/dist/utils/export.d.ts +2 -2
  401. package/dist/utils/geometry/geometry.d.ts +1 -1
  402. package/dist/utils/geometry/shape.d.ts +2 -1
  403. package/dist/utils/geometry/shape.js +19 -0
  404. package/dist/utils/withinBounds.d.ts +1 -1
  405. package/history.ts +163 -218
  406. package/package.json +2 -2
  407. package/dist/browser/dev/excalidraw-assets-dev/chunk-WQFMSDPT.js.map +0 -7
  408. package/dist/browser/dev/excalidraw-assets-dev/chunk-XOM7LNOU.js.map +0 -7
  409. package/dist/browser/dev/excalidraw-assets-dev/chunk-Z3PH3V2B.js.map +0 -7
  410. package/dist/browser/dev/excalidraw-assets-dev/dist-Z46EOVOL.js.map +0 -7
  411. package/dist/browser/dev/excalidraw-assets-dev/image-OFRRV5MB.css.map +0 -7
  412. package/dist/browser/prod/excalidraw-assets/chunk-U3COIHDW.js +0 -55
  413. package/dist/browser/prod/excalidraw-assets/dist-PIPZXALV.js +0 -6
  414. package/dist/browser/prod/excalidraw-assets/en-7GPZE2Y2.js +0 -1
  415. package/dist/browser/prod/excalidraw-assets/image-ZLNYKWVQ.js +0 -1
  416. package/dist/excalidraw/components/Stats.d.ts +0 -11
  417. package/dist/excalidraw/components/Stats.js +0 -13
  418. /package/dist/browser/dev/excalidraw-assets-dev/{blockDiagram-91b80b7a-ACFH36JV.js.map → blockDiagram-91b80b7a-H47FTXHA.js.map} +0 -0
  419. /package/dist/browser/dev/excalidraw-assets-dev/{c4Diagram-b2a90758-QZ27YR47.js.map → c4Diagram-b2a90758-NNJK6GKC.js.map} +0 -0
  420. /package/dist/browser/dev/excalidraw-assets-dev/{chunk-HO2HMSK7.js.map → chunk-4KQVEBHW.js.map} +0 -0
  421. /package/dist/browser/dev/excalidraw-assets-dev/{chunk-USGV265L.js.map → chunk-53YI56GV.js.map} +0 -0
  422. /package/dist/browser/dev/excalidraw-assets-dev/{chunk-EDFX3S7X.js.map → chunk-A2WCJI4I.js.map} +0 -0
  423. /package/dist/browser/dev/excalidraw-assets-dev/{chunk-IX4V72YG.js.map → chunk-EFLPX7NE.js.map} +0 -0
  424. /package/dist/browser/dev/excalidraw-assets-dev/{chunk-MXVETLVM.js.map → chunk-JYIQCNWV.js.map} +0 -0
  425. /package/dist/browser/dev/excalidraw-assets-dev/{chunk-YZIOORVX.js.map → chunk-LVIQQW6F.js.map} +0 -0
  426. /package/dist/browser/dev/excalidraw-assets-dev/{chunk-6U7GQNJT.js.map → chunk-PXLO3FOU.js.map} +0 -0
  427. /package/dist/browser/dev/excalidraw-assets-dev/{chunk-7DACDEY3.js.map → chunk-TO2AW5PW.js.map} +0 -0
  428. /package/dist/browser/dev/excalidraw-assets-dev/{chunk-NJ77ZFNJ.js.map → chunk-VURILHLY.js.map} +0 -0
  429. /package/dist/browser/dev/excalidraw-assets-dev/{chunk-2T2GU7NF.js.map → chunk-ZAYGSUHF.js.map} +0 -0
  430. /package/dist/browser/dev/excalidraw-assets-dev/{classDiagram-30eddba6-QSLMH4JW.js.map → classDiagram-30eddba6-CUYIJICN.js.map} +0 -0
  431. /package/dist/browser/dev/excalidraw-assets-dev/{classDiagram-v2-f2df5561-DY4DYQ5P.js.map → classDiagram-v2-f2df5561-K6WW6K73.js.map} +0 -0
  432. /package/dist/browser/dev/excalidraw-assets-dev/{en-TR4QLF5E.js.map → en-AZFA5HJJ.js.map} +0 -0
  433. /package/dist/browser/dev/excalidraw-assets-dev/{erDiagram-47591fe2-SOOJRTCB.js.map → erDiagram-47591fe2-XGAD7EEP.js.map} +0 -0
  434. /package/dist/browser/dev/excalidraw-assets-dev/{flowDiagram-5540d9b9-AHGL4KPK.js.map → flowDiagram-5540d9b9-B6EOVNNO.js.map} +0 -0
  435. /package/dist/browser/dev/excalidraw-assets-dev/{flowDiagram-v2-3b53844e-56LDZZWY.js.map → flowDiagram-v2-3b53844e-NUG24FJH.js.map} +0 -0
  436. /package/dist/browser/dev/excalidraw-assets-dev/{flowchart-elk-definition-5fe447d6-27LUKRI6.js.map → flowchart-elk-definition-5fe447d6-25Y7PCBL.js.map} +0 -0
  437. /package/dist/browser/dev/excalidraw-assets-dev/{ganttDiagram-9a3bba1f-EHGYGNG6.js.map → ganttDiagram-9a3bba1f-GNL6ZDTC.js.map} +0 -0
  438. /package/dist/browser/dev/excalidraw-assets-dev/{gitGraphDiagram-96e6b4ee-AJQNBDW5.js.map → gitGraphDiagram-96e6b4ee-HNW52NVO.js.map} +0 -0
  439. /package/dist/browser/dev/excalidraw-assets-dev/{image-OIPMBJGR.js.map → image-5XCR4WHS.js.map} +0 -0
  440. /package/dist/browser/dev/excalidraw-assets-dev/{infoDiagram-bcd20f53-SWLLQVES.js.map → infoDiagram-bcd20f53-FWEUVFLT.js.map} +0 -0
  441. /package/dist/browser/dev/excalidraw-assets-dev/{journeyDiagram-4fe6b3dc-7UAVCWOZ.js.map → journeyDiagram-4fe6b3dc-RZIUI7UG.js.map} +0 -0
  442. /package/dist/browser/dev/excalidraw-assets-dev/{mindmap-definition-f354de21-SROW5KGM.js.map → mindmap-definition-f354de21-GBVN45GU.js.map} +0 -0
  443. /package/dist/browser/dev/excalidraw-assets-dev/{pieDiagram-79897490-QKCI6NCB.js.map → pieDiagram-79897490-ECENNII6.js.map} +0 -0
  444. /package/dist/browser/dev/excalidraw-assets-dev/{quadrantDiagram-62f64e94-LNYJZFC5.js.map → quadrantDiagram-62f64e94-ZMEOFVNL.js.map} +0 -0
  445. /package/dist/browser/dev/excalidraw-assets-dev/{requirementDiagram-05bf5f74-ZZD7ZHFA.js.map → requirementDiagram-05bf5f74-FHZSFHCR.js.map} +0 -0
  446. /package/dist/browser/dev/excalidraw-assets-dev/{sankeyDiagram-97764748-L75ZZ4UM.js.map → sankeyDiagram-97764748-VDKIKTA6.js.map} +0 -0
  447. /package/dist/browser/dev/excalidraw-assets-dev/{sequenceDiagram-acc0e65c-6PCU7TDK.js.map → sequenceDiagram-acc0e65c-6JUSPVKX.js.map} +0 -0
  448. /package/dist/browser/dev/excalidraw-assets-dev/{stateDiagram-0ff1cf1a-WM76WOPR.js.map → stateDiagram-0ff1cf1a-L3AKWENF.js.map} +0 -0
  449. /package/dist/browser/dev/excalidraw-assets-dev/{stateDiagram-v2-9a9d610d-N4HZW3O2.js.map → stateDiagram-v2-9a9d610d-NU3GGMCH.js.map} +0 -0
  450. /package/dist/browser/dev/excalidraw-assets-dev/{timeline-definition-fea2a41d-ZHGCAXGP.js.map → timeline-definition-fea2a41d-JGP7XCHW.js.map} +0 -0
  451. /package/dist/browser/dev/excalidraw-assets-dev/{xychartDiagram-ab372869-2DLOVRAZ.js.map → xychartDiagram-ab372869-HLFHHF2I.js.map} +0 -0
@@ -6,13 +6,14 @@ import * as GATransform from "../gatransforms";
6
6
  import { getElementAbsoluteCoords } from "./bounds";
7
7
  import { isPointOnShape } from "../../utils/collision";
8
8
  import { getElementAtPosition } from "../scene";
9
- import { isBindableElement, isBindingElement, isLinearElement, } from "./typeChecks";
9
+ import { isArrowElement, isBindableElement, isBindingElement, isBoundToContainer, isLinearElement, isTextElement, } from "./typeChecks";
10
10
  import { mutateElement } from "./mutateElement";
11
11
  import Scene from "../scene/Scene";
12
12
  import { LinearElementEditor } from "./linearElementEditor";
13
13
  import { arrayToMap, tupleToCoors } from "../utils";
14
14
  import { KEYS } from "../keys";
15
15
  import { getBoundTextElement, handleBindTextResize } from "./textElement";
16
+ import { getElementShape } from "../shapes";
16
17
  export const shouldEnableBindingForPointerEvent = (event) => {
17
18
  return !event[KEYS.CTRL_OR_CMD];
18
19
  };
@@ -46,51 +47,125 @@ const bindOrUnbindLinearElementEdge = (linearElement, bindableElement, otherEdge
46
47
  boundToElementIds,
47
48
  // Is mutated
48
49
  unboundFromElementIds, elementsMap) => {
49
- if (bindableElement !== "keep") {
50
- if (bindableElement != null) {
51
- // Don't bind if we're trying to bind or are already bound to the same
52
- // element on the other edge already ("start" edge takes precedence).
53
- if (otherEdgeBindableElement == null ||
54
- (otherEdgeBindableElement === "keep"
55
- ? !isLinearElementSimpleAndAlreadyBoundOnOppositeEdge(linearElement, bindableElement, startOrEnd)
56
- : startOrEnd === "start" ||
57
- otherEdgeBindableElement.id !== bindableElement.id)) {
58
- bindLinearElement(linearElement, bindableElement, startOrEnd, elementsMap);
59
- boundToElementIds.add(bindableElement.id);
60
- }
50
+ // "keep" is for method chaining convenience, a "no-op", so just bail out
51
+ if (bindableElement === "keep") {
52
+ return;
53
+ }
54
+ // null means break the bind, so nothing to consider here
55
+ if (bindableElement === null) {
56
+ const unbound = unbindLinearElement(linearElement, startOrEnd);
57
+ if (unbound != null) {
58
+ unboundFromElementIds.add(unbound);
61
59
  }
62
- else {
63
- const unbound = unbindLinearElement(linearElement, startOrEnd);
64
- if (unbound != null) {
65
- unboundFromElementIds.add(unbound);
66
- }
60
+ return;
61
+ }
62
+ // While complext arrows can do anything, simple arrow with both ends trying
63
+ // to bind to the same bindable should not be allowed, start binding takes
64
+ // precedence
65
+ if (isLinearElementSimple(linearElement)) {
66
+ if (otherEdgeBindableElement == null ||
67
+ (otherEdgeBindableElement === "keep"
68
+ ? // TODO: Refactor - Needlessly complex
69
+ !isLinearElementSimpleAndAlreadyBoundOnOppositeEdge(linearElement, bindableElement, startOrEnd)
70
+ : startOrEnd === "start" ||
71
+ otherEdgeBindableElement.id !== bindableElement.id)) {
72
+ bindLinearElement(linearElement, bindableElement, startOrEnd, elementsMap);
73
+ boundToElementIds.add(bindableElement.id);
67
74
  }
68
75
  }
76
+ else {
77
+ bindLinearElement(linearElement, bindableElement, startOrEnd, elementsMap);
78
+ boundToElementIds.add(bindableElement.id);
79
+ }
69
80
  };
70
- export const bindOrUnbindSelectedElements = (selectedElements, app) => {
71
- selectedElements.forEach((selectedElement) => {
72
- if (isBindingElement(selectedElement)) {
73
- bindOrUnbindLinearElement(selectedElement, getElligibleElementForBindingElement(selectedElement, "start", app), getElligibleElementForBindingElement(selectedElement, "end", app), app.scene.getNonDeletedElementsMap());
74
- }
75
- else if (isBindableElement(selectedElement)) {
76
- maybeBindBindableElement(selectedElement, app.scene.getNonDeletedElementsMap(), app);
81
+ const getOriginalBindingIfStillCloseOfLinearElementEdge = (linearElement, edge, elementsMap) => {
82
+ const coors = getLinearElementEdgeCoors(linearElement, edge, elementsMap);
83
+ const elementId = edge === "start"
84
+ ? linearElement.startBinding?.elementId
85
+ : linearElement.endBinding?.elementId;
86
+ if (elementId) {
87
+ const element = elementsMap.get(elementId);
88
+ if (isBindableElement(element) &&
89
+ bindingBorderTest(element, coors, elementsMap)) {
90
+ return element;
77
91
  }
92
+ }
93
+ return null;
94
+ };
95
+ const getOriginalBindingsIfStillCloseToArrowEnds = (linearElement, elementsMap) => ["start", "end"].map((edge) => getOriginalBindingIfStillCloseOfLinearElementEdge(linearElement, edge, elementsMap));
96
+ const getBindingStrategyForDraggingArrowEndpoints = (selectedElement, isBindingEnabled, draggingPoints, elementsMap) => {
97
+ const startIdx = 0;
98
+ const endIdx = selectedElement.points.length - 1;
99
+ const startDragged = draggingPoints.findIndex((i) => i === startIdx) > -1;
100
+ const endDragged = draggingPoints.findIndex((i) => i === endIdx) > -1;
101
+ const start = startDragged
102
+ ? isBindingEnabled
103
+ ? getElligibleElementForBindingElement(selectedElement, "start", elementsMap)
104
+ : null // If binding is disabled and start is dragged, break all binds
105
+ : // We have to update the focus and gap of the binding, so let's rebind
106
+ getElligibleElementForBindingElement(selectedElement, "start", elementsMap);
107
+ const end = endDragged
108
+ ? isBindingEnabled
109
+ ? getElligibleElementForBindingElement(selectedElement, "end", elementsMap)
110
+ : null // If binding is disabled and end is dragged, break all binds
111
+ : // We have to update the focus and gap of the binding, so let's rebind
112
+ getElligibleElementForBindingElement(selectedElement, "end", elementsMap);
113
+ return [start, end];
114
+ };
115
+ const getBindingStrategyForDraggingArrowOrJoints = (selectedElement, elementsMap, isBindingEnabled) => {
116
+ const [startIsClose, endIsClose] = getOriginalBindingsIfStillCloseToArrowEnds(selectedElement, elementsMap);
117
+ const start = startIsClose
118
+ ? isBindingEnabled
119
+ ? getElligibleElementForBindingElement(selectedElement, "start", elementsMap)
120
+ : null
121
+ : null;
122
+ const end = endIsClose
123
+ ? isBindingEnabled
124
+ ? getElligibleElementForBindingElement(selectedElement, "end", elementsMap)
125
+ : null
126
+ : null;
127
+ return [start, end];
128
+ };
129
+ export const bindOrUnbindLinearElements = (selectedElements, elementsMap, isBindingEnabled, draggingPoints) => {
130
+ selectedElements.forEach((selectedElement) => {
131
+ const [start, end] = draggingPoints?.length
132
+ ? // The arrow edge points are dragged (i.e. start, end)
133
+ getBindingStrategyForDraggingArrowEndpoints(selectedElement, isBindingEnabled, draggingPoints ?? [], elementsMap)
134
+ : // The arrow itself (the shaft) or the inner joins are dragged
135
+ getBindingStrategyForDraggingArrowOrJoints(selectedElement, elementsMap, isBindingEnabled);
136
+ bindOrUnbindLinearElement(selectedElement, start, end, elementsMap);
78
137
  });
79
138
  };
80
- const maybeBindBindableElement = (bindableElement, elementsMap, app) => {
81
- getElligibleElementsForBindableElementAndWhere(bindableElement, app).forEach(([linearElement, where]) => bindOrUnbindLinearElement(linearElement, where === "end" ? "keep" : bindableElement, where === "start" ? "keep" : bindableElement, elementsMap));
82
- };
83
- export const maybeBindLinearElement = (linearElement, appState, pointerCoords, app) => {
139
+ export const getSuggestedBindingsForArrows = (selectedElements, elementsMap) => {
140
+ // HOT PATH: Bail out if selected elements list is too large
141
+ if (selectedElements.length > 50) {
142
+ return [];
143
+ }
144
+ return (selectedElements
145
+ .filter(isLinearElement)
146
+ .flatMap((element) => getOriginalBindingsIfStillCloseToArrowEnds(element, elementsMap))
147
+ .filter((element) => element !== null)
148
+ // Filter out bind candidates which are in the
149
+ // same selection / group with the arrow
150
+ //
151
+ // TODO: Is it worth turning the list into a set to avoid dupes?
152
+ .filter((element) => selectedElements.filter((selected) => selected.id === element?.id)
153
+ .length === 0));
154
+ };
155
+ export const maybeBindLinearElement = (linearElement, appState, pointerCoords, elementsMap) => {
84
156
  if (appState.startBoundElement != null) {
85
- bindLinearElement(linearElement, appState.startBoundElement, "start", app.scene.getNonDeletedElementsMap());
157
+ bindLinearElement(linearElement, appState.startBoundElement, "start", elementsMap);
86
158
  }
87
- const hoveredElement = getHoveredElementForBinding(pointerCoords, app);
159
+ const hoveredElement = getHoveredElementForBinding(pointerCoords, elementsMap);
88
160
  if (hoveredElement != null &&
89
161
  !isLinearElementSimpleAndAlreadyBoundOnOppositeEdge(linearElement, hoveredElement, "end")) {
90
- bindLinearElement(linearElement, hoveredElement, "end", app.scene.getNonDeletedElementsMap());
162
+ bindLinearElement(linearElement, hoveredElement, "end", elementsMap);
91
163
  }
92
164
  };
93
165
  export const bindLinearElement = (linearElement, hoveredElement, startOrEnd, elementsMap) => {
166
+ if (!isArrowElement(linearElement)) {
167
+ return;
168
+ }
94
169
  mutateElement(linearElement, {
95
170
  [startOrEnd === "start" ? "startBinding" : "endBinding"]: {
96
171
  elementId: hoveredElement.id,
@@ -113,15 +188,10 @@ const isLinearElementSimpleAndAlreadyBoundOnOppositeEdge = (linearElement, binda
113
188
  return isLinearElementSimpleAndAlreadyBound(linearElement, otherBinding?.elementId, bindableElement);
114
189
  };
115
190
  export const isLinearElementSimpleAndAlreadyBound = (linearElement, alreadyBoundToId, bindableElement) => {
116
- return (alreadyBoundToId === bindableElement.id && linearElement.points.length < 3);
117
- };
118
- export const unbindLinearElements = (elements, elementsMap) => {
119
- elements.forEach((element) => {
120
- if (isBindingElement(element)) {
121
- bindOrUnbindLinearElement(element, null, null, elementsMap);
122
- }
123
- });
191
+ return (alreadyBoundToId === bindableElement.id &&
192
+ isLinearElementSimple(linearElement));
124
193
  };
194
+ const isLinearElementSimple = (linearElement) => linearElement.points.length < 3;
125
195
  const unbindLinearElement = (linearElement, startOrEnd) => {
126
196
  const field = startOrEnd === "start" ? "startBinding" : "endBinding";
127
197
  const binding = linearElement[field];
@@ -131,9 +201,9 @@ const unbindLinearElement = (linearElement, startOrEnd) => {
131
201
  mutateElement(linearElement, { [field]: null });
132
202
  return binding.elementId;
133
203
  };
134
- export const getHoveredElementForBinding = (pointerCoords, app) => {
135
- const hoveredElement = getElementAtPosition(app.scene.getNonDeletedElements(), (element) => isBindableElement(element, false) &&
136
- bindingBorderTest(element, pointerCoords, app));
204
+ export const getHoveredElementForBinding = (pointerCoords, elementsMap) => {
205
+ const hoveredElement = getElementAtPosition([...elementsMap].map(([_, value]) => value), (element) => isBindableElement(element, false) &&
206
+ bindingBorderTest(element, pointerCoords, elementsMap));
137
207
  return hoveredElement;
138
208
  };
139
209
  const calculateFocusAndGap = (linearElement, hoveredElement, startOrEnd, elementsMap) => {
@@ -153,34 +223,38 @@ const calculateFocusAndGap = (linearElement, hoveredElement, startOrEnd, element
153
223
  // done before the `changedElement` is updated, and the `newSize` is passed
154
224
  // in explicitly.
155
225
  export const updateBoundElements = (changedElement, elementsMap, options) => {
156
- const boundLinearElements = (changedElement.boundElements ?? []).filter((el) => el.type === "arrow");
157
- if (boundLinearElements.length === 0) {
158
- return;
159
- }
160
226
  const { newSize, simultaneouslyUpdated } = options ?? {};
161
227
  const simultaneouslyUpdatedElementIds = getSimultaneouslyUpdatedElementIds(simultaneouslyUpdated);
162
- const scene = Scene.getScene(changedElement);
163
- getNonDeletedElements(scene, boundLinearElements.map((el) => el.id)).forEach((element) => {
164
- if (!isLinearElement(element)) {
228
+ if (!isBindableElement(changedElement)) {
229
+ return;
230
+ }
231
+ boundElementsVisitor(elementsMap, changedElement, (element) => {
232
+ if (!isLinearElement(element) || element.isDeleted) {
165
233
  return;
166
234
  }
167
- const bindableElement = changedElement;
168
235
  // In case the boundElements are stale
169
- if (!doesNeedUpdate(element, bindableElement)) {
236
+ if (!doesNeedUpdate(element, changedElement)) {
170
237
  return;
171
238
  }
172
- const startBinding = maybeCalculateNewGapWhenScaling(bindableElement, element.startBinding, newSize);
173
- const endBinding = maybeCalculateNewGapWhenScaling(bindableElement, element.endBinding, newSize);
239
+ const bindings = {
240
+ startBinding: maybeCalculateNewGapWhenScaling(changedElement, element.startBinding, newSize),
241
+ endBinding: maybeCalculateNewGapWhenScaling(changedElement, element.endBinding, newSize),
242
+ };
174
243
  // `linearElement` is being moved/scaled already, just update the binding
175
244
  if (simultaneouslyUpdatedElementIds.has(element.id)) {
176
- mutateElement(element, { startBinding, endBinding });
245
+ mutateElement(element, bindings);
177
246
  return;
178
247
  }
179
- updateBoundPoint(element, "start", startBinding, changedElement, elementsMap);
180
- updateBoundPoint(element, "end", endBinding, changedElement, elementsMap);
181
- const boundText = getBoundTextElement(element, scene.getNonDeletedElementsMap());
182
- if (boundText) {
183
- handleBindTextResize(element, scene.getNonDeletedElementsMap(), false);
248
+ bindableElementsVisitor(elementsMap, element, (bindableElement, bindingProp) => {
249
+ if (bindableElement &&
250
+ isBindableElement(bindableElement) &&
251
+ (bindingProp === "startBinding" || bindingProp === "endBinding")) {
252
+ updateBoundPoint(element, bindingProp, bindings[bindingProp], bindableElement, elementsMap);
253
+ }
254
+ });
255
+ const boundText = getBoundTextElement(element, elementsMap);
256
+ if (boundText && !boundText.isDeleted) {
257
+ handleBindTextResize(element, elementsMap, false);
184
258
  }
185
259
  });
186
260
  };
@@ -191,22 +265,18 @@ const doesNeedUpdate = (boundElement, changedElement) => {
191
265
  const getSimultaneouslyUpdatedElementIds = (simultaneouslyUpdated) => {
192
266
  return new Set((simultaneouslyUpdated || []).map((element) => element.id));
193
267
  };
194
- const updateBoundPoint = (linearElement, startOrEnd, binding, changedElement, elementsMap) => {
268
+ const updateBoundPoint = (linearElement, startOrEnd, binding, bindableElement, elementsMap) => {
195
269
  if (binding == null ||
196
270
  // We only need to update the other end if this is a 2 point line element
197
- (binding.elementId !== changedElement.id && linearElement.points.length > 2)) {
271
+ (binding.elementId !== bindableElement.id &&
272
+ linearElement.points.length > 2)) {
198
273
  return;
199
274
  }
200
- const bindingElement = Scene.getScene(linearElement).getElement(binding.elementId);
201
- if (bindingElement == null) {
202
- // We're not cleaning up after deleted elements atm., so handle this case
203
- return;
204
- }
205
- const direction = startOrEnd === "start" ? -1 : 1;
275
+ const direction = startOrEnd === "startBinding" ? -1 : 1;
206
276
  const edgePointIndex = direction === -1 ? 0 : linearElement.points.length - 1;
207
277
  const adjacentPointIndex = edgePointIndex - direction;
208
278
  const adjacentPoint = LinearElementEditor.getPointAtIndexGlobalCoordinates(linearElement, adjacentPointIndex, elementsMap);
209
- const focusPointAbsolute = determineFocusPoint(bindingElement, binding.focus, adjacentPoint, elementsMap);
279
+ const focusPointAbsolute = determineFocusPoint(bindableElement, binding.focus, adjacentPoint, elementsMap);
210
280
  let newEdgePoint;
211
281
  // The linear element was not originally pointing inside the bound shape,
212
282
  // we can point directly at the focus point
@@ -214,7 +284,7 @@ const updateBoundPoint = (linearElement, startOrEnd, binding, changedElement, el
214
284
  newEdgePoint = focusPointAbsolute;
215
285
  }
216
286
  else {
217
- const intersections = intersectElementWithLine(bindingElement, adjacentPoint, focusPointAbsolute, binding.gap, elementsMap);
287
+ const intersections = intersectElementWithLine(bindableElement, adjacentPoint, focusPointAbsolute, binding.gap, elementsMap);
218
288
  if (intersections.length === 0) {
219
289
  // This should never happen, since focusPoint should always be
220
290
  // inside the element, but just in case, bail out
@@ -230,7 +300,7 @@ const updateBoundPoint = (linearElement, startOrEnd, binding, changedElement, el
230
300
  index: edgePointIndex,
231
301
  point: LinearElementEditor.pointFromAbsoluteCoords(linearElement, newEdgePoint, elementsMap),
232
302
  },
233
- ], { [startOrEnd === "start" ? "startBinding" : "endBinding"]: binding });
303
+ ], { [startOrEnd]: binding });
234
304
  };
235
305
  const maybeCalculateNewGapWhenScaling = (changedElement, currentBinding, newSize) => {
236
306
  if (currentBinding == null || newSize == null) {
@@ -242,55 +312,13 @@ const maybeCalculateNewGapWhenScaling = (changedElement, currentBinding, newSize
242
312
  const newGap = Math.max(1, Math.min(maxBindingGap(changedElement, newWidth, newHeight), gap * (newWidth < newHeight ? newWidth / width : newHeight / height)));
243
313
  return { elementId, gap: newGap, focus };
244
314
  };
245
- // TODO: this is a bottleneck, optimise
246
- export const getEligibleElementsForBinding = (selectedElements, app) => {
247
- const includedElementIds = new Set(selectedElements.map(({ id }) => id));
248
- return selectedElements.flatMap((selectedElement) => isBindingElement(selectedElement, false)
249
- ? getElligibleElementsForBindingElement(selectedElement, app).filter((element) => !includedElementIds.has(element.id))
250
- : isBindableElement(selectedElement, false)
251
- ? getElligibleElementsForBindableElementAndWhere(selectedElement, app).filter((binding) => !includedElementIds.has(binding[0].id))
252
- : []);
253
- };
254
- const getElligibleElementsForBindingElement = (linearElement, app) => {
255
- return [
256
- getElligibleElementForBindingElement(linearElement, "start", app),
257
- getElligibleElementForBindingElement(linearElement, "end", app),
258
- ].filter((element) => element != null);
259
- };
260
- const getElligibleElementForBindingElement = (linearElement, startOrEnd, app) => {
261
- return getHoveredElementForBinding(getLinearElementEdgeCoors(linearElement, startOrEnd, app.scene.getNonDeletedElementsMap()), app);
315
+ const getElligibleElementForBindingElement = (linearElement, startOrEnd, elementsMap) => {
316
+ return getHoveredElementForBinding(getLinearElementEdgeCoors(linearElement, startOrEnd, elementsMap), elementsMap);
262
317
  };
263
318
  const getLinearElementEdgeCoors = (linearElement, startOrEnd, elementsMap) => {
264
319
  const index = startOrEnd === "start" ? 0 : -1;
265
320
  return tupleToCoors(LinearElementEditor.getPointAtIndexGlobalCoordinates(linearElement, index, elementsMap));
266
321
  };
267
- const getElligibleElementsForBindableElementAndWhere = (bindableElement, app) => {
268
- const scene = Scene.getScene(bindableElement);
269
- return scene
270
- .getNonDeletedElements()
271
- .map((element) => {
272
- if (!isBindingElement(element, false)) {
273
- return null;
274
- }
275
- const canBindStart = isLinearElementEligibleForNewBindingByBindable(element, "start", bindableElement, scene.getNonDeletedElementsMap(), app);
276
- const canBindEnd = isLinearElementEligibleForNewBindingByBindable(element, "end", bindableElement, scene.getNonDeletedElementsMap(), app);
277
- if (!canBindStart && !canBindEnd) {
278
- return null;
279
- }
280
- return [
281
- element,
282
- canBindStart && canBindEnd ? "both" : canBindStart ? "start" : "end",
283
- bindableElement,
284
- ];
285
- })
286
- .filter((maybeElement) => maybeElement != null);
287
- };
288
- const isLinearElementEligibleForNewBindingByBindable = (linearElement, startOrEnd, bindableElement, elementsMap, app) => {
289
- const existingBinding = linearElement[startOrEnd === "start" ? "startBinding" : "endBinding"];
290
- return (existingBinding == null &&
291
- !isLinearElementSimpleAndAlreadyBoundOnOppositeEdge(linearElement, bindableElement, startOrEnd) &&
292
- bindingBorderTest(bindableElement, getLinearElementEdgeCoors(linearElement, startOrEnd, elementsMap), app));
293
- };
294
322
  // We need to:
295
323
  // 1: Update elements not selected to point to duplicated elements
296
324
  // 2: Update duplicated elements to point to other duplicated elements
@@ -305,6 +333,7 @@ duplicatesServeAsOld) => {
305
333
  const allBoundElementIds = new Set();
306
334
  const allBindableElementIds = new Set();
307
335
  const shouldReverseRoles = duplicatesServeAsOld === "duplicatesServeAsOld";
336
+ const duplicateIdToOldId = new Map([...oldIdToDuplicatedId].map(([key, value]) => [value, key]));
308
337
  oldElements.forEach((oldElement) => {
309
338
  const { boundElements } = oldElement;
310
339
  if (boundElements != null && boundElements.length > 0) {
@@ -345,7 +374,8 @@ duplicatesServeAsOld) => {
345
374
  sceneElements
346
375
  .filter(({ id }) => allBindableElementIds.has(id))
347
376
  .forEach((bindableElement) => {
348
- const { boundElements } = bindableElement;
377
+ const oldElementId = duplicateIdToOldId.get(bindableElement.id);
378
+ const { boundElements } = sceneElements.find(({ id }) => id === oldElementId);
349
379
  if (boundElements != null && boundElements.length > 0) {
350
380
  mutateElement(bindableElement, {
351
381
  boundElements: boundElements.map((boundElement) => oldIdToDuplicatedId.has(boundElement.id)
@@ -370,57 +400,23 @@ const newBindingAfterDuplication = (binding, oldIdToDuplicatedId) => {
370
400
  };
371
401
  };
372
402
  export const fixBindingsAfterDeletion = (sceneElements, deletedElements) => {
373
- const deletedElementIds = new Set(deletedElements.map((element) => element.id));
374
- // non-deleted which bindings need to be updated
375
- const affectedElements = new Set();
376
- deletedElements.forEach((deletedElement) => {
377
- if (isBindableElement(deletedElement)) {
378
- deletedElement.boundElements?.forEach((element) => {
379
- if (!deletedElementIds.has(element.id)) {
380
- affectedElements.add(element.id);
381
- }
382
- });
383
- }
384
- else if (isBindingElement(deletedElement)) {
385
- if (deletedElement.startBinding) {
386
- affectedElements.add(deletedElement.startBinding.elementId);
387
- }
388
- if (deletedElement.endBinding) {
389
- affectedElements.add(deletedElement.endBinding.elementId);
390
- }
391
- }
392
- });
393
- sceneElements
394
- .filter(({ id }) => affectedElements.has(id))
395
- .forEach((element) => {
396
- if (isBindableElement(element)) {
397
- mutateElement(element, {
398
- boundElements: newBoundElementsAfterDeletion(element.boundElements, deletedElementIds),
399
- });
400
- }
401
- else if (isBindingElement(element)) {
402
- mutateElement(element, {
403
- startBinding: newBindingAfterDeletion(element.startBinding, deletedElementIds),
404
- endBinding: newBindingAfterDeletion(element.endBinding, deletedElementIds),
405
- });
406
- }
407
- });
408
- };
409
- const newBindingAfterDeletion = (binding, deletedElementIds) => {
410
- if (binding == null || deletedElementIds.has(binding.elementId)) {
411
- return null;
403
+ const elements = arrayToMap(sceneElements);
404
+ for (const element of deletedElements) {
405
+ BoundElement.unbindAffected(elements, element, mutateElement);
406
+ BindableElement.unbindAffected(elements, element, mutateElement);
412
407
  }
413
- return binding;
414
408
  };
415
- const newBoundElementsAfterDeletion = (boundElements, deletedElementIds) => {
409
+ const newBoundElements = (boundElements, idsToRemove, elementsToAdd = []) => {
416
410
  if (!boundElements) {
417
411
  return null;
418
412
  }
419
- return boundElements.filter((ele) => !deletedElementIds.has(ele.id));
413
+ const nextBoundElements = boundElements.filter((boundElement) => !idsToRemove.has(boundElement.id));
414
+ nextBoundElements.push(...elementsToAdd.map((x) => ({ id: x.id, type: x.type })));
415
+ return nextBoundElements;
420
416
  };
421
- export const bindingBorderTest = (element, { x, y }, app) => {
417
+ const bindingBorderTest = (element, { x, y }, elementsMap) => {
422
418
  const threshold = maxBindingGap(element, element.width, element.height);
423
- const shape = app.getElementShape(element);
419
+ const shape = getElementShape(element, elementsMap);
424
420
  return isPointOnShape([x, y], shape, threshold);
425
421
  };
426
422
  export const maxBindingGap = (element, elementWidth, elementHeight) => {
@@ -430,7 +426,7 @@ export const maxBindingGap = (element, elementWidth, elementHeight) => {
430
426
  // We make the bindable boundary bigger for bigger elements
431
427
  return Math.max(16, Math.min(0.25 * smallerDimension, 32));
432
428
  };
433
- export const distanceToBindableElement = (element, point, elementsMap) => {
429
+ const distanceToBindableElement = (element, point, elementsMap) => {
434
430
  switch (element.type) {
435
431
  case "rectangle":
436
432
  case "image":
@@ -455,7 +451,7 @@ const distanceToDiamond = (element, point, elementsMap) => {
455
451
  const side = GALine.equation(hheight, hwidth, -hheight * hwidth);
456
452
  return GAPoint.distanceToLine(pointRel, side);
457
453
  };
458
- export const distanceToEllipse = (element, point, elementsMap) => {
454
+ const distanceToEllipse = (element, point, elementsMap) => {
459
455
  const [pointRel, tangent] = ellipseParamsForTest(element, point, elementsMap);
460
456
  return -GALine.sign(tangent) * GAPoint.distanceToLine(pointRel, tangent);
461
457
  };
@@ -533,7 +529,7 @@ const coordsCenter = (x1, y1, x2, y2) => {
533
529
  // all focus points lie, so it's a number between -1 and 1.
534
530
  // The line going through `a` and `b` is a tangent to the "focus image"
535
531
  // of the element.
536
- export const determineFocusDistance = (element,
532
+ const determineFocusDistance = (element,
537
533
  // Point on the line, in absolute coordinates
538
534
  a,
539
535
  // Another point on the line, in absolute coordinates (closer to element)
@@ -570,7 +566,7 @@ b, elementsMap) => {
570
566
  }
571
567
  return ret || 0;
572
568
  };
573
- export const determineFocusPoint = (element,
569
+ const determineFocusPoint = (element,
574
570
  // The oriented, relative distance from the center of `element` of the
575
571
  // returned focusPoint
576
572
  focus, adjecentPoint, elementsMap) => {
@@ -602,7 +598,7 @@ focus, adjecentPoint, elementsMap) => {
602
598
  };
603
599
  // Returns 2 or 0 intersection points between line going through `a` and `b`
604
600
  // and the `element`, in ascending order of distance from `a`.
605
- export const intersectElementWithLine = (element,
601
+ const intersectElementWithLine = (element,
606
602
  // Point on the line, in absolute coordinates
607
603
  a,
608
604
  // Another point on the line, in absolute coordinates
@@ -717,7 +713,7 @@ const getEllipseIntersections = (element, gap, line) => {
717
713
  GA.point((xn - a * b * n * discrRoot) / squares, (yn + a * b * m * discrRoot) / squares),
718
714
  ];
719
715
  };
720
- export const getCircleIntersections = (center, radius, line) => {
716
+ const getCircleIntersections = (center, radius, line) => {
721
717
  if (radius === 0) {
722
718
  return GAPoint.distanceToLine(line, center) === 0 ? [center] : [];
723
719
  }
@@ -741,7 +737,7 @@ export const getCircleIntersections = (center, radius, line) => {
741
737
  };
742
738
  // The focus point is the tangent point of the "focus image" of the
743
739
  // `element`, where the tangent goes through `point`.
744
- export const findFocusPointForEllipse = (ellipse,
740
+ const findFocusPointForEllipse = (ellipse,
745
741
  // Between -1 and 1 (not 0) the relative size of the "focus image" of
746
742
  // the element on which the focus point lies
747
743
  relativeDistance,
@@ -768,7 +764,7 @@ point) => {
768
764
  const x = -(a ** 2 * m) / (n ** 2 * b ** 2 + m ** 2 * a ** 2);
769
765
  return GA.point(x, (-m * x - 1) / n);
770
766
  };
771
- export const findFocusPointForRectangulars = (element,
767
+ const findFocusPointForRectangulars = (element,
772
768
  // Between -1 and 1 for how far away should the focus point be relative
773
769
  // to the size of the element. Sign determines orientation.
774
770
  relativeDistance,
@@ -789,3 +785,193 @@ point) => {
789
785
  });
790
786
  return tangentPoint;
791
787
  };
788
+ export const bindingProperties = new Set([
789
+ "boundElements",
790
+ "frameId",
791
+ "containerId",
792
+ "startBinding",
793
+ "endBinding",
794
+ ]);
795
+ /**
796
+ * Tries to visit each bound element (does not have to be found).
797
+ */
798
+ const boundElementsVisitor = (elements, element, visit) => {
799
+ if (isBindableElement(element)) {
800
+ // create new instance so that possible mutations won't play a role in visiting order
801
+ const boundElements = element.boundElements?.slice() ?? [];
802
+ // last added text should be the one we keep (~previous are duplicates)
803
+ boundElements.forEach(({ id }) => {
804
+ visit(elements.get(id), "boundElements", id);
805
+ });
806
+ }
807
+ };
808
+ /**
809
+ * Tries to visit each bindable element (does not have to be found).
810
+ */
811
+ const bindableElementsVisitor = (elements, element, visit) => {
812
+ if (element.frameId) {
813
+ const id = element.frameId;
814
+ visit(elements.get(id), "frameId", id);
815
+ }
816
+ if (isBoundToContainer(element)) {
817
+ const id = element.containerId;
818
+ visit(elements.get(id), "containerId", id);
819
+ }
820
+ if (isArrowElement(element)) {
821
+ if (element.startBinding) {
822
+ const id = element.startBinding.elementId;
823
+ visit(elements.get(id), "startBinding", id);
824
+ }
825
+ if (element.endBinding) {
826
+ const id = element.endBinding.elementId;
827
+ visit(elements.get(id), "endBinding", id);
828
+ }
829
+ }
830
+ };
831
+ /**
832
+ * Bound element containing bindings to `frameId`, `containerId`, `startBinding` or `endBinding`.
833
+ */
834
+ export class BoundElement {
835
+ /**
836
+ * Unbind the affected non deleted bindable elements (removing element from `boundElements`).
837
+ * - iterates non deleted bindable elements (`containerId` | `startBinding.elementId` | `endBinding.elementId`) of the current element
838
+ * - prepares updates to unbind each bindable element's `boundElements` from the current element
839
+ */
840
+ static unbindAffected(elements, boundElement, updateElementWith) {
841
+ if (!boundElement) {
842
+ return;
843
+ }
844
+ bindableElementsVisitor(elements, boundElement, (bindableElement) => {
845
+ // bindable element is deleted, this is fine
846
+ if (!bindableElement || bindableElement.isDeleted) {
847
+ return;
848
+ }
849
+ boundElementsVisitor(elements, bindableElement, (_, __, boundElementId) => {
850
+ if (boundElementId === boundElement.id) {
851
+ updateElementWith(bindableElement, {
852
+ boundElements: newBoundElements(bindableElement.boundElements, new Set([boundElementId])),
853
+ });
854
+ }
855
+ });
856
+ });
857
+ }
858
+ /**
859
+ * Rebind the next affected non deleted bindable elements (adding element to `boundElements`).
860
+ * - iterates non deleted bindable elements (`containerId` | `startBinding.elementId` | `endBinding.elementId`) of the current element
861
+ * - prepares updates to rebind each bindable element's `boundElements` to the current element
862
+ *
863
+ * NOTE: rebind expects that affected elements were previously unbound with `BoundElement.unbindAffected`
864
+ */
865
+ static rebindAffected = (elements, boundElement, updateElementWith) => {
866
+ // don't try to rebind element that is deleted
867
+ if (!boundElement || boundElement.isDeleted) {
868
+ return;
869
+ }
870
+ bindableElementsVisitor(elements, boundElement, (bindableElement, bindingProp) => {
871
+ // unbind from bindable elements, as bindings from non deleted elements into deleted elements are incorrect
872
+ if (!bindableElement || bindableElement.isDeleted) {
873
+ updateElementWith(boundElement, { [bindingProp]: null });
874
+ return;
875
+ }
876
+ // frame bindings are unidirectional, there is nothing to rebind
877
+ if (bindingProp === "frameId") {
878
+ return;
879
+ }
880
+ if (bindableElement.boundElements?.find((x) => x.id === boundElement.id)) {
881
+ return;
882
+ }
883
+ if (isArrowElement(boundElement)) {
884
+ // rebind if not found!
885
+ updateElementWith(bindableElement, {
886
+ boundElements: newBoundElements(bindableElement.boundElements, new Set(), new Array(boundElement)),
887
+ });
888
+ }
889
+ if (isTextElement(boundElement)) {
890
+ if (!bindableElement.boundElements?.find((x) => x.type === "text")) {
891
+ // rebind only if there is no other text bound already
892
+ updateElementWith(bindableElement, {
893
+ boundElements: newBoundElements(bindableElement.boundElements, new Set(), new Array(boundElement)),
894
+ });
895
+ }
896
+ else {
897
+ // unbind otherwise
898
+ updateElementWith(boundElement, { [bindingProp]: null });
899
+ }
900
+ }
901
+ });
902
+ };
903
+ }
904
+ /**
905
+ * Bindable element containing bindings to `boundElements`.
906
+ */
907
+ export class BindableElement {
908
+ /**
909
+ * Unbind the affected non deleted bound elements (resetting `containerId`, `startBinding`, `endBinding` to `null`).
910
+ * - iterates through non deleted `boundElements` of the current element
911
+ * - prepares updates to unbind each bound element from the current element
912
+ */
913
+ static unbindAffected(elements, bindableElement, updateElementWith) {
914
+ if (!bindableElement) {
915
+ return;
916
+ }
917
+ boundElementsVisitor(elements, bindableElement, (boundElement) => {
918
+ // bound element is deleted, this is fine
919
+ if (!boundElement || boundElement.isDeleted) {
920
+ return;
921
+ }
922
+ bindableElementsVisitor(elements, boundElement, (_, bindingProp, bindableElementId) => {
923
+ // making sure there is an element to be unbound
924
+ if (bindableElementId === bindableElement.id) {
925
+ updateElementWith(boundElement, { [bindingProp]: null });
926
+ }
927
+ });
928
+ });
929
+ }
930
+ /**
931
+ * Rebind the affected non deleted bound elements (for now setting only `containerId`, as we cannot rebind arrows atm).
932
+ * - iterates through non deleted `boundElements` of the current element
933
+ * - prepares updates to rebind each bound element to the current element or unbind it from `boundElements` in case of conflicts
934
+ *
935
+ * NOTE: rebind expects that affected elements were previously unbound with `BindaleElement.unbindAffected`
936
+ */
937
+ static rebindAffected = (elements, bindableElement, updateElementWith) => {
938
+ // don't try to rebind element that is deleted (i.e. updated as deleted)
939
+ if (!bindableElement || bindableElement.isDeleted) {
940
+ return;
941
+ }
942
+ boundElementsVisitor(elements, bindableElement, (boundElement, _, boundElementId) => {
943
+ // unbind from bindable elements, as bindings from non deleted elements into deleted elements are incorrect
944
+ if (!boundElement || boundElement.isDeleted) {
945
+ updateElementWith(bindableElement, {
946
+ boundElements: newBoundElements(bindableElement.boundElements, new Set([boundElementId])),
947
+ });
948
+ return;
949
+ }
950
+ if (isTextElement(boundElement)) {
951
+ const boundElements = bindableElement.boundElements?.slice() ?? [];
952
+ // check if this is the last element in the array, if not, there is an previously bound text which should be unbound
953
+ if (boundElements.reverse().find((x) => x.type === "text")?.id ===
954
+ boundElement.id) {
955
+ if (boundElement.containerId !== bindableElement.id) {
956
+ // rebind if not bound already!
957
+ updateElementWith(boundElement, {
958
+ containerId: bindableElement.id,
959
+ });
960
+ }
961
+ }
962
+ else {
963
+ if (boundElement.containerId !== null) {
964
+ // unbind if not unbound already
965
+ updateElementWith(boundElement, {
966
+ containerId: null,
967
+ });
968
+ }
969
+ // unbind from boundElements as the element got bound to some other element in the meantime
970
+ updateElementWith(bindableElement, {
971
+ boundElements: newBoundElements(bindableElement.boundElements, new Set([boundElement.id])),
972
+ });
973
+ }
974
+ }
975
+ });
976
+ };
977
+ }