@excalidraw/excalidraw 0.17.1-550a388 → 0.17.1-62228e0

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 (552) hide show
  1. package/CHANGELOG.md +18 -2
  2. package/dist/browser/dev/excalidraw-assets-dev/CascadiaMono-Regular-NWCXRPUG.woff2 +0 -0
  3. package/dist/browser/dev/excalidraw-assets-dev/ComicShanns-Regular-6TOETDFT.woff2 +0 -0
  4. package/dist/browser/dev/excalidraw-assets-dev/Excalifont-Regular-CPKEUDVM.woff2 +0 -0
  5. package/dist/browser/dev/excalidraw-assets-dev/LiberationSans-Regular-ZQD73GJM.woff2 +0 -0
  6. package/dist/browser/dev/excalidraw-assets-dev/Virgil-Regular-YHAB2VGJ.woff2 +0 -0
  7. package/dist/browser/dev/excalidraw-assets-dev/{blockDiagram-91b80b7a-ACFH36JV.js → blockDiagram-91b80b7a-H47FTXHA.js} +5 -5
  8. package/dist/browser/dev/excalidraw-assets-dev/{c4Diagram-b2a90758-QZ27YR47.js → c4Diagram-b2a90758-NNJK6GKC.js} +3 -3
  9. package/dist/browser/dev/excalidraw-assets-dev/{chunk-HO2HMSK7.js → chunk-4KQVEBHW.js} +3 -3
  10. package/dist/browser/dev/excalidraw-assets-dev/{chunk-USGV265L.js → chunk-53YI56GV.js} +4 -4
  11. package/dist/browser/dev/excalidraw-assets-dev/{chunk-EDFX3S7X.js → chunk-A2WCJI4I.js} +3 -3
  12. package/dist/browser/dev/excalidraw-assets-dev/{chunk-IX4V72YG.js → chunk-EFLPX7NE.js} +6 -6
  13. package/dist/browser/dev/excalidraw-assets-dev/{chunk-MXVETLVM.js → chunk-JYIQCNWV.js} +2 -2
  14. package/dist/browser/dev/excalidraw-assets-dev/{chunk-YZIOORVX.js → chunk-LVIQQW6F.js} +2 -2
  15. package/dist/browser/dev/excalidraw-assets-dev/{chunk-6U7GQNJT.js → chunk-PXLO3FOU.js} +2 -2
  16. package/dist/browser/dev/excalidraw-assets-dev/{chunk-7DACDEY3.js → chunk-TO2AW5PW.js} +2 -2
  17. package/dist/browser/dev/excalidraw-assets-dev/{chunk-NJ77ZFNJ.js → chunk-VURILHLY.js} +2 -2
  18. package/dist/browser/dev/excalidraw-assets-dev/{chunk-AK7SWNLN.js → chunk-XDYNNNIZ.js} +48 -10
  19. package/dist/browser/dev/excalidraw-assets-dev/chunk-XDYNNNIZ.js.map +7 -0
  20. package/dist/browser/dev/excalidraw-assets-dev/{chunk-2T2GU7NF.js → chunk-ZAYGSUHF.js} +2 -2
  21. package/dist/browser/dev/excalidraw-assets-dev/{chunk-Z3PH3V2B.js → chunk-ZQR5ML6Y.js} +26 -26
  22. package/dist/browser/dev/excalidraw-assets-dev/chunk-ZQR5ML6Y.js.map +7 -0
  23. package/dist/browser/dev/excalidraw-assets-dev/{chunk-RWZVJAQU.js → chunk-ZYC7SDAJ.js} +13172 -7476
  24. package/dist/browser/dev/excalidraw-assets-dev/chunk-ZYC7SDAJ.js.map +7 -0
  25. package/dist/browser/dev/excalidraw-assets-dev/{classDiagram-30eddba6-QSLMH4JW.js → classDiagram-30eddba6-CUYIJICN.js} +5 -5
  26. package/dist/browser/dev/excalidraw-assets-dev/{classDiagram-v2-f2df5561-DY4DYQ5P.js → classDiagram-v2-f2df5561-K6WW6K73.js} +8 -8
  27. package/dist/browser/dev/excalidraw-assets-dev/{dist-Z46EOVOL.js → dist-DNSPZDOZ.js} +67 -33
  28. package/dist/browser/dev/excalidraw-assets-dev/dist-DNSPZDOZ.js.map +7 -0
  29. package/dist/browser/dev/excalidraw-assets-dev/{en-5TCZHGGJ.js → en-RAFN4KPD.js} +8 -2
  30. package/dist/browser/dev/excalidraw-assets-dev/{erDiagram-47591fe2-SOOJRTCB.js → erDiagram-47591fe2-XGAD7EEP.js} +4 -4
  31. package/dist/browser/dev/excalidraw-assets-dev/{flowDiagram-5540d9b9-AHGL4KPK.js → flowDiagram-5540d9b9-B6EOVNNO.js} +9 -9
  32. package/dist/browser/dev/excalidraw-assets-dev/{flowDiagram-v2-3b53844e-56LDZZWY.js → flowDiagram-v2-3b53844e-NUG24FJH.js} +9 -9
  33. package/dist/browser/dev/excalidraw-assets-dev/{flowchart-elk-definition-5fe447d6-27LUKRI6.js → flowchart-elk-definition-5fe447d6-25Y7PCBL.js} +5 -5
  34. package/dist/browser/dev/excalidraw-assets-dev/{ganttDiagram-9a3bba1f-EHGYGNG6.js → ganttDiagram-9a3bba1f-GNL6ZDTC.js} +2 -2
  35. package/dist/browser/dev/excalidraw-assets-dev/{gitGraphDiagram-96e6b4ee-AJQNBDW5.js → gitGraphDiagram-96e6b4ee-HNW52NVO.js} +2 -2
  36. package/dist/browser/dev/excalidraw-assets-dev/{image-OFRRV5MB.css → image-WDHYGKKP.css} +1 -1
  37. package/dist/browser/dev/excalidraw-assets-dev/image-WDHYGKKP.css.map +7 -0
  38. package/dist/browser/dev/excalidraw-assets-dev/{image-EDKQZH7Z.js → image-ZNLDWTK3.js} +2 -2
  39. package/dist/browser/dev/excalidraw-assets-dev/{infoDiagram-bcd20f53-SWLLQVES.js → infoDiagram-bcd20f53-FWEUVFLT.js} +2 -2
  40. package/dist/browser/dev/excalidraw-assets-dev/{journeyDiagram-4fe6b3dc-7UAVCWOZ.js → journeyDiagram-4fe6b3dc-RZIUI7UG.js} +3 -3
  41. package/dist/browser/dev/excalidraw-assets-dev/{mindmap-definition-f354de21-SROW5KGM.js → mindmap-definition-f354de21-GBVN45GU.js} +3 -3
  42. package/dist/browser/dev/excalidraw-assets-dev/{pieDiagram-79897490-QKCI6NCB.js → pieDiagram-79897490-ECENNII6.js} +2 -2
  43. package/dist/browser/dev/excalidraw-assets-dev/{quadrantDiagram-62f64e94-LNYJZFC5.js → quadrantDiagram-62f64e94-ZMEOFVNL.js} +2 -2
  44. package/dist/browser/dev/excalidraw-assets-dev/{requirementDiagram-05bf5f74-ZZD7ZHFA.js → requirementDiagram-05bf5f74-FHZSFHCR.js} +4 -4
  45. package/dist/browser/dev/excalidraw-assets-dev/{sankeyDiagram-97764748-L75ZZ4UM.js → sankeyDiagram-97764748-VDKIKTA6.js} +2 -2
  46. package/dist/browser/dev/excalidraw-assets-dev/{sequenceDiagram-acc0e65c-6PCU7TDK.js → sequenceDiagram-acc0e65c-6JUSPVKX.js} +3 -3
  47. package/dist/browser/dev/excalidraw-assets-dev/{stateDiagram-0ff1cf1a-WM76WOPR.js → stateDiagram-0ff1cf1a-L3AKWENF.js} +5 -5
  48. package/dist/browser/dev/excalidraw-assets-dev/{stateDiagram-v2-9a9d610d-N4HZW3O2.js → stateDiagram-v2-9a9d610d-NU3GGMCH.js} +8 -8
  49. package/dist/browser/dev/excalidraw-assets-dev/{timeline-definition-fea2a41d-ZHGCAXGP.js → timeline-definition-fea2a41d-JGP7XCHW.js} +2 -2
  50. package/dist/browser/dev/excalidraw-assets-dev/{xychartDiagram-ab372869-2DLOVRAZ.js → xychartDiagram-ab372869-HLFHHF2I.js} +3 -3
  51. package/dist/browser/dev/index.css +668 -191
  52. package/dist/browser/dev/index.css.map +3 -3
  53. package/dist/browser/dev/index.js +14529 -9273
  54. package/dist/browser/dev/index.js.map +4 -4
  55. package/dist/browser/prod/excalidraw-assets/CascadiaMono-Regular-NWCXRPUG.woff2 +0 -0
  56. package/dist/browser/prod/excalidraw-assets/ComicShanns-Regular-6TOETDFT.woff2 +0 -0
  57. package/dist/browser/prod/excalidraw-assets/Excalifont-Regular-CPKEUDVM.woff2 +0 -0
  58. package/dist/browser/prod/excalidraw-assets/LiberationSans-Regular-ZQD73GJM.woff2 +0 -0
  59. package/dist/browser/prod/excalidraw-assets/Virgil-Regular-YHAB2VGJ.woff2 +0 -0
  60. package/dist/browser/prod/excalidraw-assets/{blockDiagram-91b80b7a-ONPS22AM.js → blockDiagram-91b80b7a-FVCRVGN5.js} +1 -1
  61. package/dist/browser/prod/excalidraw-assets/{c4Diagram-b2a90758-XMIQY7ZT.js → c4Diagram-b2a90758-56CXO7GA.js} +1 -1
  62. package/dist/browser/prod/excalidraw-assets/{chunk-GCHQBOKV.js → chunk-635MQ3CK.js} +1 -1
  63. package/dist/browser/prod/excalidraw-assets/{chunk-P5M3G2RP.js → chunk-AIKXYJX3.js} +1 -1
  64. package/dist/browser/prod/excalidraw-assets/{chunk-E2YLWFZX.js → chunk-CR7VMNWC.js} +1 -1
  65. package/dist/browser/prod/excalidraw-assets/chunk-F3JN4YS2.js +61 -0
  66. package/dist/browser/prod/excalidraw-assets/{chunk-WEYK4A2L.js → chunk-FFF2CSVG.js} +1 -1
  67. package/dist/browser/prod/excalidraw-assets/{chunk-R3HAIP6R.js → chunk-G4WDCSPE.js} +1 -1
  68. package/dist/browser/prod/excalidraw-assets/{chunk-HFOXJM22.js → chunk-HKZSHFLX.js} +1 -1
  69. package/dist/browser/prod/excalidraw-assets/{chunk-XIMFFJTE.js → chunk-IKCDYWMW.js} +1 -1
  70. package/dist/browser/prod/excalidraw-assets/{chunk-AHLLBBVJ.js → chunk-L5DS24G6.js} +1 -1
  71. package/dist/browser/prod/excalidraw-assets/{chunk-CQJF3C6G.js → chunk-MUNOKHUD.js} +1 -1
  72. package/dist/browser/prod/excalidraw-assets/{chunk-CTYINSWT.js → chunk-MXFM2KIK.js} +5 -5
  73. package/dist/browser/prod/excalidraw-assets/{chunk-NI6SYCUG.js → chunk-QOQYOOQ4.js} +1 -1
  74. package/dist/browser/prod/excalidraw-assets/{chunk-I2PZFXTK.js → chunk-ZTIWFPBM.js} +21 -21
  75. package/dist/browser/prod/excalidraw-assets/{classDiagram-30eddba6-IEJXXCVX.js → classDiagram-30eddba6-BCUTAUMD.js} +1 -1
  76. package/dist/browser/prod/excalidraw-assets/{classDiagram-v2-f2df5561-7LZDSWOS.js → classDiagram-v2-f2df5561-6SOXSGQ2.js} +1 -1
  77. package/dist/browser/prod/excalidraw-assets/dist-NLUQPPQQ.js +7 -0
  78. package/dist/browser/prod/excalidraw-assets/en-SQSS4H2K.js +1 -0
  79. package/dist/browser/prod/excalidraw-assets/{erDiagram-47591fe2-E5V666CF.js → erDiagram-47591fe2-RE6HB7RM.js} +1 -1
  80. package/dist/browser/prod/excalidraw-assets/{flowDiagram-5540d9b9-GMBRCYVF.js → flowDiagram-5540d9b9-ZNJZBERW.js} +1 -1
  81. package/dist/browser/prod/excalidraw-assets/{flowDiagram-v2-3b53844e-Z4HUWP6B.js → flowDiagram-v2-3b53844e-LY44JLQJ.js} +1 -1
  82. package/dist/browser/prod/excalidraw-assets/{flowchart-elk-definition-5fe447d6-5ZCYTX5N.js → flowchart-elk-definition-5fe447d6-TMTJ6Z7O.js} +1 -1
  83. package/dist/browser/prod/excalidraw-assets/{ganttDiagram-9a3bba1f-WM32OMT5.js → ganttDiagram-9a3bba1f-5O6EA6LX.js} +1 -1
  84. package/dist/browser/prod/excalidraw-assets/{gitGraphDiagram-96e6b4ee-CAKZ2U6E.js → gitGraphDiagram-96e6b4ee-UHYNM5DI.js} +1 -1
  85. package/dist/browser/prod/excalidraw-assets/image-CMH7O36X.js +1 -0
  86. package/dist/browser/prod/excalidraw-assets/{infoDiagram-bcd20f53-MUIKXGC4.js → infoDiagram-bcd20f53-BP77NQEH.js} +1 -1
  87. package/dist/browser/prod/excalidraw-assets/{journeyDiagram-4fe6b3dc-NYRV4HK2.js → journeyDiagram-4fe6b3dc-XMGKCMES.js} +1 -1
  88. package/dist/browser/prod/excalidraw-assets/{mindmap-definition-f354de21-MY55DRSM.js → mindmap-definition-f354de21-ZQRRBRWF.js} +1 -1
  89. package/dist/browser/prod/excalidraw-assets/{pieDiagram-79897490-47L6J6L2.js → pieDiagram-79897490-IGXEC2KX.js} +1 -1
  90. package/dist/browser/prod/excalidraw-assets/{quadrantDiagram-62f64e94-DF5C2GDT.js → quadrantDiagram-62f64e94-WTHHDYJL.js} +1 -1
  91. package/dist/browser/prod/excalidraw-assets/{requirementDiagram-05bf5f74-C4IMUBDN.js → requirementDiagram-05bf5f74-MV4OFRVW.js} +1 -1
  92. package/dist/browser/prod/excalidraw-assets/{sankeyDiagram-97764748-YHW7EUST.js → sankeyDiagram-97764748-ZGYUHEJT.js} +1 -1
  93. package/dist/browser/prod/excalidraw-assets/{sequenceDiagram-acc0e65c-H3XEHT32.js → sequenceDiagram-acc0e65c-IBSENK6W.js} +1 -1
  94. package/dist/browser/prod/excalidraw-assets/{stateDiagram-0ff1cf1a-Z5WB6Q3P.js → stateDiagram-0ff1cf1a-DB73XNZH.js} +1 -1
  95. package/dist/browser/prod/excalidraw-assets/{stateDiagram-v2-9a9d610d-T7OZETQC.js → stateDiagram-v2-9a9d610d-2OOBUPNR.js} +1 -1
  96. package/dist/browser/prod/excalidraw-assets/{timeline-definition-fea2a41d-VVC22BWF.js → timeline-definition-fea2a41d-P3NQQVDU.js} +1 -1
  97. package/dist/browser/prod/excalidraw-assets/{xychartDiagram-ab372869-JAXODQF7.js → xychartDiagram-ab372869-HI3XLK3Y.js} +1 -1
  98. package/dist/browser/prod/index.css +1 -1
  99. package/dist/browser/prod/index.js +70 -51
  100. package/dist/dev/CascadiaMono-Regular-NWCXRPUG.woff2 +0 -0
  101. package/dist/dev/ComicShanns-Regular-6TOETDFT.woff2 +0 -0
  102. package/dist/dev/Excalifont-Regular-CPKEUDVM.woff2 +0 -0
  103. package/dist/dev/LiberationSans-Regular-ZQD73GJM.woff2 +0 -0
  104. package/dist/dev/Virgil-Regular-YHAB2VGJ.woff2 +0 -0
  105. package/dist/{prod/en-II4GK66F.json → dev/en-HDAPS7XK.json} +41 -9
  106. package/dist/dev/index.css +668 -191
  107. package/dist/dev/index.css.map +3 -3
  108. package/dist/dev/index.js +22026 -16675
  109. package/dist/dev/index.js.map +4 -4
  110. package/dist/excalidraw/actions/actionAddToLibrary.d.ts +22 -10
  111. package/dist/excalidraw/actions/actionAddToLibrary.js +4 -3
  112. package/dist/excalidraw/actions/actionAlign.d.ts +22 -22
  113. package/dist/excalidraw/actions/actionAlign.js +7 -6
  114. package/dist/excalidraw/actions/actionBoundText.d.ts +22 -14
  115. package/dist/excalidraw/actions/actionBoundText.js +11 -5
  116. package/dist/excalidraw/actions/actionCanvas.d.ts +124 -76
  117. package/dist/excalidraw/actions/actionCanvas.js +20 -15
  118. package/dist/excalidraw/actions/actionClipboard.d.ts +66 -38
  119. package/dist/excalidraw/actions/actionClipboard.js +14 -13
  120. package/dist/excalidraw/actions/actionDeleteSelected.d.ts +28 -16
  121. package/dist/excalidraw/actions/actionDeleteSelected.js +6 -3
  122. package/dist/excalidraw/actions/actionDistribute.d.ts +10 -10
  123. package/dist/excalidraw/actions/actionDistribute.js +3 -2
  124. package/dist/excalidraw/actions/actionDuplicateSelection.d.ts +7 -8
  125. package/dist/excalidraw/actions/actionDuplicateSelection.js +7 -3
  126. package/dist/excalidraw/actions/actionElementLock.d.ts +21 -13
  127. package/dist/excalidraw/actions/actionElementLock.js +3 -2
  128. package/dist/excalidraw/actions/actionExport.d.ts +87 -51
  129. package/dist/excalidraw/actions/actionExport.js +15 -11
  130. package/dist/excalidraw/actions/actionFinalize.d.ts +21 -13
  131. package/dist/excalidraw/actions/actionFinalize.js +9 -5
  132. package/dist/excalidraw/actions/actionFlip.d.ts +10 -10
  133. package/dist/excalidraw/actions/actionFlip.js +12 -12
  134. package/dist/excalidraw/actions/actionFrame.d.ts +193 -24
  135. package/dist/excalidraw/actions/actionFrame.js +7 -6
  136. package/dist/excalidraw/actions/actionGroup.d.ts +28 -20
  137. package/dist/excalidraw/actions/actionGroup.js +9 -11
  138. package/dist/excalidraw/actions/actionHistory.d.ts +4 -3
  139. package/dist/excalidraw/actions/actionHistory.js +27 -28
  140. package/dist/excalidraw/actions/actionLinearEditor.d.ts +12 -6
  141. package/dist/excalidraw/actions/actionLinearEditor.js +21 -5
  142. package/dist/excalidraw/actions/actionLink.d.ts +11 -7
  143. package/dist/excalidraw/actions/actionLink.js +2 -1
  144. package/dist/excalidraw/actions/actionMenu.d.ts +26 -14
  145. package/dist/excalidraw/actions/actionMenu.js +4 -3
  146. package/dist/excalidraw/actions/actionNavigate.d.ts +16 -8
  147. package/dist/excalidraw/actions/actionNavigate.js +3 -2
  148. package/dist/excalidraw/actions/actionProperties.d.ts +272 -62
  149. package/dist/excalidraw/actions/actionProperties.js +261 -59
  150. package/dist/excalidraw/actions/actionSelectAll.d.ts +11 -7
  151. package/dist/excalidraw/actions/actionSelectAll.js +2 -1
  152. package/dist/excalidraw/actions/actionStyles.d.ts +17 -13
  153. package/dist/excalidraw/actions/actionStyles.js +7 -5
  154. package/dist/excalidraw/actions/actionTextAutoResize.d.ts +17 -0
  155. package/dist/excalidraw/actions/actionTextAutoResize.js +38 -0
  156. package/dist/excalidraw/actions/actionToggleGridMode.d.ts +13 -7
  157. package/dist/excalidraw/actions/actionToggleGridMode.js +6 -2
  158. package/dist/excalidraw/actions/actionToggleObjectsSnapMode.d.ts +10 -6
  159. package/dist/excalidraw/actions/actionToggleObjectsSnapMode.js +2 -1
  160. package/dist/excalidraw/actions/actionToggleStats.d.ts +11 -6
  161. package/dist/excalidraw/actions/actionToggleStats.js +6 -4
  162. package/dist/excalidraw/actions/actionToggleViewMode.d.ts +10 -6
  163. package/dist/excalidraw/actions/actionToggleViewMode.js +2 -1
  164. package/dist/excalidraw/actions/actionToggleZenMode.d.ts +10 -6
  165. package/dist/excalidraw/actions/actionToggleZenMode.js +2 -1
  166. package/dist/excalidraw/actions/actionZindex.d.ts +23 -19
  167. package/dist/excalidraw/actions/actionZindex.js +9 -4
  168. package/dist/excalidraw/actions/manager.d.ts +5 -5
  169. package/dist/excalidraw/actions/register.d.ts +1 -1
  170. package/dist/excalidraw/actions/shortcuts.d.ts +2 -2
  171. package/dist/excalidraw/actions/shortcuts.js +1 -1
  172. package/dist/excalidraw/actions/types.d.ts +8 -8
  173. package/dist/excalidraw/align.d.ts +1 -1
  174. package/dist/excalidraw/analytics.js +9 -7
  175. package/dist/excalidraw/animated-trail.d.ts +2 -2
  176. package/dist/excalidraw/appState.d.ts +9 -6
  177. package/dist/excalidraw/appState.js +8 -3
  178. package/dist/excalidraw/change.d.ts +191 -0
  179. package/dist/excalidraw/change.js +901 -0
  180. package/dist/excalidraw/charts.d.ts +1 -1
  181. package/dist/excalidraw/clients.d.ts +2 -2
  182. package/dist/excalidraw/clients.js +1 -1
  183. package/dist/excalidraw/clipboard.d.ts +3 -3
  184. package/dist/excalidraw/colors.d.ts +1 -1
  185. package/dist/excalidraw/components/Actions.d.ts +3 -3
  186. package/dist/excalidraw/components/Actions.js +10 -7
  187. package/dist/excalidraw/components/App.d.ts +26 -16
  188. package/dist/excalidraw/components/App.js +490 -217
  189. package/dist/excalidraw/components/ButtonIcon.d.ts +15 -0
  190. package/dist/excalidraw/components/ButtonIcon.js +8 -0
  191. package/dist/excalidraw/components/ButtonIconSelect.js +2 -3
  192. package/dist/excalidraw/components/ButtonSeparator.d.ts +2 -0
  193. package/dist/excalidraw/components/ButtonSeparator.js +7 -0
  194. package/dist/excalidraw/components/CheckboxItem.js +1 -1
  195. package/dist/excalidraw/components/ColorPicker/ColorInput.d.ts +1 -1
  196. package/dist/excalidraw/components/ColorPicker/ColorInput.js +1 -1
  197. package/dist/excalidraw/components/ColorPicker/ColorPicker.d.ts +4 -4
  198. package/dist/excalidraw/components/ColorPicker/ColorPicker.js +48 -80
  199. package/dist/excalidraw/components/ColorPicker/Picker.d.ts +3 -3
  200. package/dist/excalidraw/components/ColorPicker/Picker.js +1 -1
  201. package/dist/excalidraw/components/ColorPicker/PickerColorList.d.ts +1 -1
  202. package/dist/excalidraw/components/ColorPicker/PickerHeading.d.ts +1 -1
  203. package/dist/excalidraw/components/ColorPicker/ShadeList.d.ts +1 -1
  204. package/dist/excalidraw/components/ColorPicker/TopPicks.d.ts +1 -1
  205. package/dist/excalidraw/components/ColorPicker/colorPickerUtils.d.ts +2 -2
  206. package/dist/excalidraw/components/ColorPicker/colorPickerUtils.js +1 -1
  207. package/dist/excalidraw/components/ColorPicker/keyboardNavHandlers.d.ts +2 -2
  208. package/dist/excalidraw/components/ColorPicker/keyboardNavHandlers.js +1 -1
  209. package/dist/excalidraw/components/CommandPalette/CommandPalette.d.ts +1 -1
  210. package/dist/excalidraw/components/CommandPalette/CommandPalette.js +33 -18
  211. package/dist/excalidraw/components/CommandPalette/defaultCommandPaletteItems.d.ts +1 -1
  212. package/dist/excalidraw/components/CommandPalette/types.d.ts +3 -3
  213. package/dist/excalidraw/components/ConfirmDialog.d.ts +1 -1
  214. package/dist/excalidraw/components/ContextMenu.d.ts +2 -2
  215. package/dist/excalidraw/components/ContextMenu.js +2 -2
  216. package/dist/excalidraw/components/DarkModeToggle.d.ts +1 -1
  217. package/dist/excalidraw/components/DarkModeToggle.js +3 -1
  218. package/dist/excalidraw/components/DefaultSidebar.d.ts +2 -2
  219. package/dist/excalidraw/components/Dialog.js +1 -1
  220. package/dist/excalidraw/components/DialogActionButton.d.ts +1 -1
  221. package/dist/excalidraw/components/EyeDropper.d.ts +2 -2
  222. package/dist/excalidraw/components/FollowMode/FollowMode.d.ts +1 -1
  223. package/dist/excalidraw/components/FollowMode/FollowMode.js +1 -1
  224. package/dist/excalidraw/components/FontPicker/FontPicker.d.ts +21 -0
  225. package/dist/excalidraw/components/FontPicker/FontPicker.js +49 -0
  226. package/dist/excalidraw/components/FontPicker/FontPickerList.d.ts +25 -0
  227. package/dist/excalidraw/components/FontPicker/FontPickerList.js +119 -0
  228. package/dist/excalidraw/components/FontPicker/FontPickerTrigger.d.ts +7 -0
  229. package/dist/excalidraw/components/FontPicker/FontPickerTrigger.js +13 -0
  230. package/dist/excalidraw/components/FontPicker/keyboardNavHandlers.d.ts +14 -0
  231. package/dist/excalidraw/components/FontPicker/keyboardNavHandlers.js +38 -0
  232. package/dist/excalidraw/components/HelpDialog.js +9 -7
  233. package/dist/excalidraw/components/HintViewer.d.ts +1 -1
  234. package/dist/excalidraw/components/IconPicker.js +2 -2
  235. package/dist/excalidraw/components/ImageExportDialog.d.ts +1 -1
  236. package/dist/excalidraw/components/InitializeApp.d.ts +2 -2
  237. package/dist/excalidraw/components/JSONExportDialog.d.ts +3 -3
  238. package/dist/excalidraw/components/LayerUI.d.ts +4 -4
  239. package/dist/excalidraw/components/LayerUI.js +10 -7
  240. package/dist/excalidraw/components/LibraryMenu.d.ts +2 -2
  241. package/dist/excalidraw/components/LibraryMenuBrowseButton.d.ts +1 -1
  242. package/dist/excalidraw/components/LibraryMenuControlButtons.d.ts +1 -1
  243. package/dist/excalidraw/components/LibraryMenuHeaderContent.d.ts +2 -2
  244. package/dist/excalidraw/components/LibraryMenuItems.d.ts +1 -1
  245. package/dist/excalidraw/components/LibraryMenuSection.d.ts +5 -4
  246. package/dist/excalidraw/components/LibraryUnit.d.ts +2 -2
  247. package/dist/excalidraw/components/LoadingMessage.d.ts +1 -1
  248. package/dist/excalidraw/components/MagicSettings.js +2 -2
  249. package/dist/excalidraw/components/MobileMenu.d.ts +3 -3
  250. package/dist/excalidraw/components/MobileMenu.js +2 -6
  251. package/dist/excalidraw/components/Modal.d.ts +1 -1
  252. package/dist/excalidraw/components/OverwriteConfirm/OverwriteConfirmState.d.ts +1 -1
  253. package/dist/excalidraw/components/PasteChartDialog.d.ts +1 -1
  254. package/dist/excalidraw/components/PasteChartDialog.js +1 -1
  255. package/dist/excalidraw/components/PropertiesPopover.d.ts +15 -0
  256. package/dist/excalidraw/components/PropertiesPopover.js +31 -0
  257. package/dist/excalidraw/components/PublishLibrary.d.ts +1 -1
  258. package/dist/excalidraw/components/QuickSearch.d.ts +9 -0
  259. package/dist/excalidraw/components/QuickSearch.js +8 -0
  260. package/dist/excalidraw/components/RadioGroup.d.ts +2 -1
  261. package/dist/excalidraw/components/RadioGroup.js +1 -1
  262. package/dist/excalidraw/components/SVGLayer.d.ts +1 -1
  263. package/dist/excalidraw/components/ScrollableList.d.ts +9 -0
  264. package/dist/excalidraw/components/ScrollableList.js +8 -0
  265. package/dist/excalidraw/components/Sidebar/Sidebar.d.ts +2 -2
  266. package/dist/excalidraw/components/Sidebar/Sidebar.js +1 -1
  267. package/dist/excalidraw/components/Sidebar/SidebarTab.d.ts +1 -1
  268. package/dist/excalidraw/components/Sidebar/SidebarTabTrigger.d.ts +1 -1
  269. package/dist/excalidraw/components/Sidebar/SidebarTrigger.d.ts +1 -1
  270. package/dist/excalidraw/components/Sidebar/common.d.ts +1 -1
  271. package/dist/excalidraw/components/Stack.d.ts +2 -2
  272. package/dist/excalidraw/components/Stats/Angle.d.ts +12 -0
  273. package/dist/excalidraw/components/Stats/Angle.js +52 -0
  274. package/dist/excalidraw/components/Stats/Collapsible.d.ts +9 -0
  275. package/dist/excalidraw/components/Stats/Collapsible.js +12 -0
  276. package/dist/excalidraw/components/Stats/Dimension.d.ts +12 -0
  277. package/dist/excalidraw/components/Stats/Dimension.js +67 -0
  278. package/dist/excalidraw/components/Stats/DragInput.d.ts +32 -0
  279. package/dist/excalidraw/components/Stats/DragInput.js +174 -0
  280. package/dist/excalidraw/components/Stats/FontSize.d.ts +12 -0
  281. package/dist/excalidraw/components/Stats/FontSize.js +50 -0
  282. package/dist/excalidraw/components/Stats/MultiAngle.d.ts +12 -0
  283. package/dist/excalidraw/components/Stats/MultiAngle.js +66 -0
  284. package/dist/excalidraw/components/Stats/MultiDimension.d.ts +15 -0
  285. package/dist/excalidraw/components/Stats/MultiDimension.js +197 -0
  286. package/dist/excalidraw/components/Stats/MultiFontSize.d.ts +13 -0
  287. package/dist/excalidraw/components/Stats/MultiFontSize.js +72 -0
  288. package/dist/excalidraw/components/Stats/MultiPosition.d.ts +15 -0
  289. package/dist/excalidraw/components/Stats/MultiPosition.js +100 -0
  290. package/dist/excalidraw/components/Stats/Position.d.ts +13 -0
  291. package/dist/excalidraw/components/Stats/Position.js +39 -0
  292. package/dist/excalidraw/components/Stats/index.d.ts +16 -0
  293. package/dist/excalidraw/components/Stats/index.js +78 -0
  294. package/dist/excalidraw/components/Stats/utils.d.ts +25 -0
  295. package/dist/excalidraw/components/Stats/utils.js +158 -0
  296. package/dist/excalidraw/components/TTDDialog/MermaidToExcalidraw.d.ts +1 -1
  297. package/dist/excalidraw/components/TTDDialog/MermaidToExcalidraw.js +6 -2
  298. package/dist/excalidraw/components/TTDDialog/TTDDialog.js +2 -2
  299. package/dist/excalidraw/components/TTDDialog/TTDDialogInput.d.ts +1 -1
  300. package/dist/excalidraw/components/TTDDialog/TTDDialogPanel.d.ts +1 -1
  301. package/dist/excalidraw/components/TTDDialog/TTDDialogPanels.d.ts +1 -1
  302. package/dist/excalidraw/components/TTDDialog/TTDDialogTabs.d.ts +1 -1
  303. package/dist/excalidraw/components/TTDDialog/TTDDialogTrigger.d.ts +1 -1
  304. package/dist/excalidraw/components/TTDDialog/common.d.ts +5 -5
  305. package/dist/excalidraw/components/TTDDialog/common.js +3 -7
  306. package/dist/excalidraw/components/TextField.d.ts +1 -1
  307. package/dist/excalidraw/components/Toast.d.ts +1 -1
  308. package/dist/excalidraw/components/ToolButton.d.ts +4 -2
  309. package/dist/excalidraw/components/ToolButton.js +1 -1
  310. package/dist/excalidraw/components/Trans.d.ts +1 -1
  311. package/dist/excalidraw/components/UserList.d.ts +1 -1
  312. package/dist/excalidraw/components/UserList.js +22 -22
  313. package/dist/excalidraw/components/canvases/InteractiveCanvas.d.ts +5 -3
  314. package/dist/excalidraw/components/canvases/InteractiveCanvas.js +5 -2
  315. package/dist/excalidraw/components/canvases/StaticCanvas.d.ts +2 -2
  316. package/dist/excalidraw/components/canvases/StaticCanvas.js +3 -2
  317. package/dist/excalidraw/components/dropdownMenu/DropdownMenu.d.ts +12 -3
  318. package/dist/excalidraw/components/dropdownMenu/DropdownMenuItem.d.ts +24 -4
  319. package/dist/excalidraw/components/dropdownMenu/DropdownMenuItem.js +55 -14
  320. package/dist/excalidraw/components/dropdownMenu/DropdownMenuItemContent.d.ts +2 -1
  321. package/dist/excalidraw/components/dropdownMenu/DropdownMenuItemContent.js +2 -2
  322. package/dist/excalidraw/components/dropdownMenu/DropdownMenuItemContentRadio.d.ts +18 -0
  323. package/dist/excalidraw/components/dropdownMenu/DropdownMenuItemContentRadio.js +9 -0
  324. package/dist/excalidraw/components/dropdownMenu/common.d.ts +1 -1
  325. package/dist/excalidraw/components/dropdownMenu/common.js +3 -2
  326. package/dist/excalidraw/components/footer/Footer.d.ts +2 -2
  327. package/dist/excalidraw/components/hyperlink/Hyperlink.d.ts +2 -2
  328. package/dist/excalidraw/components/hyperlink/Hyperlink.js +3 -3
  329. package/dist/excalidraw/components/hyperlink/helpers.d.ts +3 -3
  330. package/dist/excalidraw/components/hyperlink/helpers.js +2 -3
  331. package/dist/excalidraw/components/icons.d.ts +10 -1
  332. package/dist/excalidraw/components/icons.js +27 -5
  333. package/dist/excalidraw/components/main-menu/DefaultItems.d.ts +12 -2
  334. package/dist/excalidraw/components/main-menu/DefaultItems.js +38 -7
  335. package/dist/excalidraw/components/main-menu/MainMenu.d.ts +12 -3
  336. package/dist/excalidraw/components/welcome-screen/WelcomeScreen.Center.js +2 -2
  337. package/dist/excalidraw/components/welcome-screen/WelcomeScreen.Hints.js +3 -3
  338. package/dist/excalidraw/constants.d.ts +24 -6
  339. package/dist/excalidraw/constants.js +29 -7
  340. package/dist/excalidraw/context/ui-appState.d.ts +1 -1
  341. package/dist/excalidraw/cursor.d.ts +1 -1
  342. package/dist/excalidraw/data/EditorLocalStorage.d.ts +2 -2
  343. package/dist/excalidraw/data/blob.d.ts +5 -5
  344. package/dist/excalidraw/data/filesystem.d.ts +2 -1
  345. package/dist/excalidraw/data/index.d.ts +4 -4
  346. package/dist/excalidraw/data/json.d.ts +3 -3
  347. package/dist/excalidraw/data/library.d.ts +3 -3
  348. package/dist/excalidraw/data/magic.d.ts +3 -3
  349. package/dist/excalidraw/data/magic.js +2 -1
  350. package/dist/excalidraw/data/reconcile.d.ts +6 -0
  351. package/dist/excalidraw/data/reconcile.js +49 -0
  352. package/dist/excalidraw/data/resave.d.ts +2 -2
  353. package/dist/excalidraw/data/restore.d.ts +5 -5
  354. package/dist/excalidraw/data/restore.js +25 -10
  355. package/dist/excalidraw/data/transform.d.ts +4 -4
  356. package/dist/excalidraw/data/transform.js +15 -5
  357. package/dist/excalidraw/data/types.d.ts +3 -3
  358. package/dist/excalidraw/data/url.d.ts +1 -0
  359. package/dist/excalidraw/data/url.js +4 -1
  360. package/dist/excalidraw/element/ElementCanvasButtons.d.ts +1 -1
  361. package/dist/excalidraw/element/binding.d.ts +49 -8
  362. package/dist/excalidraw/element/binding.js +716 -153
  363. package/dist/excalidraw/element/bounds.d.ts +3 -4
  364. package/dist/excalidraw/element/bounds.js +0 -3
  365. package/dist/excalidraw/element/collision.d.ts +14 -19
  366. package/dist/excalidraw/element/collision.js +36 -713
  367. package/dist/excalidraw/element/containerCache.d.ts +1 -1
  368. package/dist/excalidraw/element/dragElements.d.ts +4 -4
  369. package/dist/excalidraw/element/dragElements.js +27 -3
  370. package/dist/excalidraw/element/embeddable.d.ts +15 -8
  371. package/dist/excalidraw/element/embeddable.js +98 -62
  372. package/dist/excalidraw/element/image.d.ts +2 -2
  373. package/dist/excalidraw/element/index.d.ts +2 -3
  374. package/dist/excalidraw/element/index.js +1 -2
  375. package/dist/excalidraw/element/linearElementEditor.d.ts +18 -14
  376. package/dist/excalidraw/element/linearElementEditor.js +12 -7
  377. package/dist/excalidraw/element/mutateElement.d.ts +4 -5
  378. package/dist/excalidraw/element/mutateElement.js +5 -3
  379. package/dist/excalidraw/element/newElement.d.ts +6 -9
  380. package/dist/excalidraw/element/newElement.js +21 -17
  381. package/dist/excalidraw/element/resizeElements.d.ts +12 -4
  382. package/dist/excalidraw/element/resizeElements.js +174 -98
  383. package/dist/excalidraw/element/resizeTest.d.ts +7 -7
  384. package/dist/excalidraw/element/resizeTest.js +53 -8
  385. package/dist/excalidraw/element/showSelectedShapeActions.d.ts +2 -2
  386. package/dist/excalidraw/element/sizeHelpers.d.ts +2 -2
  387. package/dist/excalidraw/element/sizeHelpers.js +3 -0
  388. package/dist/excalidraw/element/sortElements.d.ts +1 -1
  389. package/dist/excalidraw/element/textElement.d.ts +7 -30
  390. package/dist/excalidraw/element/textElement.js +68 -144
  391. package/dist/excalidraw/element/textWysiwyg.d.ts +12 -6
  392. package/dist/excalidraw/element/textWysiwyg.js +75 -62
  393. package/dist/excalidraw/element/transformHandles.d.ts +24 -6
  394. package/dist/excalidraw/element/transformHandles.js +22 -11
  395. package/dist/excalidraw/element/typeChecks.d.ts +5 -5
  396. package/dist/excalidraw/element/types.d.ts +33 -10
  397. package/dist/excalidraw/emitter.d.ts +1 -1
  398. package/dist/excalidraw/errors.d.ts +3 -0
  399. package/dist/excalidraw/errors.js +3 -0
  400. package/dist/excalidraw/fonts/ExcalidrawFont.d.ts +17 -0
  401. package/dist/excalidraw/fonts/ExcalidrawFont.js +50 -0
  402. package/dist/excalidraw/fonts/index.d.ts +45 -0
  403. package/dist/excalidraw/fonts/index.js +202 -0
  404. package/dist/excalidraw/fonts/metadata.d.ts +34 -0
  405. package/dist/excalidraw/fonts/metadata.js +90 -0
  406. package/dist/excalidraw/fractionalIndex.d.ts +40 -0
  407. package/dist/excalidraw/fractionalIndex.js +239 -0
  408. package/dist/excalidraw/frame.d.ts +4 -4
  409. package/dist/excalidraw/gatransforms.d.ts +1 -1
  410. package/dist/excalidraw/gesture.d.ts +1 -1
  411. package/dist/excalidraw/groups.d.ts +6 -4
  412. package/dist/excalidraw/groups.js +17 -0
  413. package/dist/excalidraw/history.d.ts +35 -47
  414. package/dist/excalidraw/history.js +100 -167
  415. package/dist/excalidraw/hooks/useCreatePortalContainer.js +2 -1
  416. package/dist/excalidraw/hooks/useEmitter.d.ts +2 -0
  417. package/dist/excalidraw/hooks/useEmitter.js +13 -0
  418. package/dist/excalidraw/hooks/useLibraryItemSvg.d.ts +1 -1
  419. package/dist/excalidraw/i18n.d.ts +1 -1
  420. package/dist/excalidraw/index.d.ts +4 -2
  421. package/dist/excalidraw/index.js +5 -3
  422. package/dist/excalidraw/jotai.d.ts +1 -1
  423. package/dist/excalidraw/laser-trails.d.ts +3 -2
  424. package/dist/excalidraw/locales/en.json +41 -9
  425. package/dist/excalidraw/math.d.ts +4 -2
  426. package/dist/excalidraw/math.js +6 -0
  427. package/dist/excalidraw/mermaid.d.ts +2 -0
  428. package/dist/excalidraw/mermaid.js +28 -0
  429. package/dist/excalidraw/points.d.ts +1 -1
  430. package/dist/excalidraw/queue.d.ts +1 -1
  431. package/dist/excalidraw/renderer/helpers.d.ts +2 -2
  432. package/dist/excalidraw/renderer/helpers.js +2 -2
  433. package/dist/excalidraw/renderer/interactiveScene.d.ts +2 -2
  434. package/dist/excalidraw/renderer/interactiveScene.js +38 -11
  435. package/dist/excalidraw/renderer/renderElement.d.ts +6 -4
  436. package/dist/excalidraw/renderer/renderElement.js +81 -61
  437. package/dist/excalidraw/renderer/renderSnaps.d.ts +1 -1
  438. package/dist/excalidraw/renderer/renderSnaps.js +2 -1
  439. package/dist/excalidraw/renderer/staticScene.d.ts +1 -1
  440. package/dist/excalidraw/renderer/staticScene.js +14 -3
  441. package/dist/excalidraw/renderer/staticSvgScene.d.ts +4 -4
  442. package/dist/excalidraw/renderer/staticSvgScene.js +12 -1
  443. package/dist/excalidraw/scene/Renderer.d.ts +4 -4
  444. package/dist/excalidraw/scene/Renderer.js +2 -3
  445. package/dist/excalidraw/scene/Scene.d.ts +22 -12
  446. package/dist/excalidraw/scene/Scene.js +47 -23
  447. package/dist/excalidraw/scene/Shape.d.ts +1 -1
  448. package/dist/excalidraw/scene/ShapeCache.d.ts +4 -4
  449. package/dist/excalidraw/scene/comparisons.d.ts +2 -2
  450. package/dist/excalidraw/scene/export.d.ts +3 -2
  451. package/dist/excalidraw/scene/export.js +40 -29
  452. package/dist/excalidraw/scene/scroll.d.ts +2 -2
  453. package/dist/excalidraw/scene/scrollbars.d.ts +3 -3
  454. package/dist/excalidraw/scene/selection.d.ts +2 -2
  455. package/dist/excalidraw/scene/types.d.ts +7 -8
  456. package/dist/excalidraw/scene/zoom.d.ts +1 -1
  457. package/dist/excalidraw/shapes.d.ts +7 -0
  458. package/dist/excalidraw/shapes.js +40 -0
  459. package/dist/excalidraw/snapping.d.ts +4 -4
  460. package/dist/excalidraw/snapping.js +2 -1
  461. package/dist/excalidraw/store.d.ts +129 -0
  462. package/dist/excalidraw/store.js +296 -0
  463. package/dist/excalidraw/types.d.ts +45 -22
  464. package/dist/excalidraw/utils.d.ts +20 -4
  465. package/dist/excalidraw/utils.js +29 -0
  466. package/dist/excalidraw/zindex.d.ts +4 -4
  467. package/dist/excalidraw/zindex.js +9 -13
  468. package/dist/prod/CascadiaMono-Regular-NWCXRPUG.woff2 +0 -0
  469. package/dist/prod/ComicShanns-Regular-6TOETDFT.woff2 +0 -0
  470. package/dist/prod/Excalifont-Regular-CPKEUDVM.woff2 +0 -0
  471. package/dist/prod/LiberationSans-Regular-ZQD73GJM.woff2 +0 -0
  472. package/dist/prod/Virgil-Regular-YHAB2VGJ.woff2 +0 -0
  473. package/dist/{dev/en-II4GK66F.json → prod/en-HDAPS7XK.json} +41 -9
  474. package/dist/prod/index.css +1 -1
  475. package/dist/prod/index.js +47 -53
  476. package/dist/utils/bbox.d.ts +2 -2
  477. package/dist/utils/collision.d.ts +4 -0
  478. package/dist/utils/collision.js +48 -0
  479. package/dist/utils/export.d.ts +4 -3
  480. package/dist/utils/export.js +2 -1
  481. package/dist/utils/geometry/geometry.d.ts +71 -0
  482. package/dist/utils/geometry/geometry.js +674 -0
  483. package/dist/utils/geometry/shape.d.ts +56 -0
  484. package/dist/utils/geometry/shape.js +168 -0
  485. package/dist/utils/index.d.ts +1 -0
  486. package/dist/utils/index.js +1 -0
  487. package/dist/utils/withinBounds.d.ts +1 -1
  488. package/history.ts +163 -218
  489. package/package.json +3 -2
  490. package/dist/browser/dev/Cascadia-CYPE3OJC.woff2 +0 -0
  491. package/dist/browser/dev/Virgil-UZN6MUT6.woff2 +0 -0
  492. package/dist/browser/dev/excalidraw-assets-dev/chunk-AK7SWNLN.js.map +0 -7
  493. package/dist/browser/dev/excalidraw-assets-dev/chunk-RWZVJAQU.js.map +0 -7
  494. package/dist/browser/dev/excalidraw-assets-dev/chunk-Z3PH3V2B.js.map +0 -7
  495. package/dist/browser/dev/excalidraw-assets-dev/dist-Z46EOVOL.js.map +0 -7
  496. package/dist/browser/dev/excalidraw-assets-dev/image-OFRRV5MB.css.map +0 -7
  497. package/dist/browser/prod/Cascadia-CYPE3OJC.woff2 +0 -0
  498. package/dist/browser/prod/Virgil-UZN6MUT6.woff2 +0 -0
  499. package/dist/browser/prod/excalidraw-assets/chunk-LL4GORAM.js +0 -55
  500. package/dist/browser/prod/excalidraw-assets/dist-PIPZXALV.js +0 -6
  501. package/dist/browser/prod/excalidraw-assets/en-LROPV2RN.js +0 -1
  502. package/dist/browser/prod/excalidraw-assets/image-EFCJDJH3.js +0 -1
  503. package/dist/dev/Cascadia-CYPE3OJC.woff2 +0 -0
  504. package/dist/dev/Virgil-UZN6MUT6.woff2 +0 -0
  505. package/dist/excalidraw/components/Stats.d.ts +0 -11
  506. package/dist/excalidraw/components/Stats.js +0 -13
  507. package/dist/excalidraw/scene/Fonts.d.ts +0 -21
  508. package/dist/excalidraw/scene/Fonts.js +0 -72
  509. package/dist/prod/Cascadia-CYPE3OJC.woff2 +0 -0
  510. package/dist/prod/Virgil-UZN6MUT6.woff2 +0 -0
  511. /package/dist/browser/dev/{Assistant-Bold-ZDZZ6JHA.woff2 → excalidraw-assets-dev/Assistant-Bold-ZDZZ6JHA.woff2} +0 -0
  512. /package/dist/browser/dev/{Assistant-Medium-DZ25RZU3.woff2 → excalidraw-assets-dev/Assistant-Medium-DZ25RZU3.woff2} +0 -0
  513. /package/dist/browser/dev/{Assistant-Regular-PLF2XOGW.woff2 → excalidraw-assets-dev/Assistant-Regular-PLF2XOGW.woff2} +0 -0
  514. /package/dist/browser/dev/{Assistant-SemiBold-CZ5MX6FK.woff2 → excalidraw-assets-dev/Assistant-SemiBold-CZ5MX6FK.woff2} +0 -0
  515. /package/dist/browser/dev/excalidraw-assets-dev/{blockDiagram-91b80b7a-ACFH36JV.js.map → blockDiagram-91b80b7a-H47FTXHA.js.map} +0 -0
  516. /package/dist/browser/dev/excalidraw-assets-dev/{c4Diagram-b2a90758-QZ27YR47.js.map → c4Diagram-b2a90758-NNJK6GKC.js.map} +0 -0
  517. /package/dist/browser/dev/excalidraw-assets-dev/{chunk-HO2HMSK7.js.map → chunk-4KQVEBHW.js.map} +0 -0
  518. /package/dist/browser/dev/excalidraw-assets-dev/{chunk-USGV265L.js.map → chunk-53YI56GV.js.map} +0 -0
  519. /package/dist/browser/dev/excalidraw-assets-dev/{chunk-EDFX3S7X.js.map → chunk-A2WCJI4I.js.map} +0 -0
  520. /package/dist/browser/dev/excalidraw-assets-dev/{chunk-IX4V72YG.js.map → chunk-EFLPX7NE.js.map} +0 -0
  521. /package/dist/browser/dev/excalidraw-assets-dev/{chunk-MXVETLVM.js.map → chunk-JYIQCNWV.js.map} +0 -0
  522. /package/dist/browser/dev/excalidraw-assets-dev/{chunk-YZIOORVX.js.map → chunk-LVIQQW6F.js.map} +0 -0
  523. /package/dist/browser/dev/excalidraw-assets-dev/{chunk-6U7GQNJT.js.map → chunk-PXLO3FOU.js.map} +0 -0
  524. /package/dist/browser/dev/excalidraw-assets-dev/{chunk-7DACDEY3.js.map → chunk-TO2AW5PW.js.map} +0 -0
  525. /package/dist/browser/dev/excalidraw-assets-dev/{chunk-NJ77ZFNJ.js.map → chunk-VURILHLY.js.map} +0 -0
  526. /package/dist/browser/dev/excalidraw-assets-dev/{chunk-2T2GU7NF.js.map → chunk-ZAYGSUHF.js.map} +0 -0
  527. /package/dist/browser/dev/excalidraw-assets-dev/{classDiagram-30eddba6-QSLMH4JW.js.map → classDiagram-30eddba6-CUYIJICN.js.map} +0 -0
  528. /package/dist/browser/dev/excalidraw-assets-dev/{classDiagram-v2-f2df5561-DY4DYQ5P.js.map → classDiagram-v2-f2df5561-K6WW6K73.js.map} +0 -0
  529. /package/dist/browser/dev/excalidraw-assets-dev/{en-5TCZHGGJ.js.map → en-RAFN4KPD.js.map} +0 -0
  530. /package/dist/browser/dev/excalidraw-assets-dev/{erDiagram-47591fe2-SOOJRTCB.js.map → erDiagram-47591fe2-XGAD7EEP.js.map} +0 -0
  531. /package/dist/browser/dev/excalidraw-assets-dev/{flowDiagram-5540d9b9-AHGL4KPK.js.map → flowDiagram-5540d9b9-B6EOVNNO.js.map} +0 -0
  532. /package/dist/browser/dev/excalidraw-assets-dev/{flowDiagram-v2-3b53844e-56LDZZWY.js.map → flowDiagram-v2-3b53844e-NUG24FJH.js.map} +0 -0
  533. /package/dist/browser/dev/excalidraw-assets-dev/{flowchart-elk-definition-5fe447d6-27LUKRI6.js.map → flowchart-elk-definition-5fe447d6-25Y7PCBL.js.map} +0 -0
  534. /package/dist/browser/dev/excalidraw-assets-dev/{ganttDiagram-9a3bba1f-EHGYGNG6.js.map → ganttDiagram-9a3bba1f-GNL6ZDTC.js.map} +0 -0
  535. /package/dist/browser/dev/excalidraw-assets-dev/{gitGraphDiagram-96e6b4ee-AJQNBDW5.js.map → gitGraphDiagram-96e6b4ee-HNW52NVO.js.map} +0 -0
  536. /package/dist/browser/dev/excalidraw-assets-dev/{image-EDKQZH7Z.js.map → image-ZNLDWTK3.js.map} +0 -0
  537. /package/dist/browser/dev/excalidraw-assets-dev/{infoDiagram-bcd20f53-SWLLQVES.js.map → infoDiagram-bcd20f53-FWEUVFLT.js.map} +0 -0
  538. /package/dist/browser/dev/excalidraw-assets-dev/{journeyDiagram-4fe6b3dc-7UAVCWOZ.js.map → journeyDiagram-4fe6b3dc-RZIUI7UG.js.map} +0 -0
  539. /package/dist/browser/dev/excalidraw-assets-dev/{mindmap-definition-f354de21-SROW5KGM.js.map → mindmap-definition-f354de21-GBVN45GU.js.map} +0 -0
  540. /package/dist/browser/dev/excalidraw-assets-dev/{pieDiagram-79897490-QKCI6NCB.js.map → pieDiagram-79897490-ECENNII6.js.map} +0 -0
  541. /package/dist/browser/dev/excalidraw-assets-dev/{quadrantDiagram-62f64e94-LNYJZFC5.js.map → quadrantDiagram-62f64e94-ZMEOFVNL.js.map} +0 -0
  542. /package/dist/browser/dev/excalidraw-assets-dev/{requirementDiagram-05bf5f74-ZZD7ZHFA.js.map → requirementDiagram-05bf5f74-FHZSFHCR.js.map} +0 -0
  543. /package/dist/browser/dev/excalidraw-assets-dev/{sankeyDiagram-97764748-L75ZZ4UM.js.map → sankeyDiagram-97764748-VDKIKTA6.js.map} +0 -0
  544. /package/dist/browser/dev/excalidraw-assets-dev/{sequenceDiagram-acc0e65c-6PCU7TDK.js.map → sequenceDiagram-acc0e65c-6JUSPVKX.js.map} +0 -0
  545. /package/dist/browser/dev/excalidraw-assets-dev/{stateDiagram-0ff1cf1a-WM76WOPR.js.map → stateDiagram-0ff1cf1a-L3AKWENF.js.map} +0 -0
  546. /package/dist/browser/dev/excalidraw-assets-dev/{stateDiagram-v2-9a9d610d-N4HZW3O2.js.map → stateDiagram-v2-9a9d610d-NU3GGMCH.js.map} +0 -0
  547. /package/dist/browser/dev/excalidraw-assets-dev/{timeline-definition-fea2a41d-ZHGCAXGP.js.map → timeline-definition-fea2a41d-JGP7XCHW.js.map} +0 -0
  548. /package/dist/browser/dev/excalidraw-assets-dev/{xychartDiagram-ab372869-2DLOVRAZ.js.map → xychartDiagram-ab372869-HLFHHF2I.js.map} +0 -0
  549. /package/dist/browser/prod/{Assistant-Bold-ZDZZ6JHA.woff2 → excalidraw-assets/Assistant-Bold-ZDZZ6JHA.woff2} +0 -0
  550. /package/dist/browser/prod/{Assistant-Medium-DZ25RZU3.woff2 → excalidraw-assets/Assistant-Medium-DZ25RZU3.woff2} +0 -0
  551. /package/dist/browser/prod/{Assistant-Regular-PLF2XOGW.woff2 → excalidraw-assets/Assistant-Regular-PLF2XOGW.woff2} +0 -0
  552. /package/dist/browser/prod/{Assistant-SemiBold-CZ5MX6FK.woff2 → excalidraw-assets/Assistant-SemiBold-CZ5MX6FK.woff2} +0 -0
@@ -1,12 +1,19 @@
1
+ import * as GA from "../ga";
2
+ import * as GAPoint from "../gapoints";
3
+ import * as GADirection from "../gadirections";
4
+ import * as GALine from "../galines";
5
+ import * as GATransform from "../gatransforms";
6
+ import { getElementAbsoluteCoords } from "./bounds";
7
+ import { isPointOnShape } from "../../utils/collision";
1
8
  import { getElementAtPosition } from "../scene";
2
- import { isBindableElement, isBindingElement, isLinearElement, } from "./typeChecks";
3
- import { bindingBorderTest, distanceToBindableElement, maxBindingGap, determineFocusDistance, intersectElementWithLine, determineFocusPoint, } from "./collision";
9
+ import { isArrowElement, isBindableElement, isBindingElement, isBoundToContainer, isLinearElement, isTextElement, } from "./typeChecks";
4
10
  import { mutateElement } from "./mutateElement";
5
11
  import Scene from "../scene/Scene";
6
12
  import { LinearElementEditor } from "./linearElementEditor";
7
13
  import { arrayToMap, tupleToCoors } from "../utils";
8
14
  import { KEYS } from "../keys";
9
15
  import { getBoundTextElement, handleBindTextResize } from "./textElement";
16
+ import { getElementShape } from "../shapes";
10
17
  export const shouldEnableBindingForPointerEvent = (event) => {
11
18
  return !event[KEYS.CTRL_OR_CMD];
12
19
  };
@@ -40,51 +47,125 @@ const bindOrUnbindLinearElementEdge = (linearElement, bindableElement, otherEdge
40
47
  boundToElementIds,
41
48
  // Is mutated
42
49
  unboundFromElementIds, elementsMap) => {
43
- if (bindableElement !== "keep") {
44
- if (bindableElement != null) {
45
- // Don't bind if we're trying to bind or are already bound to the same
46
- // element on the other edge already ("start" edge takes precedence).
47
- if (otherEdgeBindableElement == null ||
48
- (otherEdgeBindableElement === "keep"
49
- ? !isLinearElementSimpleAndAlreadyBoundOnOppositeEdge(linearElement, bindableElement, startOrEnd)
50
- : startOrEnd === "start" ||
51
- otherEdgeBindableElement.id !== bindableElement.id)) {
52
- bindLinearElement(linearElement, bindableElement, startOrEnd, elementsMap);
53
- boundToElementIds.add(bindableElement.id);
54
- }
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);
55
59
  }
56
- else {
57
- const unbound = unbindLinearElement(linearElement, startOrEnd);
58
- if (unbound != null) {
59
- unboundFromElementIds.add(unbound);
60
- }
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);
61
74
  }
62
75
  }
76
+ else {
77
+ bindLinearElement(linearElement, bindableElement, startOrEnd, elementsMap);
78
+ boundToElementIds.add(bindableElement.id);
79
+ }
63
80
  };
64
- export const bindOrUnbindSelectedElements = (selectedElements, elements, elementsMap) => {
65
- selectedElements.forEach((selectedElement) => {
66
- if (isBindingElement(selectedElement)) {
67
- bindOrUnbindLinearElement(selectedElement, getElligibleElementForBindingElement(selectedElement, "start", elements, elementsMap), getElligibleElementForBindingElement(selectedElement, "end", elements, elementsMap), elementsMap);
68
- }
69
- else if (isBindableElement(selectedElement)) {
70
- maybeBindBindableElement(selectedElement, elementsMap);
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;
71
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);
72
137
  });
73
138
  };
74
- const maybeBindBindableElement = (bindableElement, elementsMap) => {
75
- getElligibleElementsForBindableElementAndWhere(bindableElement, elementsMap).forEach(([linearElement, where]) => bindOrUnbindLinearElement(linearElement, where === "end" ? "keep" : bindableElement, where === "start" ? "keep" : bindableElement, elementsMap));
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));
76
154
  };
77
- export const maybeBindLinearElement = (linearElement, appState, scene, pointerCoords, elementsMap) => {
155
+ export const maybeBindLinearElement = (linearElement, appState, pointerCoords, elementsMap) => {
78
156
  if (appState.startBoundElement != null) {
79
157
  bindLinearElement(linearElement, appState.startBoundElement, "start", elementsMap);
80
158
  }
81
- const hoveredElement = getHoveredElementForBinding(pointerCoords, scene.getNonDeletedElements(), elementsMap);
159
+ const hoveredElement = getHoveredElementForBinding(pointerCoords, elementsMap);
82
160
  if (hoveredElement != null &&
83
161
  !isLinearElementSimpleAndAlreadyBoundOnOppositeEdge(linearElement, hoveredElement, "end")) {
84
162
  bindLinearElement(linearElement, hoveredElement, "end", elementsMap);
85
163
  }
86
164
  };
87
165
  export const bindLinearElement = (linearElement, hoveredElement, startOrEnd, elementsMap) => {
166
+ if (!isArrowElement(linearElement)) {
167
+ return;
168
+ }
88
169
  mutateElement(linearElement, {
89
170
  [startOrEnd === "start" ? "startBinding" : "endBinding"]: {
90
171
  elementId: hoveredElement.id,
@@ -107,15 +188,10 @@ const isLinearElementSimpleAndAlreadyBoundOnOppositeEdge = (linearElement, binda
107
188
  return isLinearElementSimpleAndAlreadyBound(linearElement, otherBinding?.elementId, bindableElement);
108
189
  };
109
190
  export const isLinearElementSimpleAndAlreadyBound = (linearElement, alreadyBoundToId, bindableElement) => {
110
- return (alreadyBoundToId === bindableElement.id && linearElement.points.length < 3);
111
- };
112
- export const unbindLinearElements = (elements, elementsMap) => {
113
- elements.forEach((element) => {
114
- if (isBindingElement(element)) {
115
- bindOrUnbindLinearElement(element, null, null, elementsMap);
116
- }
117
- });
191
+ return (alreadyBoundToId === bindableElement.id &&
192
+ isLinearElementSimple(linearElement));
118
193
  };
194
+ const isLinearElementSimple = (linearElement) => linearElement.points.length < 3;
119
195
  const unbindLinearElement = (linearElement, startOrEnd) => {
120
196
  const field = startOrEnd === "start" ? "startBinding" : "endBinding";
121
197
  const binding = linearElement[field];
@@ -125,8 +201,8 @@ const unbindLinearElement = (linearElement, startOrEnd) => {
125
201
  mutateElement(linearElement, { [field]: null });
126
202
  return binding.elementId;
127
203
  };
128
- export const getHoveredElementForBinding = (pointerCoords, elements, elementsMap) => {
129
- const hoveredElement = getElementAtPosition(elements, (element) => isBindableElement(element, false) &&
204
+ export const getHoveredElementForBinding = (pointerCoords, elementsMap) => {
205
+ const hoveredElement = getElementAtPosition([...elementsMap].map(([_, value]) => value), (element) => isBindableElement(element, false) &&
130
206
  bindingBorderTest(element, pointerCoords, elementsMap));
131
207
  return hoveredElement;
132
208
  };
@@ -147,34 +223,38 @@ const calculateFocusAndGap = (linearElement, hoveredElement, startOrEnd, element
147
223
  // done before the `changedElement` is updated, and the `newSize` is passed
148
224
  // in explicitly.
149
225
  export const updateBoundElements = (changedElement, elementsMap, options) => {
150
- const boundLinearElements = (changedElement.boundElements ?? []).filter((el) => el.type === "arrow");
151
- if (boundLinearElements.length === 0) {
152
- return;
153
- }
154
226
  const { newSize, simultaneouslyUpdated } = options ?? {};
155
227
  const simultaneouslyUpdatedElementIds = getSimultaneouslyUpdatedElementIds(simultaneouslyUpdated);
156
- const scene = Scene.getScene(changedElement);
157
- getNonDeletedElements(scene, boundLinearElements.map((el) => el.id)).forEach((element) => {
158
- if (!isLinearElement(element)) {
228
+ if (!isBindableElement(changedElement)) {
229
+ return;
230
+ }
231
+ boundElementsVisitor(elementsMap, changedElement, (element) => {
232
+ if (!isLinearElement(element) || element.isDeleted) {
159
233
  return;
160
234
  }
161
- const bindableElement = changedElement;
162
235
  // In case the boundElements are stale
163
- if (!doesNeedUpdate(element, bindableElement)) {
236
+ if (!doesNeedUpdate(element, changedElement)) {
164
237
  return;
165
238
  }
166
- const startBinding = maybeCalculateNewGapWhenScaling(bindableElement, element.startBinding, newSize);
167
- 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
+ };
168
243
  // `linearElement` is being moved/scaled already, just update the binding
169
244
  if (simultaneouslyUpdatedElementIds.has(element.id)) {
170
- mutateElement(element, { startBinding, endBinding });
245
+ mutateElement(element, bindings);
171
246
  return;
172
247
  }
173
- updateBoundPoint(element, "start", startBinding, changedElement, elementsMap);
174
- updateBoundPoint(element, "end", endBinding, changedElement, elementsMap);
175
- const boundText = getBoundTextElement(element, scene.getNonDeletedElementsMap());
176
- if (boundText) {
177
- 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);
178
258
  }
179
259
  });
180
260
  };
@@ -185,22 +265,18 @@ const doesNeedUpdate = (boundElement, changedElement) => {
185
265
  const getSimultaneouslyUpdatedElementIds = (simultaneouslyUpdated) => {
186
266
  return new Set((simultaneouslyUpdated || []).map((element) => element.id));
187
267
  };
188
- const updateBoundPoint = (linearElement, startOrEnd, binding, changedElement, elementsMap) => {
268
+ const updateBoundPoint = (linearElement, startOrEnd, binding, bindableElement, elementsMap) => {
189
269
  if (binding == null ||
190
270
  // We only need to update the other end if this is a 2 point line element
191
- (binding.elementId !== changedElement.id && linearElement.points.length > 2)) {
192
- return;
193
- }
194
- const bindingElement = Scene.getScene(linearElement).getElement(binding.elementId);
195
- if (bindingElement == null) {
196
- // We're not cleaning up after deleted elements atm., so handle this case
271
+ (binding.elementId !== bindableElement.id &&
272
+ linearElement.points.length > 2)) {
197
273
  return;
198
274
  }
199
- const direction = startOrEnd === "start" ? -1 : 1;
275
+ const direction = startOrEnd === "startBinding" ? -1 : 1;
200
276
  const edgePointIndex = direction === -1 ? 0 : linearElement.points.length - 1;
201
277
  const adjacentPointIndex = edgePointIndex - direction;
202
278
  const adjacentPoint = LinearElementEditor.getPointAtIndexGlobalCoordinates(linearElement, adjacentPointIndex, elementsMap);
203
- const focusPointAbsolute = determineFocusPoint(bindingElement, binding.focus, adjacentPoint, elementsMap);
279
+ const focusPointAbsolute = determineFocusPoint(bindableElement, binding.focus, adjacentPoint, elementsMap);
204
280
  let newEdgePoint;
205
281
  // The linear element was not originally pointing inside the bound shape,
206
282
  // we can point directly at the focus point
@@ -208,7 +284,7 @@ const updateBoundPoint = (linearElement, startOrEnd, binding, changedElement, el
208
284
  newEdgePoint = focusPointAbsolute;
209
285
  }
210
286
  else {
211
- const intersections = intersectElementWithLine(bindingElement, adjacentPoint, focusPointAbsolute, binding.gap, elementsMap);
287
+ const intersections = intersectElementWithLine(bindableElement, adjacentPoint, focusPointAbsolute, binding.gap, elementsMap);
212
288
  if (intersections.length === 0) {
213
289
  // This should never happen, since focusPoint should always be
214
290
  // inside the element, but just in case, bail out
@@ -224,7 +300,7 @@ const updateBoundPoint = (linearElement, startOrEnd, binding, changedElement, el
224
300
  index: edgePointIndex,
225
301
  point: LinearElementEditor.pointFromAbsoluteCoords(linearElement, newEdgePoint, elementsMap),
226
302
  },
227
- ], { [startOrEnd === "start" ? "startBinding" : "endBinding"]: binding });
303
+ ], { [startOrEnd]: binding });
228
304
  };
229
305
  const maybeCalculateNewGapWhenScaling = (changedElement, currentBinding, newSize) => {
230
306
  if (currentBinding == null || newSize == null) {
@@ -236,55 +312,13 @@ const maybeCalculateNewGapWhenScaling = (changedElement, currentBinding, newSize
236
312
  const newGap = Math.max(1, Math.min(maxBindingGap(changedElement, newWidth, newHeight), gap * (newWidth < newHeight ? newWidth / width : newHeight / height)));
237
313
  return { elementId, gap: newGap, focus };
238
314
  };
239
- // TODO: this is a bottleneck, optimise
240
- export const getEligibleElementsForBinding = (selectedElements, elements, elementsMap) => {
241
- const includedElementIds = new Set(selectedElements.map(({ id }) => id));
242
- return selectedElements.flatMap((selectedElement) => isBindingElement(selectedElement, false)
243
- ? getElligibleElementsForBindingElement(selectedElement, elements, elementsMap).filter((element) => !includedElementIds.has(element.id))
244
- : isBindableElement(selectedElement, false)
245
- ? getElligibleElementsForBindableElementAndWhere(selectedElement, elementsMap).filter((binding) => !includedElementIds.has(binding[0].id))
246
- : []);
247
- };
248
- const getElligibleElementsForBindingElement = (linearElement, elements, elementsMap) => {
249
- return [
250
- getElligibleElementForBindingElement(linearElement, "start", elements, elementsMap),
251
- getElligibleElementForBindingElement(linearElement, "end", elements, elementsMap),
252
- ].filter((element) => element != null);
253
- };
254
- const getElligibleElementForBindingElement = (linearElement, startOrEnd, elements, elementsMap) => {
255
- return getHoveredElementForBinding(getLinearElementEdgeCoors(linearElement, startOrEnd, elementsMap), elements, elementsMap);
315
+ const getElligibleElementForBindingElement = (linearElement, startOrEnd, elementsMap) => {
316
+ return getHoveredElementForBinding(getLinearElementEdgeCoors(linearElement, startOrEnd, elementsMap), elementsMap);
256
317
  };
257
318
  const getLinearElementEdgeCoors = (linearElement, startOrEnd, elementsMap) => {
258
319
  const index = startOrEnd === "start" ? 0 : -1;
259
320
  return tupleToCoors(LinearElementEditor.getPointAtIndexGlobalCoordinates(linearElement, index, elementsMap));
260
321
  };
261
- const getElligibleElementsForBindableElementAndWhere = (bindableElement, elementsMap) => {
262
- const scene = Scene.getScene(bindableElement);
263
- return scene
264
- .getNonDeletedElements()
265
- .map((element) => {
266
- if (!isBindingElement(element, false)) {
267
- return null;
268
- }
269
- const canBindStart = isLinearElementEligibleForNewBindingByBindable(element, "start", bindableElement, elementsMap);
270
- const canBindEnd = isLinearElementEligibleForNewBindingByBindable(element, "end", bindableElement, elementsMap);
271
- if (!canBindStart && !canBindEnd) {
272
- return null;
273
- }
274
- return [
275
- element,
276
- canBindStart && canBindEnd ? "both" : canBindStart ? "start" : "end",
277
- bindableElement,
278
- ];
279
- })
280
- .filter((maybeElement) => maybeElement != null);
281
- };
282
- const isLinearElementEligibleForNewBindingByBindable = (linearElement, startOrEnd, bindableElement, elementsMap) => {
283
- const existingBinding = linearElement[startOrEnd === "start" ? "startBinding" : "endBinding"];
284
- return (existingBinding == null &&
285
- !isLinearElementSimpleAndAlreadyBoundOnOppositeEdge(linearElement, bindableElement, startOrEnd) &&
286
- bindingBorderTest(bindableElement, getLinearElementEdgeCoors(linearElement, startOrEnd, elementsMap), elementsMap));
287
- };
288
322
  // We need to:
289
323
  // 1: Update elements not selected to point to duplicated elements
290
324
  // 2: Update duplicated elements to point to other duplicated elements
@@ -299,6 +333,7 @@ duplicatesServeAsOld) => {
299
333
  const allBoundElementIds = new Set();
300
334
  const allBindableElementIds = new Set();
301
335
  const shouldReverseRoles = duplicatesServeAsOld === "duplicatesServeAsOld";
336
+ const duplicateIdToOldId = new Map([...oldIdToDuplicatedId].map(([key, value]) => [value, key]));
302
337
  oldElements.forEach((oldElement) => {
303
338
  const { boundElements } = oldElement;
304
339
  if (boundElements != null && boundElements.length > 0) {
@@ -339,7 +374,8 @@ duplicatesServeAsOld) => {
339
374
  sceneElements
340
375
  .filter(({ id }) => allBindableElementIds.has(id))
341
376
  .forEach((bindableElement) => {
342
- const { boundElements } = bindableElement;
377
+ const oldElementId = duplicateIdToOldId.get(bindableElement.id);
378
+ const { boundElements } = sceneElements.find(({ id }) => id === oldElementId);
343
379
  if (boundElements != null && boundElements.length > 0) {
344
380
  mutateElement(bindableElement, {
345
381
  boundElements: boundElements.map((boundElement) => oldIdToDuplicatedId.has(boundElement.id)
@@ -364,51 +400,578 @@ const newBindingAfterDuplication = (binding, oldIdToDuplicatedId) => {
364
400
  };
365
401
  };
366
402
  export const fixBindingsAfterDeletion = (sceneElements, deletedElements) => {
367
- const deletedElementIds = new Set(deletedElements.map((element) => element.id));
368
- // non-deleted which bindings need to be updated
369
- const affectedElements = new Set();
370
- deletedElements.forEach((deletedElement) => {
371
- if (isBindableElement(deletedElement)) {
372
- deletedElement.boundElements?.forEach((element) => {
373
- if (!deletedElementIds.has(element.id)) {
374
- affectedElements.add(element.id);
375
- }
376
- });
377
- }
378
- else if (isBindingElement(deletedElement)) {
379
- if (deletedElement.startBinding) {
380
- affectedElements.add(deletedElement.startBinding.elementId);
381
- }
382
- if (deletedElement.endBinding) {
383
- affectedElements.add(deletedElement.endBinding.elementId);
384
- }
385
- }
403
+ const elements = arrayToMap(sceneElements);
404
+ for (const element of deletedElements) {
405
+ BoundElement.unbindAffected(elements, element, mutateElement);
406
+ BindableElement.unbindAffected(elements, element, mutateElement);
407
+ }
408
+ };
409
+ const newBoundElements = (boundElements, idsToRemove, elementsToAdd = []) => {
410
+ if (!boundElements) {
411
+ return null;
412
+ }
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;
416
+ };
417
+ const bindingBorderTest = (element, { x, y }, elementsMap) => {
418
+ const threshold = maxBindingGap(element, element.width, element.height);
419
+ const shape = getElementShape(element, elementsMap);
420
+ return isPointOnShape([x, y], shape, threshold);
421
+ };
422
+ export const maxBindingGap = (element, elementWidth, elementHeight) => {
423
+ // Aligns diamonds with rectangles
424
+ const shapeRatio = element.type === "diamond" ? 1 / Math.sqrt(2) : 1;
425
+ const smallerDimension = shapeRatio * Math.min(elementWidth, elementHeight);
426
+ // We make the bindable boundary bigger for bigger elements
427
+ return Math.max(16, Math.min(0.25 * smallerDimension, 32));
428
+ };
429
+ const distanceToBindableElement = (element, point, elementsMap) => {
430
+ switch (element.type) {
431
+ case "rectangle":
432
+ case "image":
433
+ case "text":
434
+ case "iframe":
435
+ case "embeddable":
436
+ case "frame":
437
+ case "magicframe":
438
+ return distanceToRectangle(element, point, elementsMap);
439
+ case "diamond":
440
+ return distanceToDiamond(element, point, elementsMap);
441
+ case "ellipse":
442
+ return distanceToEllipse(element, point, elementsMap);
443
+ }
444
+ };
445
+ const distanceToRectangle = (element, point, elementsMap) => {
446
+ const [, pointRel, hwidth, hheight] = pointRelativeToElement(element, point, elementsMap);
447
+ return Math.max(GAPoint.distanceToLine(pointRel, GALine.equation(0, 1, -hheight)), GAPoint.distanceToLine(pointRel, GALine.equation(1, 0, -hwidth)));
448
+ };
449
+ const distanceToDiamond = (element, point, elementsMap) => {
450
+ const [, pointRel, hwidth, hheight] = pointRelativeToElement(element, point, elementsMap);
451
+ const side = GALine.equation(hheight, hwidth, -hheight * hwidth);
452
+ return GAPoint.distanceToLine(pointRel, side);
453
+ };
454
+ const distanceToEllipse = (element, point, elementsMap) => {
455
+ const [pointRel, tangent] = ellipseParamsForTest(element, point, elementsMap);
456
+ return -GALine.sign(tangent) * GAPoint.distanceToLine(pointRel, tangent);
457
+ };
458
+ const ellipseParamsForTest = (element, point, elementsMap) => {
459
+ const [, pointRel, hwidth, hheight] = pointRelativeToElement(element, point, elementsMap);
460
+ const [px, py] = GAPoint.toTuple(pointRel);
461
+ // We're working in positive quadrant, so start with `t = 45deg`, `tx=cos(t)`
462
+ let tx = 0.707;
463
+ let ty = 0.707;
464
+ const a = hwidth;
465
+ const b = hheight;
466
+ // This is a numerical method to find the params tx, ty at which
467
+ // the ellipse has the closest point to the given point
468
+ [0, 1, 2, 3].forEach((_) => {
469
+ const xx = a * tx;
470
+ const yy = b * ty;
471
+ const ex = ((a * a - b * b) * tx ** 3) / a;
472
+ const ey = ((b * b - a * a) * ty ** 3) / b;
473
+ const rx = xx - ex;
474
+ const ry = yy - ey;
475
+ const qx = px - ex;
476
+ const qy = py - ey;
477
+ const r = Math.hypot(ry, rx);
478
+ const q = Math.hypot(qy, qx);
479
+ tx = Math.min(1, Math.max(0, ((qx * r) / q + ex) / a));
480
+ ty = Math.min(1, Math.max(0, ((qy * r) / q + ey) / b));
481
+ const t = Math.hypot(ty, tx);
482
+ tx /= t;
483
+ ty /= t;
386
484
  });
387
- sceneElements
388
- .filter(({ id }) => affectedElements.has(id))
389
- .forEach((element) => {
390
- if (isBindableElement(element)) {
391
- mutateElement(element, {
392
- boundElements: newBoundElementsAfterDeletion(element.boundElements, deletedElementIds),
393
- });
394
- }
395
- else if (isBindingElement(element)) {
396
- mutateElement(element, {
397
- startBinding: newBindingAfterDeletion(element.startBinding, deletedElementIds),
398
- endBinding: newBindingAfterDeletion(element.endBinding, deletedElementIds),
399
- });
485
+ const closestPoint = GA.point(a * tx, b * ty);
486
+ const tangent = GALine.orthogonalThrough(pointRel, closestPoint);
487
+ return [pointRel, tangent];
488
+ };
489
+ // Returns:
490
+ // 1. the point relative to the elements (x, y) position
491
+ // 2. the point relative to the element's center with positive (x, y)
492
+ // 3. half element width
493
+ // 4. half element height
494
+ //
495
+ // Note that for linear elements the (x, y) position is not at the
496
+ // top right corner of their boundary.
497
+ //
498
+ // Rectangles, diamonds and ellipses are symmetrical over axes,
499
+ // and other elements have a rectangular boundary,
500
+ // so we only need to perform hit tests for the positive quadrant.
501
+ const pointRelativeToElement = (element, pointTuple, elementsMap) => {
502
+ const point = GAPoint.from(pointTuple);
503
+ const [x1, y1, x2, y2] = getElementAbsoluteCoords(element, elementsMap);
504
+ const center = coordsCenter(x1, y1, x2, y2);
505
+ // GA has angle orientation opposite to `rotate`
506
+ const rotate = GATransform.rotation(center, element.angle);
507
+ const pointRotated = GATransform.apply(rotate, point);
508
+ const pointRelToCenter = GA.sub(pointRotated, GADirection.from(center));
509
+ const pointRelToCenterAbs = GAPoint.abs(pointRelToCenter);
510
+ const elementPos = GA.offset(element.x, element.y);
511
+ const pointRelToPos = GA.sub(pointRotated, elementPos);
512
+ const halfWidth = (x2 - x1) / 2;
513
+ const halfHeight = (y2 - y1) / 2;
514
+ return [pointRelToPos, pointRelToCenterAbs, halfWidth, halfHeight];
515
+ };
516
+ const relativizationToElementCenter = (element, elementsMap) => {
517
+ const [x1, y1, x2, y2] = getElementAbsoluteCoords(element, elementsMap);
518
+ const center = coordsCenter(x1, y1, x2, y2);
519
+ // GA has angle orientation opposite to `rotate`
520
+ const rotate = GATransform.rotation(center, element.angle);
521
+ const translate = GA.reverse(GATransform.translation(GADirection.from(center)));
522
+ return GATransform.compose(rotate, translate);
523
+ };
524
+ const coordsCenter = (x1, y1, x2, y2) => {
525
+ return GA.point((x1 + x2) / 2, (y1 + y2) / 2);
526
+ };
527
+ // The focus distance is the oriented ratio between the size of
528
+ // the `element` and the "focus image" of the element on which
529
+ // all focus points lie, so it's a number between -1 and 1.
530
+ // The line going through `a` and `b` is a tangent to the "focus image"
531
+ // of the element.
532
+ const determineFocusDistance = (element,
533
+ // Point on the line, in absolute coordinates
534
+ a,
535
+ // Another point on the line, in absolute coordinates (closer to element)
536
+ b, elementsMap) => {
537
+ const relateToCenter = relativizationToElementCenter(element, elementsMap);
538
+ const aRel = GATransform.apply(relateToCenter, GAPoint.from(a));
539
+ const bRel = GATransform.apply(relateToCenter, GAPoint.from(b));
540
+ const line = GALine.through(aRel, bRel);
541
+ const q = element.height / element.width;
542
+ const hwidth = element.width / 2;
543
+ const hheight = element.height / 2;
544
+ const n = line[2];
545
+ const m = line[3];
546
+ const c = line[1];
547
+ const mabs = Math.abs(m);
548
+ const nabs = Math.abs(n);
549
+ let ret;
550
+ switch (element.type) {
551
+ case "rectangle":
552
+ case "image":
553
+ case "text":
554
+ case "iframe":
555
+ case "embeddable":
556
+ case "frame":
557
+ case "magicframe":
558
+ ret = c / (hwidth * (nabs + q * mabs));
559
+ break;
560
+ case "diamond":
561
+ ret = mabs < nabs ? c / (nabs * hwidth) : c / (mabs * hheight);
562
+ break;
563
+ case "ellipse":
564
+ ret = c / (hwidth * Math.sqrt(n ** 2 + q ** 2 * m ** 2));
565
+ break;
566
+ }
567
+ return ret || 0;
568
+ };
569
+ const determineFocusPoint = (element,
570
+ // The oriented, relative distance from the center of `element` of the
571
+ // returned focusPoint
572
+ focus, adjecentPoint, elementsMap) => {
573
+ if (focus === 0) {
574
+ const [x1, y1, x2, y2] = getElementAbsoluteCoords(element, elementsMap);
575
+ const center = coordsCenter(x1, y1, x2, y2);
576
+ return GAPoint.toTuple(center);
577
+ }
578
+ const relateToCenter = relativizationToElementCenter(element, elementsMap);
579
+ const adjecentPointRel = GATransform.apply(relateToCenter, GAPoint.from(adjecentPoint));
580
+ const reverseRelateToCenter = GA.reverse(relateToCenter);
581
+ let point;
582
+ switch (element.type) {
583
+ case "rectangle":
584
+ case "image":
585
+ case "text":
586
+ case "diamond":
587
+ case "iframe":
588
+ case "embeddable":
589
+ case "frame":
590
+ case "magicframe":
591
+ point = findFocusPointForRectangulars(element, focus, adjecentPointRel);
592
+ break;
593
+ case "ellipse":
594
+ point = findFocusPointForEllipse(element, focus, adjecentPointRel);
595
+ break;
596
+ }
597
+ return GAPoint.toTuple(GATransform.apply(reverseRelateToCenter, point));
598
+ };
599
+ // Returns 2 or 0 intersection points between line going through `a` and `b`
600
+ // and the `element`, in ascending order of distance from `a`.
601
+ const intersectElementWithLine = (element,
602
+ // Point on the line, in absolute coordinates
603
+ a,
604
+ // Another point on the line, in absolute coordinates
605
+ b,
606
+ // If given, the element is inflated by this value
607
+ gap = 0, elementsMap) => {
608
+ const relateToCenter = relativizationToElementCenter(element, elementsMap);
609
+ const aRel = GATransform.apply(relateToCenter, GAPoint.from(a));
610
+ const bRel = GATransform.apply(relateToCenter, GAPoint.from(b));
611
+ const line = GALine.through(aRel, bRel);
612
+ const reverseRelateToCenter = GA.reverse(relateToCenter);
613
+ const intersections = getSortedElementLineIntersections(element, line, aRel, gap);
614
+ return intersections.map((point) => GAPoint.toTuple(GATransform.apply(reverseRelateToCenter, point)));
615
+ };
616
+ const getSortedElementLineIntersections = (element,
617
+ // Relative to element center
618
+ line,
619
+ // Relative to element center
620
+ nearPoint, gap = 0) => {
621
+ let intersections;
622
+ switch (element.type) {
623
+ case "rectangle":
624
+ case "image":
625
+ case "text":
626
+ case "diamond":
627
+ case "iframe":
628
+ case "embeddable":
629
+ case "frame":
630
+ case "magicframe":
631
+ const corners = getCorners(element);
632
+ intersections = corners
633
+ .flatMap((point, i) => {
634
+ const edge = [point, corners[(i + 1) % 4]];
635
+ return intersectSegment(line, offsetSegment(edge, gap));
636
+ })
637
+ .concat(corners.flatMap((point) => getCircleIntersections(point, gap, line)));
638
+ break;
639
+ case "ellipse":
640
+ intersections = getEllipseIntersections(element, gap, line);
641
+ break;
642
+ }
643
+ if (intersections.length < 2) {
644
+ // Ignore the "edge" case of only intersecting with a single corner
645
+ return [];
646
+ }
647
+ const sortedIntersections = intersections.sort((i1, i2) => GAPoint.distance(i1, nearPoint) - GAPoint.distance(i2, nearPoint));
648
+ return [
649
+ sortedIntersections[0],
650
+ sortedIntersections[sortedIntersections.length - 1],
651
+ ];
652
+ };
653
+ const getCorners = (element, scale = 1) => {
654
+ const hx = (scale * element.width) / 2;
655
+ const hy = (scale * element.height) / 2;
656
+ switch (element.type) {
657
+ case "rectangle":
658
+ case "image":
659
+ case "text":
660
+ case "iframe":
661
+ case "embeddable":
662
+ case "frame":
663
+ case "magicframe":
664
+ return [
665
+ GA.point(hx, hy),
666
+ GA.point(hx, -hy),
667
+ GA.point(-hx, -hy),
668
+ GA.point(-hx, hy),
669
+ ];
670
+ case "diamond":
671
+ return [
672
+ GA.point(0, hy),
673
+ GA.point(hx, 0),
674
+ GA.point(0, -hy),
675
+ GA.point(-hx, 0),
676
+ ];
677
+ }
678
+ };
679
+ // Returns intersection of `line` with `segment`, with `segment` moved by
680
+ // `gap` in its polar direction.
681
+ // If intersection coincides with second segment point returns empty array.
682
+ const intersectSegment = (line, segment) => {
683
+ const [a, b] = segment;
684
+ const aDist = GAPoint.distanceToLine(a, line);
685
+ const bDist = GAPoint.distanceToLine(b, line);
686
+ if (aDist * bDist >= 0) {
687
+ // The intersection is outside segment `(a, b)`
688
+ return [];
689
+ }
690
+ return [GAPoint.intersect(line, GALine.through(a, b))];
691
+ };
692
+ const offsetSegment = (segment, distance) => {
693
+ const [a, b] = segment;
694
+ const offset = GATransform.translationOrthogonal(GADirection.fromTo(a, b), distance);
695
+ return [GATransform.apply(offset, a), GATransform.apply(offset, b)];
696
+ };
697
+ const getEllipseIntersections = (element, gap, line) => {
698
+ const a = element.width / 2 + gap;
699
+ const b = element.height / 2 + gap;
700
+ const m = line[2];
701
+ const n = line[3];
702
+ const c = line[1];
703
+ const squares = a * a * m * m + b * b * n * n;
704
+ const discr = squares - c * c;
705
+ if (squares === 0 || discr <= 0) {
706
+ return [];
707
+ }
708
+ const discrRoot = Math.sqrt(discr);
709
+ const xn = -a * a * m * c;
710
+ const yn = -b * b * n * c;
711
+ return [
712
+ GA.point((xn + a * b * n * discrRoot) / squares, (yn - a * b * m * discrRoot) / squares),
713
+ GA.point((xn - a * b * n * discrRoot) / squares, (yn + a * b * m * discrRoot) / squares),
714
+ ];
715
+ };
716
+ const getCircleIntersections = (center, radius, line) => {
717
+ if (radius === 0) {
718
+ return GAPoint.distanceToLine(line, center) === 0 ? [center] : [];
719
+ }
720
+ const m = line[2];
721
+ const n = line[3];
722
+ const c = line[1];
723
+ const [a, b] = GAPoint.toTuple(center);
724
+ const r = radius;
725
+ const squares = m * m + n * n;
726
+ const discr = r * r * squares - (m * a + n * b + c) ** 2;
727
+ if (squares === 0 || discr <= 0) {
728
+ return [];
729
+ }
730
+ const discrRoot = Math.sqrt(discr);
731
+ const xn = a * n * n - b * m * n - m * c;
732
+ const yn = b * m * m - a * m * n - n * c;
733
+ return [
734
+ GA.point((xn + n * discrRoot) / squares, (yn - m * discrRoot) / squares),
735
+ GA.point((xn - n * discrRoot) / squares, (yn + m * discrRoot) / squares),
736
+ ];
737
+ };
738
+ // The focus point is the tangent point of the "focus image" of the
739
+ // `element`, where the tangent goes through `point`.
740
+ const findFocusPointForEllipse = (ellipse,
741
+ // Between -1 and 1 (not 0) the relative size of the "focus image" of
742
+ // the element on which the focus point lies
743
+ relativeDistance,
744
+ // The point for which we're trying to find the focus point, relative
745
+ // to the ellipse center.
746
+ point) => {
747
+ const relativeDistanceAbs = Math.abs(relativeDistance);
748
+ const a = (ellipse.width * relativeDistanceAbs) / 2;
749
+ const b = (ellipse.height * relativeDistanceAbs) / 2;
750
+ const orientation = Math.sign(relativeDistance);
751
+ const [px, pyo] = GAPoint.toTuple(point);
752
+ // The calculation below can't handle py = 0
753
+ const py = pyo === 0 ? 0.0001 : pyo;
754
+ const squares = px ** 2 * b ** 2 + py ** 2 * a ** 2;
755
+ // Tangent mx + ny + 1 = 0
756
+ const m = (-px * b ** 2 +
757
+ orientation * py * Math.sqrt(Math.max(0, squares - a ** 2 * b ** 2))) /
758
+ squares;
759
+ let n = (-m * px - 1) / py;
760
+ if (n === 0) {
761
+ // if zero {-0, 0}, fall back to a same-sign value in the similar range
762
+ n = (Object.is(n, -0) ? -1 : 1) * 0.01;
763
+ }
764
+ const x = -(a ** 2 * m) / (n ** 2 * b ** 2 + m ** 2 * a ** 2);
765
+ return GA.point(x, (-m * x - 1) / n);
766
+ };
767
+ const findFocusPointForRectangulars = (element,
768
+ // Between -1 and 1 for how far away should the focus point be relative
769
+ // to the size of the element. Sign determines orientation.
770
+ relativeDistance,
771
+ // The point for which we're trying to find the focus point, relative
772
+ // to the element center.
773
+ point) => {
774
+ const relativeDistanceAbs = Math.abs(relativeDistance);
775
+ const orientation = Math.sign(relativeDistance);
776
+ const corners = getCorners(element, relativeDistanceAbs);
777
+ let maxDistance = 0;
778
+ let tangentPoint = null;
779
+ corners.forEach((corner) => {
780
+ const distance = orientation * GALine.through(point, corner)[1];
781
+ if (distance > maxDistance) {
782
+ maxDistance = distance;
783
+ tangentPoint = corner;
400
784
  }
401
785
  });
786
+ return tangentPoint;
402
787
  };
403
- const newBindingAfterDeletion = (binding, deletedElementIds) => {
404
- if (binding == null || deletedElementIds.has(binding.elementId)) {
405
- return null;
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
+ });
406
806
  }
407
- return binding;
408
807
  };
409
- const newBoundElementsAfterDeletion = (boundElements, deletedElementIds) => {
410
- if (!boundElements) {
411
- return null;
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
+ }
412
829
  }
413
- return boundElements.filter((ele) => !deletedElementIds.has(ele.id));
414
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
+ }