@excalidraw/excalidraw 0.18.0-abeeaeb → 0.18.0-afa3a65

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 (389) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/dist/dev/{chunk-6WU4HLK7.js → chunk-N7DCBD6G.js} +293 -43
  3. package/dist/dev/chunk-N7DCBD6G.js.map +7 -0
  4. package/dist/dev/{chunk-7QNTKOP3.js → chunk-NC5N2LFL.js} +8 -1
  5. package/dist/dev/chunk-NC5N2LFL.js.map +7 -0
  6. package/dist/dev/chunk-Q67DF2PJ.js +69 -0
  7. package/dist/dev/chunk-Q67DF2PJ.js.map +7 -0
  8. package/dist/dev/data/{image-OPX5T4TO.js → image-KWAGZKDR.js} +2 -2
  9. package/dist/dev/index.css +25 -3
  10. package/dist/dev/index.css.map +2 -2
  11. package/dist/dev/index.js +2533 -1571
  12. package/dist/dev/index.js.map +4 -4
  13. package/dist/dev/locales/{ar-SA-YEOLME2Y.js → ar-SA-EW44IW4V.js} +14 -2
  14. package/dist/dev/locales/ar-SA-EW44IW4V.js.map +7 -0
  15. package/dist/dev/locales/{az-AZ-DQL36U4O.js → az-AZ-AI7WAYA2.js} +14 -2
  16. package/dist/dev/locales/az-AZ-AI7WAYA2.js.map +7 -0
  17. package/dist/dev/locales/{bg-BG-LG6R5FEQ.js → bg-BG-43ZNGDXF.js} +14 -2
  18. package/dist/dev/locales/bg-BG-43ZNGDXF.js.map +7 -0
  19. package/dist/dev/locales/{bn-BD-W63P7JT5.js → bn-BD-PU4CN7NP.js} +14 -2
  20. package/dist/dev/locales/bn-BD-PU4CN7NP.js.map +7 -0
  21. package/dist/dev/locales/{bn-IN-SCHACAA6.js → bn-IN-54CF43JL.js} +14 -2
  22. package/dist/dev/locales/bn-IN-54CF43JL.js.map +7 -0
  23. package/dist/dev/locales/{ca-ES-XP3CQTWV.js → ca-ES-RHJO3QDO.js} +14 -2
  24. package/dist/dev/locales/ca-ES-RHJO3QDO.js.map +7 -0
  25. package/dist/dev/locales/{cs-CZ-EXLEOJMD.js → cs-CZ-ZRSAO3BA.js} +14 -2
  26. package/dist/dev/locales/cs-CZ-ZRSAO3BA.js.map +7 -0
  27. package/dist/dev/locales/{da-DK-46ONLZRX.js → da-DK-OAB6DEJX.js} +14 -2
  28. package/dist/dev/locales/da-DK-OAB6DEJX.js.map +7 -0
  29. package/dist/dev/locales/{de-CH-A5QH3YGW.js → de-CH-QF7JLXTF.js} +14 -2
  30. package/dist/dev/locales/de-CH-QF7JLXTF.js.map +7 -0
  31. package/dist/dev/locales/{de-DE-FVCCKR5N.js → de-DE-5ZO4KOPT.js} +14 -2
  32. package/dist/dev/locales/de-DE-5ZO4KOPT.js.map +7 -0
  33. package/dist/dev/locales/{el-GR-SB4MX5JS.js → el-GR-F74ZSUEO.js} +14 -2
  34. package/dist/dev/locales/el-GR-F74ZSUEO.js.map +7 -0
  35. package/dist/dev/locales/{en-YJ3ZYXZZ.js → en-Z6IIINMM.js} +2 -2
  36. package/dist/dev/locales/{es-ES-VRTYQG6S.js → es-ES-3B3IENPS.js} +14 -2
  37. package/dist/dev/locales/es-ES-3B3IENPS.js.map +7 -0
  38. package/dist/dev/locales/{eu-ES-3OHEU2YV.js → eu-ES-NH447TVU.js} +14 -2
  39. package/dist/dev/locales/eu-ES-NH447TVU.js.map +7 -0
  40. package/dist/dev/locales/{fa-IR-74WR2KXF.js → fa-IR-V44PNTTK.js} +46 -34
  41. package/dist/dev/locales/fa-IR-V44PNTTK.js.map +7 -0
  42. package/dist/dev/locales/{fi-FI-XZQC4II2.js → fi-FI-ZXSYWCC4.js} +14 -2
  43. package/dist/dev/locales/fi-FI-ZXSYWCC4.js.map +7 -0
  44. package/dist/dev/locales/{fr-FR-RABBDBKM.js → fr-FR-RJSOSEYS.js} +25 -13
  45. package/dist/dev/locales/fr-FR-RJSOSEYS.js.map +7 -0
  46. package/dist/dev/locales/{gl-ES-OU3Q6XUE.js → gl-ES-NAUVMVFY.js} +14 -2
  47. package/dist/dev/locales/gl-ES-NAUVMVFY.js.map +7 -0
  48. package/dist/dev/locales/{he-IL-6NCD5D54.js → he-IL-JBKWWR75.js} +67 -55
  49. package/dist/dev/locales/he-IL-JBKWWR75.js.map +7 -0
  50. package/dist/dev/locales/{hi-IN-M54WKOJI.js → hi-IN-SD773MVZ.js} +14 -2
  51. package/dist/dev/locales/hi-IN-SD773MVZ.js.map +7 -0
  52. package/dist/dev/locales/{hu-HU-HAW63BCI.js → hu-HU-OTA7GOAV.js} +14 -2
  53. package/dist/dev/locales/hu-HU-OTA7GOAV.js.map +7 -0
  54. package/dist/dev/locales/{id-ID-TFSPHGWX.js → id-ID-KGCGQFTT.js} +100 -88
  55. package/dist/dev/locales/id-ID-KGCGQFTT.js.map +7 -0
  56. package/dist/dev/locales/{it-IT-MH3BAO5W.js → it-IT-EWGEXMVK.js} +25 -13
  57. package/dist/dev/locales/it-IT-EWGEXMVK.js.map +7 -0
  58. package/dist/dev/locales/{ja-JP-UGJBHLX6.js → ja-JP-YMGRGBPS.js} +17 -5
  59. package/dist/dev/locales/ja-JP-YMGRGBPS.js.map +7 -0
  60. package/dist/dev/locales/{kaa-5ZUEYWIM.js → kaa-RRE7XUCW.js} +14 -2
  61. package/dist/dev/locales/kaa-RRE7XUCW.js.map +7 -0
  62. package/dist/dev/locales/{kab-KAB-RLAZQZSM.js → kab-KAB-ZCYVOJU4.js} +14 -2
  63. package/dist/dev/locales/kab-KAB-ZCYVOJU4.js.map +7 -0
  64. package/dist/dev/locales/{kk-KZ-CIP7GOIF.js → kk-KZ-TO6XEFJC.js} +14 -2
  65. package/dist/dev/locales/kk-KZ-TO6XEFJC.js.map +7 -0
  66. package/dist/dev/locales/{km-KH-YMR4247H.js → km-KH-3HTDL5HB.js} +14 -2
  67. package/dist/dev/locales/km-KH-3HTDL5HB.js.map +7 -0
  68. package/dist/dev/locales/{ko-KR-WGKQKR2R.js → ko-KR-O4L4O7L6.js} +14 -2
  69. package/dist/dev/locales/ko-KR-O4L4O7L6.js.map +7 -0
  70. package/dist/dev/locales/{ku-TR-ZSJN6TN6.js → ku-TR-AFJWDY67.js} +14 -2
  71. package/dist/dev/locales/ku-TR-AFJWDY67.js.map +7 -0
  72. package/dist/dev/locales/{lt-LT-FT6ZGIZP.js → lt-LT-7QOT2VDQ.js} +14 -2
  73. package/dist/dev/locales/lt-LT-7QOT2VDQ.js.map +7 -0
  74. package/dist/dev/locales/{lv-LV-U74YKDPR.js → lv-LV-WV6C4NYF.js} +14 -2
  75. package/dist/dev/locales/lv-LV-WV6C4NYF.js.map +7 -0
  76. package/dist/dev/locales/{mr-IN-KN72LOIA.js → mr-IN-3TLYWOEI.js} +14 -2
  77. package/dist/dev/locales/mr-IN-3TLYWOEI.js.map +7 -0
  78. package/dist/dev/locales/{my-MM-E57NLQ7W.js → my-MM-NNL2QJT3.js} +14 -2
  79. package/dist/dev/locales/my-MM-NNL2QJT3.js.map +7 -0
  80. package/dist/dev/locales/{nb-NO-FYQDWD7X.js → nb-NO-PG3XLMEV.js} +14 -2
  81. package/dist/dev/locales/nb-NO-PG3XLMEV.js.map +7 -0
  82. package/dist/dev/locales/{nl-NL-D5MZQRAC.js → nl-NL-MMOYEKKQ.js} +14 -2
  83. package/dist/dev/locales/nl-NL-MMOYEKKQ.js.map +7 -0
  84. package/dist/dev/locales/{nn-NO-5ZEUZJV4.js → nn-NO-AAC2I2YX.js} +14 -2
  85. package/dist/dev/locales/nn-NO-AAC2I2YX.js.map +7 -0
  86. package/dist/dev/locales/{oc-FR-MVW6LDAP.js → oc-FR-SR6MFB4N.js} +14 -2
  87. package/dist/dev/locales/oc-FR-SR6MFB4N.js.map +7 -0
  88. package/dist/dev/locales/{pa-IN-2NH3SVNI.js → pa-IN-ADGMQLQI.js} +14 -2
  89. package/dist/dev/locales/pa-IN-ADGMQLQI.js.map +7 -0
  90. package/dist/dev/locales/{percentages-QBBLQLIV.js → percentages-X2QIQ6XJ.js} +2 -2
  91. package/dist/dev/locales/{pl-PL-M6LYWLHY.js → pl-PL-FNIPTMVP.js} +14 -2
  92. package/dist/dev/locales/pl-PL-FNIPTMVP.js.map +7 -0
  93. package/dist/dev/locales/{pt-BR-27M3CCS7.js → pt-BR-67FMCDNE.js} +14 -2
  94. package/dist/dev/locales/pt-BR-67FMCDNE.js.map +7 -0
  95. package/dist/dev/locales/{pt-PT-V3C226NP.js → pt-PT-4G3GI4SF.js} +14 -2
  96. package/dist/dev/locales/pt-PT-4G3GI4SF.js.map +7 -0
  97. package/dist/dev/locales/{ro-RO-S4GNBAJI.js → ro-RO-CUZFN555.js} +25 -13
  98. package/dist/dev/locales/ro-RO-CUZFN555.js.map +7 -0
  99. package/dist/dev/locales/{ru-RU-CRRT5JUZ.js → ru-RU-4GHINTII.js} +14 -2
  100. package/dist/dev/locales/ru-RU-4GHINTII.js.map +7 -0
  101. package/dist/dev/locales/{si-LK-APMICZ7H.js → si-LK-SSNT7T4A.js} +14 -2
  102. package/dist/dev/locales/si-LK-SSNT7T4A.js.map +7 -0
  103. package/dist/dev/locales/{sk-SK-7ZFDZG6Y.js → sk-SK-J7TKZQEH.js} +14 -2
  104. package/dist/dev/locales/sk-SK-J7TKZQEH.js.map +7 -0
  105. package/dist/dev/locales/{sl-SI-BBENCX7D.js → sl-SI-SIBMLDYY.js} +130 -118
  106. package/dist/dev/locales/sl-SI-SIBMLDYY.js.map +7 -0
  107. package/dist/dev/locales/{sv-SE-35QJIOEW.js → sv-SE-6GYGFZNL.js} +25 -13
  108. package/dist/dev/locales/sv-SE-6GYGFZNL.js.map +7 -0
  109. package/dist/dev/locales/{ta-IN-4N5CFIWZ.js → ta-IN-7AW6CTGA.js} +14 -2
  110. package/dist/dev/locales/ta-IN-7AW6CTGA.js.map +7 -0
  111. package/dist/dev/locales/{th-TH-2F4V4IDB.js → th-TH-FP7ULYYM.js} +23 -11
  112. package/dist/dev/locales/th-TH-FP7ULYYM.js.map +7 -0
  113. package/dist/dev/locales/{tr-TR-NDFP3F7P.js → tr-TR-UDQGNXAG.js} +14 -2
  114. package/dist/dev/locales/tr-TR-UDQGNXAG.js.map +7 -0
  115. package/dist/dev/locales/{uk-UA-4I6VBQZ5.js → uk-UA-25HL2NCU.js} +51 -39
  116. package/dist/dev/locales/uk-UA-25HL2NCU.js.map +7 -0
  117. package/dist/dev/locales/{uz-UZ-UVKC7UNZ.js → uz-UZ-OPSBAY4H.js} +14 -2
  118. package/dist/dev/locales/uz-UZ-OPSBAY4H.js.map +7 -0
  119. package/dist/dev/locales/{vi-VN-UQCETDRL.js → vi-VN-DK367UGA.js} +14 -2
  120. package/dist/dev/locales/vi-VN-DK367UGA.js.map +7 -0
  121. package/dist/dev/locales/{zh-CN-RSRHKN75.js → zh-CN-QCVKNWUH.js} +14 -2
  122. package/dist/dev/locales/zh-CN-QCVKNWUH.js.map +7 -0
  123. package/dist/dev/locales/{zh-HK-XSFQ32U4.js → zh-HK-WFGYHWPG.js} +14 -2
  124. package/dist/dev/locales/zh-HK-WFGYHWPG.js.map +7 -0
  125. package/dist/dev/locales/{zh-TW-KFVYWRFJ.js → zh-TW-WHQS4ZSD.js} +33 -21
  126. package/dist/dev/locales/zh-TW-WHQS4ZSD.js.map +7 -0
  127. package/dist/prod/chunk-4SOEAONT.js +4 -0
  128. package/dist/prod/chunk-DYU5D34O.js +1 -0
  129. package/dist/prod/{chunk-FLYJHZSQ.js → chunk-RUX4WMZV.js} +6 -6
  130. package/dist/prod/data/image-EJJKRVD3.js +1 -0
  131. package/dist/prod/index.css +1 -1
  132. package/dist/prod/index.js +66 -97
  133. package/dist/prod/locales/{ar-SA-PQUY64WN.js → ar-SA-5WIASEJP.js} +5 -5
  134. package/dist/prod/locales/az-AZ-V5EUQD6C.js +1 -0
  135. package/dist/prod/locales/bg-BG-EXASCMTR.js +5 -0
  136. package/dist/prod/locales/bn-BD-U4SYNFCO.js +3 -0
  137. package/dist/prod/locales/bn-IN-HKDJIITE.js +3 -0
  138. package/dist/prod/locales/ca-ES-2KGUU5XB.js +8 -0
  139. package/dist/prod/locales/cs-CZ-VUCGPRML.js +7 -0
  140. package/dist/prod/locales/da-DK-NNDP2IVP.js +2 -0
  141. package/dist/prod/locales/de-CH-I7RAVIZN.js +11 -0
  142. package/dist/prod/locales/de-DE-WBQ3DQLR.js +11 -0
  143. package/dist/prod/locales/el-GR-TYQHVGXW.js +7 -0
  144. package/dist/prod/locales/{en-SJ2YIMFF.js → en-GNC3RJIS.js} +1 -1
  145. package/dist/prod/locales/es-ES-JEUOREKJ.js +12 -0
  146. package/dist/prod/locales/eu-ES-SO5DEEAN.js +8 -0
  147. package/dist/prod/locales/fa-IR-I4JNTJHK.js +9 -0
  148. package/dist/prod/locales/fi-FI-REAEF6HQ.js +6 -0
  149. package/dist/prod/locales/fr-FR-SUCL7J6B.js +12 -0
  150. package/dist/prod/locales/gl-ES-KHCSOGVH.js +6 -0
  151. package/dist/prod/locales/he-IL-JYXVXV2Q.js +9 -0
  152. package/dist/prod/locales/hi-IN-BU52H3BO.js +3 -0
  153. package/dist/prod/locales/hu-HU-OWADXDQ3.js +3 -0
  154. package/dist/prod/locales/id-ID-2WY7E4VX.js +8 -0
  155. package/dist/prod/locales/it-IT-INVHSAJF.js +12 -0
  156. package/dist/prod/locales/ja-JP-JBNTKYP4.js +12 -0
  157. package/dist/prod/locales/kaa-TC3VIB7V.js +1 -0
  158. package/dist/prod/locales/kab-KAB-UOUDSQKM.js +4 -0
  159. package/dist/prod/locales/kk-KZ-P5H2X7YS.js +1 -0
  160. package/dist/prod/locales/{km-KH-PCWDKPHP.js → km-KH-IHMV2US7.js} +4 -4
  161. package/dist/prod/locales/ko-KR-ZTMANIDF.js +5 -0
  162. package/dist/prod/locales/ku-TR-GPJTRB5G.js +6 -0
  163. package/dist/prod/locales/lt-LT-V3XDOK3P.js +3 -0
  164. package/dist/prod/locales/lv-LV-DVQ3FADO.js +4 -0
  165. package/dist/prod/locales/mr-IN-VZ6HH5FE.js +9 -0
  166. package/dist/prod/locales/my-MM-XYKWHRK6.js +1 -0
  167. package/dist/prod/locales/nb-NO-UNO2GGZJ.js +8 -0
  168. package/dist/prod/locales/nl-NL-76EFHT4P.js +13 -0
  169. package/dist/prod/locales/nn-NO-CFKD7ABE.js +4 -0
  170. package/dist/prod/locales/oc-FR-YBJTCJ3J.js +4 -0
  171. package/dist/prod/locales/pa-IN-SNOXSMRV.js +4 -0
  172. package/dist/prod/locales/percentages-LWOC67ZH.js +1 -0
  173. package/dist/prod/locales/pl-PL-BSY6YFZ3.js +12 -0
  174. package/dist/prod/locales/pt-BR-CZDV62R3.js +10 -0
  175. package/dist/prod/locales/pt-PT-JO57XJJW.js +12 -0
  176. package/dist/prod/locales/ro-RO-UZ5ICYYN.js +12 -0
  177. package/dist/prod/locales/ru-RU-AN7JPREC.js +10 -0
  178. package/dist/prod/locales/si-LK-7CBLD6QQ.js +1 -0
  179. package/dist/prod/locales/sk-SK-SWR6DKBI.js +7 -0
  180. package/dist/prod/locales/sl-SI-QY5KCFGA.js +8 -0
  181. package/dist/prod/locales/sv-SE-O3OFCY3J.js +12 -0
  182. package/dist/prod/locales/ta-IN-V6NHHU6Z.js +6 -0
  183. package/dist/prod/locales/th-TH-WLSZUSBX.js +1 -0
  184. package/dist/prod/locales/tr-TR-GUFYG22B.js +4 -0
  185. package/dist/prod/locales/uk-UA-K6SV5NFQ.js +6 -0
  186. package/dist/prod/locales/uz-UZ-TVKTZO2G.js +1 -0
  187. package/dist/prod/locales/vi-VN-7FKFXJNO.js +7 -0
  188. package/dist/prod/locales/zh-CN-AOKVLNNK.js +11 -0
  189. package/dist/prod/locales/zh-HK-CDKPF5DC.js +1 -0
  190. package/dist/prod/locales/zh-TW-ZVGYESGW.js +13 -0
  191. package/dist/types/common/src/colors.d.ts +8 -0
  192. package/dist/types/common/src/constants.d.ts +44 -0
  193. package/dist/types/common/src/keys.d.ts +2 -0
  194. package/dist/types/common/src/random.d.ts +7 -0
  195. package/dist/types/element/src/Scene.d.ts +1 -1
  196. package/dist/types/element/src/comparisons.d.ts +5 -3
  197. package/dist/types/element/src/delta.d.ts +23 -1
  198. package/dist/types/element/src/flowchart.d.ts +5 -1
  199. package/dist/types/element/src/frame.d.ts +2 -2
  200. package/dist/types/element/src/index.d.ts +1 -0
  201. package/dist/types/element/src/linearElementEditor.d.ts +10 -0
  202. package/dist/types/element/src/mutateElement.d.ts +1 -1
  203. package/dist/types/element/src/newElement.d.ts +24 -2
  204. package/dist/types/element/src/sizeHelpers.d.ts +6 -0
  205. package/dist/types/element/src/stickyNote.d.ts +183 -0
  206. package/dist/types/element/src/textElement.d.ts +2 -1
  207. package/dist/types/element/src/transform.d.ts +25 -6
  208. package/dist/types/element/src/typeChecks.d.ts +3 -2
  209. package/dist/types/element/src/types.d.ts +35 -6
  210. package/dist/types/element/src/utils.d.ts +7 -3
  211. package/dist/types/excalidraw/actions/actionAddToLibrary.d.ts +12 -0
  212. package/dist/types/excalidraw/actions/actionAlign.d.ts +6 -6
  213. package/dist/types/excalidraw/actions/actionBoundText.d.ts +8 -0
  214. package/dist/types/excalidraw/actions/actionCanvas.d.ts +28 -0
  215. package/dist/types/excalidraw/actions/actionClipboard.d.ts +8 -0
  216. package/dist/types/excalidraw/actions/actionCropEditor.d.ts +4 -0
  217. package/dist/types/excalidraw/actions/actionDeleteSelected.d.ts +13 -1
  218. package/dist/types/excalidraw/actions/actionDeselect.d.ts +4 -0
  219. package/dist/types/excalidraw/actions/actionDistribute.d.ts +2 -2
  220. package/dist/types/excalidraw/actions/actionElementLink.d.ts +4 -0
  221. package/dist/types/excalidraw/actions/actionElementLock.d.ts +8 -0
  222. package/dist/types/excalidraw/actions/actionExport.d.ts +8 -0
  223. package/dist/types/excalidraw/actions/actionFinalize.d.ts +1 -0
  224. package/dist/types/excalidraw/actions/actionFrame.d.ts +63 -1
  225. package/dist/types/excalidraw/actions/actionGroup.d.ts +8 -0
  226. package/dist/types/excalidraw/actions/actionLinearEditor.d.ts +55 -1
  227. package/dist/types/excalidraw/actions/actionLink.d.ts +4 -0
  228. package/dist/types/excalidraw/actions/actionMenu.d.ts +4 -0
  229. package/dist/types/excalidraw/actions/actionProperties.d.ts +18 -6
  230. package/dist/types/excalidraw/actions/actionSelectAll.d.ts +4 -0
  231. package/dist/types/excalidraw/actions/actionStyles.d.ts +5 -1
  232. package/dist/types/excalidraw/actions/actionToggleArrowBinding.d.ts +4 -0
  233. package/dist/types/excalidraw/actions/actionToggleGridMode.d.ts +4 -0
  234. package/dist/types/excalidraw/actions/actionToggleMidpointSnapping.d.ts +4 -0
  235. package/dist/types/excalidraw/actions/actionToggleObjectsSnapMode.d.ts +4 -0
  236. package/dist/types/excalidraw/actions/actionToggleSearchMenu.d.ts +4 -0
  237. package/dist/types/excalidraw/actions/actionToggleStats.d.ts +4 -0
  238. package/dist/types/excalidraw/actions/actionToggleViewMode.d.ts +4 -0
  239. package/dist/types/excalidraw/actions/actionToggleZenMode.d.ts +4 -0
  240. package/dist/types/excalidraw/actions/colorTargets.d.ts +39 -0
  241. package/dist/types/excalidraw/appState.d.ts +4 -0
  242. package/dist/types/excalidraw/components/App.arrowText.d.ts +40 -8
  243. package/dist/types/excalidraw/components/App.cursor.d.ts +8 -0
  244. package/dist/types/excalidraw/components/App.d.ts +92 -6
  245. package/dist/types/excalidraw/components/App.toolDrag.d.ts +63 -0
  246. package/dist/types/excalidraw/components/IconButton.d.ts +2 -0
  247. package/dist/types/excalidraw/components/TTDDialog/utils/TTDStreamFetch.d.ts +1 -0
  248. package/dist/types/excalidraw/components/Tools.d.ts +7 -2
  249. package/dist/types/excalidraw/components/canvases/NewElementCanvas.d.ts +2 -0
  250. package/dist/types/excalidraw/components/icons.d.ts +1 -0
  251. package/dist/types/excalidraw/components/shapeActionPredicates.d.ts +2 -2
  252. package/dist/types/excalidraw/data/blob.d.ts +8 -0
  253. package/dist/types/excalidraw/data/json.d.ts +4 -0
  254. package/dist/types/excalidraw/fonts/Fonts.d.ts +3 -2
  255. package/dist/types/excalidraw/hooks/useTextEditorFocus.d.ts +5 -5
  256. package/dist/types/excalidraw/index.d.ts +2 -1
  257. package/dist/types/excalidraw/renderer/helpers.d.ts +25 -0
  258. package/dist/types/excalidraw/renderer/interactiveScene.d.ts +1 -1
  259. package/dist/types/excalidraw/scene/Renderer.d.ts +50 -1
  260. package/dist/types/excalidraw/scene/index.d.ts +1 -1
  261. package/dist/types/excalidraw/scene/types.d.ts +1 -0
  262. package/dist/types/excalidraw/types.d.ts +30 -2
  263. package/dist/types/excalidraw/viewport.d.ts +4 -0
  264. package/dist/types/math/src/curve.d.ts +19 -12
  265. package/dist/types/math/src/segment.d.ts +6 -0
  266. package/dist/types/utils/src/export.d.ts +1 -0
  267. package/dist/types/utils/src/shape.d.ts +2 -2
  268. package/package.json +4 -4
  269. package/dist/dev/chunk-6WU4HLK7.js.map +0 -7
  270. package/dist/dev/chunk-7QNTKOP3.js.map +0 -7
  271. package/dist/dev/chunk-HY55C7T4.js +0 -69
  272. package/dist/dev/chunk-HY55C7T4.js.map +0 -7
  273. package/dist/dev/locales/ar-SA-YEOLME2Y.js.map +0 -7
  274. package/dist/dev/locales/az-AZ-DQL36U4O.js.map +0 -7
  275. package/dist/dev/locales/bg-BG-LG6R5FEQ.js.map +0 -7
  276. package/dist/dev/locales/bn-BD-W63P7JT5.js.map +0 -7
  277. package/dist/dev/locales/bn-IN-SCHACAA6.js.map +0 -7
  278. package/dist/dev/locales/ca-ES-XP3CQTWV.js.map +0 -7
  279. package/dist/dev/locales/cs-CZ-EXLEOJMD.js.map +0 -7
  280. package/dist/dev/locales/da-DK-46ONLZRX.js.map +0 -7
  281. package/dist/dev/locales/de-CH-A5QH3YGW.js.map +0 -7
  282. package/dist/dev/locales/de-DE-FVCCKR5N.js.map +0 -7
  283. package/dist/dev/locales/el-GR-SB4MX5JS.js.map +0 -7
  284. package/dist/dev/locales/es-ES-VRTYQG6S.js.map +0 -7
  285. package/dist/dev/locales/eu-ES-3OHEU2YV.js.map +0 -7
  286. package/dist/dev/locales/fa-IR-74WR2KXF.js.map +0 -7
  287. package/dist/dev/locales/fi-FI-XZQC4II2.js.map +0 -7
  288. package/dist/dev/locales/fr-FR-RABBDBKM.js.map +0 -7
  289. package/dist/dev/locales/gl-ES-OU3Q6XUE.js.map +0 -7
  290. package/dist/dev/locales/he-IL-6NCD5D54.js.map +0 -7
  291. package/dist/dev/locales/hi-IN-M54WKOJI.js.map +0 -7
  292. package/dist/dev/locales/hu-HU-HAW63BCI.js.map +0 -7
  293. package/dist/dev/locales/id-ID-TFSPHGWX.js.map +0 -7
  294. package/dist/dev/locales/it-IT-MH3BAO5W.js.map +0 -7
  295. package/dist/dev/locales/ja-JP-UGJBHLX6.js.map +0 -7
  296. package/dist/dev/locales/kaa-5ZUEYWIM.js.map +0 -7
  297. package/dist/dev/locales/kab-KAB-RLAZQZSM.js.map +0 -7
  298. package/dist/dev/locales/kk-KZ-CIP7GOIF.js.map +0 -7
  299. package/dist/dev/locales/km-KH-YMR4247H.js.map +0 -7
  300. package/dist/dev/locales/ko-KR-WGKQKR2R.js.map +0 -7
  301. package/dist/dev/locales/ku-TR-ZSJN6TN6.js.map +0 -7
  302. package/dist/dev/locales/lt-LT-FT6ZGIZP.js.map +0 -7
  303. package/dist/dev/locales/lv-LV-U74YKDPR.js.map +0 -7
  304. package/dist/dev/locales/mr-IN-KN72LOIA.js.map +0 -7
  305. package/dist/dev/locales/my-MM-E57NLQ7W.js.map +0 -7
  306. package/dist/dev/locales/nb-NO-FYQDWD7X.js.map +0 -7
  307. package/dist/dev/locales/nl-NL-D5MZQRAC.js.map +0 -7
  308. package/dist/dev/locales/nn-NO-5ZEUZJV4.js.map +0 -7
  309. package/dist/dev/locales/oc-FR-MVW6LDAP.js.map +0 -7
  310. package/dist/dev/locales/pa-IN-2NH3SVNI.js.map +0 -7
  311. package/dist/dev/locales/pl-PL-M6LYWLHY.js.map +0 -7
  312. package/dist/dev/locales/pt-BR-27M3CCS7.js.map +0 -7
  313. package/dist/dev/locales/pt-PT-V3C226NP.js.map +0 -7
  314. package/dist/dev/locales/ro-RO-S4GNBAJI.js.map +0 -7
  315. package/dist/dev/locales/ru-RU-CRRT5JUZ.js.map +0 -7
  316. package/dist/dev/locales/si-LK-APMICZ7H.js.map +0 -7
  317. package/dist/dev/locales/sk-SK-7ZFDZG6Y.js.map +0 -7
  318. package/dist/dev/locales/sl-SI-BBENCX7D.js.map +0 -7
  319. package/dist/dev/locales/sv-SE-35QJIOEW.js.map +0 -7
  320. package/dist/dev/locales/ta-IN-4N5CFIWZ.js.map +0 -7
  321. package/dist/dev/locales/th-TH-2F4V4IDB.js.map +0 -7
  322. package/dist/dev/locales/tr-TR-NDFP3F7P.js.map +0 -7
  323. package/dist/dev/locales/uk-UA-4I6VBQZ5.js.map +0 -7
  324. package/dist/dev/locales/uz-UZ-UVKC7UNZ.js.map +0 -7
  325. package/dist/dev/locales/vi-VN-UQCETDRL.js.map +0 -7
  326. package/dist/dev/locales/zh-CN-RSRHKN75.js.map +0 -7
  327. package/dist/dev/locales/zh-HK-XSFQ32U4.js.map +0 -7
  328. package/dist/dev/locales/zh-TW-KFVYWRFJ.js.map +0 -7
  329. package/dist/prod/chunk-7XWMRXBY.js +0 -1
  330. package/dist/prod/chunk-RM4UPSZO.js +0 -4
  331. package/dist/prod/data/image-ZVKINSPA.js +0 -1
  332. package/dist/prod/locales/az-AZ-OXJXL76K.js +0 -1
  333. package/dist/prod/locales/bg-BG-W2GKIJDF.js +0 -5
  334. package/dist/prod/locales/bn-BD-TGL7M4PJ.js +0 -3
  335. package/dist/prod/locales/bn-IN-BKETKYEH.js +0 -3
  336. package/dist/prod/locales/ca-ES-LD5SCRVV.js +0 -8
  337. package/dist/prod/locales/cs-CZ-OFPU5DBV.js +0 -7
  338. package/dist/prod/locales/da-DK-FRDJFYWF.js +0 -2
  339. package/dist/prod/locales/de-CH-ZG7H3QK3.js +0 -11
  340. package/dist/prod/locales/de-DE-SIJYH4IH.js +0 -11
  341. package/dist/prod/locales/el-GR-IEE2CGI2.js +0 -7
  342. package/dist/prod/locales/es-ES-TVVPWKV5.js +0 -12
  343. package/dist/prod/locales/eu-ES-CGBMFQDT.js +0 -8
  344. package/dist/prod/locales/fa-IR-IE6XAPR4.js +0 -9
  345. package/dist/prod/locales/fi-FI-P7TKNHRM.js +0 -6
  346. package/dist/prod/locales/fr-FR-QI2XZNT7.js +0 -12
  347. package/dist/prod/locales/gl-ES-TLYCNOZZ.js +0 -6
  348. package/dist/prod/locales/he-IL-ZX43XLGP.js +0 -9
  349. package/dist/prod/locales/hi-IN-UTYRMTUF.js +0 -3
  350. package/dist/prod/locales/hu-HU-AJOSEBW6.js +0 -3
  351. package/dist/prod/locales/id-ID-ETLTVG6C.js +0 -8
  352. package/dist/prod/locales/it-IT-B4B6TP6L.js +0 -12
  353. package/dist/prod/locales/ja-JP-IYKVURR5.js +0 -12
  354. package/dist/prod/locales/kaa-SE2BUIKX.js +0 -1
  355. package/dist/prod/locales/kab-KAB-Y3GLKXLR.js +0 -4
  356. package/dist/prod/locales/kk-KZ-ABWUFVOH.js +0 -1
  357. package/dist/prod/locales/ko-KR-7JQDXKGM.js +0 -5
  358. package/dist/prod/locales/ku-TR-NAH2Q5B7.js +0 -6
  359. package/dist/prod/locales/lt-LT-VQFYRSNQ.js +0 -3
  360. package/dist/prod/locales/lv-LV-T62VSYUM.js +0 -4
  361. package/dist/prod/locales/mr-IN-V4FHLCJE.js +0 -9
  362. package/dist/prod/locales/my-MM-E3SQ6E54.js +0 -1
  363. package/dist/prod/locales/nb-NO-MLNOFN5H.js +0 -8
  364. package/dist/prod/locales/nl-NL-D5L3ZV4M.js +0 -13
  365. package/dist/prod/locales/nn-NO-NNHDGPKB.js +0 -4
  366. package/dist/prod/locales/oc-FR-DWCRF55G.js +0 -4
  367. package/dist/prod/locales/pa-IN-3JSAY44M.js +0 -4
  368. package/dist/prod/locales/percentages-ETZPVQEE.js +0 -1
  369. package/dist/prod/locales/pl-PL-ACURYKP3.js +0 -12
  370. package/dist/prod/locales/pt-BR-LOX7MLGD.js +0 -10
  371. package/dist/prod/locales/pt-PT-CZ2U2RFQ.js +0 -12
  372. package/dist/prod/locales/ro-RO-2HECL2X6.js +0 -12
  373. package/dist/prod/locales/ru-RU-HAYNXO46.js +0 -10
  374. package/dist/prod/locales/si-LK-W5KNS4H6.js +0 -1
  375. package/dist/prod/locales/sk-SK-7K2CFGDV.js +0 -7
  376. package/dist/prod/locales/sl-SI-OXV2QZWW.js +0 -6
  377. package/dist/prod/locales/sv-SE-JTOBZRGL.js +0 -12
  378. package/dist/prod/locales/ta-IN-KFAVKXGT.js +0 -6
  379. package/dist/prod/locales/th-TH-VDMSCPDL.js +0 -1
  380. package/dist/prod/locales/tr-TR-CEZ6GX45.js +0 -4
  381. package/dist/prod/locales/uk-UA-Q3H3OXQC.js +0 -6
  382. package/dist/prod/locales/uz-UZ-NGCSWWPX.js +0 -1
  383. package/dist/prod/locales/vi-VN-P3NDEVPS.js +0 -7
  384. package/dist/prod/locales/zh-CN-SS3O57GA.js +0 -11
  385. package/dist/prod/locales/zh-HK-LWJT3VCF.js +0 -1
  386. package/dist/prod/locales/zh-TW-VJXC72RT.js +0 -13
  387. /package/dist/dev/data/{image-OPX5T4TO.js.map → image-KWAGZKDR.js.map} +0 -0
  388. /package/dist/dev/locales/{en-YJ3ZYXZZ.js.map → en-Z6IIINMM.js.map} +0 -0
  389. /package/dist/dev/locales/{percentages-QBBLQLIV.js.map → percentages-X2QIQ6XJ.js.map} +0 -0
package/CHANGELOG.md CHANGED
@@ -13,6 +13,17 @@ Please add the latest change on the top under the correct section.
13
13
 
14
14
  ## Unreleased
15
15
 
16
+ ### Sticky notes (2026-09-06) [#XXXX](https://github.com/excalidraw/excalidraw/pull/XXXX)
17
+
18
+ - New `stickynote` element type and toolbar tool (`N`): an always-filled, flat-rendered note whose label auto-fits — the font shrinks from the user's size down to a minimum, and only then does the note grow in height (it never shrinks below the height the user gave it). Click to place a 250×250 note, drag to size it (previewed at the dragged size, snapped to a font-aware minimum on release); text editing starts right away.
19
+ - Element model: the note carries `baseHeight` (the user's height; `height ≥ baseHeight`), its label carries `baseFontSize` (the user's font ceiling, `null`/absent on any other text) while `fontSize` holds the fitted size. Read a text element's user-facing size through `getBaseFontSize(text, elementsMap)`.
20
+ - Sticky notes are their own color domain: new `appState.currentItemStickynoteStrokeColor` (the note's text color) and `appState.currentItemStickynoteBackgroundColor` defaults, and new customizable top-pick slots `appState.colorTopPicks.stickyNoteStroke` / `stickyNoteBackground`. The stroke and background pickers, both eyedroppers and paste-styles resolve their target (regular / sticky / mixed) at execution time. A note and its label share one ink (the stroke picker reads "Text color" for notes): coloring the label while editing colors the note too, binding a colored text gives the note its color, and the creation-date footer always paints in that ink.
21
+ - Skeleton API: `convertToExcalidrawElements([{ type: "stickynote", x, y, label?: { text, fontSize? } }])` creates a note (and fitted label); see the element-skeleton docs.
22
+ - Tools can be dragged out of the toolbar: drag the sticky note button onto the canvas to drop a default-sized note where you release it, previewed translucently while dragging (nothing reaches the scene, history or collaborators until the drop; Escape cancels). The mechanism is generic — other tools can opt in.
23
+ - Toolbar: on desktop and tablet the image tool moved into the "More tools" menu (still `9`; `UIOptions.tools.image` keeps hiding it; the mobile toolbar keeps its image slot), and tool badges now show the letter shortcuts (`R`, `T`, `N`, …) instead of the numbers, which are no longer contiguous. The number keys keep working.
24
+ - Each note shows its creation date (`element.created`) in a footer band — "7 Sep", or "7 Sep 2025" once the year differs — on canvas and in SVG/PNG exports. The band is reserved in the note's layout, so the label never overlaps it; notes without a timestamp keep the band empty.
25
+ - Resize semantics: a note's corners resize proportionally by default and scale the label's font ceiling with the note (Shift frees them); its edges resize freely by default (Shift constrains them). Drag-creation is proportional by default too (Shift frees it) and never touches the font ceiling. Width-only gestures keep the base height, height gestures set it, aspect-locked multi-select and Stats group edits scale the ceiling; flips preserve everything. Arrows bound to a note follow it as it grows.
26
+
16
27
  ## Excalidraw API
17
28
 
18
29
  ### Host-controlled active tool (2026-07-14) [#11665](https://github.com/excalidraw/excalidraw/pull/11665)
@@ -34,7 +34,8 @@ import {
34
34
  STATS_PANELS,
35
35
  THEME,
36
36
  DEFAULT_GRID_STEP,
37
- isTestEnv
37
+ isTestEnv,
38
+ DEFAULT_STICKY_NOTE_BG
38
39
  } from "@excalidraw/common";
39
40
  var defaultExportScale = EXPORT_SCALES.includes(devicePixelRatio) ? devicePixelRatio : 1;
40
41
  var getDefaultAppState = () => {
@@ -52,6 +53,8 @@ var getDefaultAppState = () => {
52
53
  currentItemStrokeVariability: "constant",
53
54
  currentItemStartArrowhead: null,
54
55
  currentItemStrokeColor: DEFAULT_ELEMENT_PROPS.strokeColor,
56
+ currentItemStickynoteStrokeColor: DEFAULT_ELEMENT_PROPS.strokeColor,
57
+ currentItemStickynoteBackgroundColor: DEFAULT_STICKY_NOTE_BG,
55
58
  currentItemRoundness: isTestEnv() ? "sharp" : "round",
56
59
  currentItemArrowType: ARROW_TYPE.round,
57
60
  currentItemStrokeStyle: DEFAULT_ELEMENT_PROPS.strokeStyle,
@@ -147,7 +150,9 @@ var getDefaultAppState = () => {
147
150
  colorTopPicks: {
148
151
  elementStroke: null,
149
152
  elementBackground: null,
150
- bucketFill: null
153
+ bucketFill: null,
154
+ stickyNoteStroke: null,
155
+ stickyNoteBackground: null
151
156
  }
152
157
  };
153
158
  };
@@ -179,6 +184,16 @@ var APP_STATE_STORAGE_CONF = /* @__PURE__ */ ((config) => config)({
179
184
  },
180
185
  currentItemStartArrowhead: { browser: true, export: false, server: false },
181
186
  currentItemStrokeColor: { browser: true, export: false, server: false },
187
+ currentItemStickynoteStrokeColor: {
188
+ browser: true,
189
+ export: false,
190
+ server: false
191
+ },
192
+ currentItemStickynoteBackgroundColor: {
193
+ browser: true,
194
+ export: false,
195
+ server: false
196
+ },
182
197
  currentItemStrokeStyle: { browser: true, export: false, server: false },
183
198
  currentItemStrokeWidthKey: { browser: true, export: false, server: false },
184
199
  currentItemTextAlign: { browser: true, export: false, server: false },
@@ -607,6 +622,8 @@ var getScrollToContentState = (elements, appState) => {
607
622
  // scene/index.ts
608
623
  import {
609
624
  hasBackground,
625
+ hasFillStyle,
626
+ hasRoughness,
610
627
  hasStrokeWidth,
611
628
  hasStrokeStyle,
612
629
  hasFreedrawMode,
@@ -2984,8 +3001,9 @@ var XiaolaiFontFaces = [
2984
3001
 
2985
3002
  // fonts/Fonts.ts
2986
3003
  var _Fonts = class _Fonts {
2987
- constructor(scene) {
3004
+ constructor(scene, ownerDocument = document) {
2988
3005
  __publicField(this, "scene");
3006
+ __publicField(this, "ownerDocument");
2989
3007
  /**
2990
3008
  * Get all the font families for the given scene.
2991
3009
  */
@@ -3037,9 +3055,14 @@ var _Fonts = class _Fonts {
3037
3055
  const charsPerFamily = _Fonts.getCharsPerFamily(
3038
3056
  this.scene.getNonDeletedElements()
3039
3057
  );
3040
- return _Fonts.loadFontFaces(sceneFamilies, charsPerFamily);
3058
+ return _Fonts.loadFontFaces(
3059
+ sceneFamilies,
3060
+ charsPerFamily,
3061
+ this.ownerDocument
3062
+ );
3041
3063
  });
3042
3064
  this.scene = scene;
3065
+ this.ownerDocument = ownerDocument;
3043
3066
  }
3044
3067
  static get registered() {
3045
3068
  if (!_Fonts._registered) {
@@ -3077,33 +3100,37 @@ var _Fonts = class _Fonts {
3077
3100
  const fontFaces = await new PromisePool(iterator, concurrency).all();
3078
3101
  return Array.from(new Set(fontFaces));
3079
3102
  }
3080
- static async loadFontFaces(fontFamilies, charsPerFamily) {
3103
+ static async loadFontFaces(fontFamilies, charsPerFamily, ownerDocument) {
3081
3104
  for (const { fontFaces: fontFaces2, metadata } of _Fonts.registered.values()) {
3082
3105
  if (metadata.local) {
3083
3106
  continue;
3084
3107
  }
3085
3108
  for (const { fontFace } of fontFaces2) {
3086
- if (!window.document.fonts.has(fontFace)) {
3087
- window.document.fonts.add(fontFace);
3109
+ if (!ownerDocument.fonts.has(fontFace)) {
3110
+ ownerDocument.fonts.add(fontFace);
3088
3111
  }
3089
3112
  }
3090
3113
  }
3091
- const iterator = _Fonts.fontFacesLoader(fontFamilies, charsPerFamily);
3114
+ const iterator = _Fonts.fontFacesLoader(
3115
+ fontFamilies,
3116
+ charsPerFamily,
3117
+ ownerDocument
3118
+ );
3092
3119
  const concurrency = 10;
3093
3120
  const fontFaces = await new PromisePool(iterator, concurrency).all();
3094
3121
  return fontFaces.flat().filter(Boolean);
3095
3122
  }
3096
- static *fontFacesLoader(fontFamilies, charsPerFamily) {
3123
+ static *fontFacesLoader(fontFamilies, charsPerFamily, ownerDocument) {
3097
3124
  for (const [index, fontFamily] of fontFamilies.entries()) {
3098
3125
  const font = getFontString({
3099
3126
  fontFamily,
3100
3127
  fontSize: FONT_SIZES.sm
3101
3128
  });
3102
3129
  const text = _Fonts.getCharacters(charsPerFamily, fontFamily);
3103
- if (!window.document.fonts.check(font, text)) {
3130
+ if (!ownerDocument.fonts.check(font, text)) {
3104
3131
  yield promiseTry3(async () => {
3105
3132
  try {
3106
- const fontFaces = await window.document.fonts.load(font, text);
3133
+ const fontFaces = await ownerDocument.fonts.load(font, text);
3107
3134
  return [index, fontFaces];
3108
3135
  } catch (e) {
3109
3136
  console.error(
@@ -3246,10 +3273,10 @@ __publicField(_Fonts, "_initialized", false);
3246
3273
  /**
3247
3274
  * Load font faces for passed elements - use when the scene is unavailable (i.e. export).
3248
3275
  */
3249
- __publicField(_Fonts, "loadElementsFonts", async (elements) => {
3276
+ __publicField(_Fonts, "loadElementsFonts", async (elements, ownerDocument = document) => {
3250
3277
  const fontFamilies = _Fonts.getUniqueFamilies(elements);
3251
3278
  const charsPerFamily = _Fonts.getCharsPerFamily(elements);
3252
- return _Fonts.loadFontFaces(fontFamilies, charsPerFamily);
3279
+ return _Fonts.loadFontFaces(fontFamilies, charsPerFamily, ownerDocument);
3253
3280
  });
3254
3281
  var Fonts = _Fonts;
3255
3282
 
@@ -3343,6 +3370,8 @@ var isPointHittingLink = (element, elementsMap, appState, [x, y], isMobile) => {
3343
3370
 
3344
3371
  // renderer/helpers.ts
3345
3372
  import { COLOR_WHITE, THEME as THEME2, applyDarkModeFilter } from "@excalidraw/common";
3373
+ var DEFAULT_SELECTION_COLOR = "#6965db";
3374
+ var getSelectionColor = (element) => element && getComputedStyle(element).getPropertyValue("--color-selection").trim() || DEFAULT_SELECTION_COLOR;
3346
3375
  var fillCircle = (context, cx, cy, radius, stroke, fill = true) => {
3347
3376
  context.beginPath();
3348
3377
  context.arc(cx, cy, radius, 0, Math.PI * 2);
@@ -3353,6 +3382,15 @@ var fillCircle = (context, cx, cy, radius, stroke, fill = true) => {
3353
3382
  context.stroke();
3354
3383
  }
3355
3384
  };
3385
+ var snapScrollToDevicePixels = (appState, scale) => {
3386
+ const devicePixels = appState.zoom.value * scale;
3387
+ if (!(devicePixels > 0)) {
3388
+ return appState;
3389
+ }
3390
+ const scrollX = Math.round(appState.scrollX * devicePixels) / devicePixels;
3391
+ const scrollY = Math.round(appState.scrollY * devicePixels) / devicePixels;
3392
+ return scrollX === appState.scrollX && scrollY === appState.scrollY ? appState : { ...appState, scrollX, scrollY };
3393
+ };
3356
3394
  var getNormalizedCanvasDimensions = (canvas, scale) => {
3357
3395
  return [canvas.width / scale, canvas.height / scale];
3358
3396
  };
@@ -3417,28 +3455,41 @@ var GridLineColor = {
3417
3455
  regular: applyDarkModeFilter2("#e5e5e5")
3418
3456
  }
3419
3457
  };
3420
- var strokeGrid = (context, gridSize, gridStep, scrollX, scrollY, zoom, theme, width, height) => {
3458
+ var strokeGrid = (context, gridSize, gridStep, scrollX, scrollY, zoom, theme, width, height, scale) => {
3421
3459
  const offsetX = scrollX % gridSize - gridSize;
3422
3460
  const offsetY = scrollY % gridSize - gridSize;
3423
3461
  const actualGridSize = gridSize * zoom.value;
3424
3462
  const spaceWidth = 1 / zoom.value;
3463
+ const devicePixels = zoom.value * scale;
3464
+ const snap = (position, maxWidthInCssPixels) => {
3465
+ const widthInDevicePixels = Math.min(
3466
+ scale,
3467
+ maxWidthInCssPixels * devicePixels
3468
+ );
3469
+ if (widthInDevicePixels < 1) {
3470
+ return { position, lineWidth: widthInDevicePixels / devicePixels };
3471
+ }
3472
+ const wholeWidth = Math.round(widthInDevicePixels);
3473
+ const center = wholeWidth % 2 ? 0.5 : 0;
3474
+ return {
3475
+ position: (Math.round(position * devicePixels - center) + center) / devicePixels,
3476
+ lineWidth: wholeWidth / devicePixels
3477
+ };
3478
+ };
3425
3479
  context.save();
3426
- if (zoom.value === 1) {
3427
- context.translate(offsetX % 1 ? 0 : 0.5, offsetY % 1 ? 0 : 0.5);
3428
- }
3429
3480
  for (let x = offsetX; x < offsetX + width + gridSize * 2; x += gridSize) {
3430
3481
  const isBold = gridStep > 1 && Math.round(x - scrollX) % (gridStep * gridSize) === 0;
3431
3482
  if (!isBold && actualGridSize < 10) {
3432
3483
  continue;
3433
3484
  }
3434
- const lineWidth = Math.min(1 / zoom.value, isBold ? 4 : 1);
3485
+ const { position, lineWidth } = snap(x, isBold ? 4 : 1);
3435
3486
  context.lineWidth = lineWidth;
3436
3487
  const lineDash = [lineWidth * 3, spaceWidth + (lineWidth + spaceWidth)];
3437
3488
  context.beginPath();
3438
3489
  context.setLineDash(isBold ? [] : lineDash);
3439
3490
  context.strokeStyle = isBold ? GridLineColor[theme].bold : GridLineColor[theme].regular;
3440
- context.moveTo(x, offsetY - gridSize);
3441
- context.lineTo(x, Math.ceil(offsetY + height + gridSize * 2));
3491
+ context.moveTo(position, offsetY - gridSize);
3492
+ context.lineTo(position, Math.ceil(offsetY + height + gridSize * 2));
3442
3493
  context.stroke();
3443
3494
  }
3444
3495
  for (let y = offsetY; y < offsetY + height + gridSize * 2; y += gridSize) {
@@ -3446,14 +3497,14 @@ var strokeGrid = (context, gridSize, gridStep, scrollX, scrollY, zoom, theme, wi
3446
3497
  if (!isBold && actualGridSize < 10) {
3447
3498
  continue;
3448
3499
  }
3449
- const lineWidth = Math.min(1 / zoom.value, isBold ? 4 : 1);
3500
+ const { position, lineWidth } = snap(y, isBold ? 4 : 1);
3450
3501
  context.lineWidth = lineWidth;
3451
3502
  const lineDash = [lineWidth * 3, spaceWidth + (lineWidth + spaceWidth)];
3452
3503
  context.beginPath();
3453
3504
  context.setLineDash(isBold ? [] : lineDash);
3454
3505
  context.strokeStyle = isBold ? GridLineColor[theme].bold : GridLineColor[theme].regular;
3455
- context.moveTo(offsetX - gridSize, y);
3456
- context.lineTo(Math.ceil(offsetX + width + gridSize * 2), y);
3506
+ context.moveTo(offsetX - gridSize, position);
3507
+ context.lineTo(Math.ceil(offsetX + width + gridSize * 2), position);
3457
3508
  context.stroke();
3458
3509
  }
3459
3510
  context.restore();
@@ -3537,13 +3588,14 @@ var _renderStaticScene = ({
3537
3588
  allElementsMap,
3538
3589
  visibleElements,
3539
3590
  scale,
3540
- appState,
3591
+ appState: unsnappedAppState,
3541
3592
  renderConfig
3542
3593
  }) => {
3543
3594
  if (canvas === null) {
3544
3595
  return;
3545
3596
  }
3546
3597
  const { renderGrid = true, isExporting } = renderConfig;
3598
+ const appState = isExporting ? unsnappedAppState : snapScrollToDevicePixels(unsnappedAppState, scale);
3547
3599
  const [normalizedWidth, normalizedHeight] = getNormalizedCanvasDimensions(
3548
3600
  canvas,
3549
3601
  scale
@@ -3568,7 +3620,8 @@ var _renderStaticScene = ({
3568
3620
  appState.zoom,
3569
3621
  renderConfig.theme,
3570
3622
  normalizedWidth / appState.zoom.value,
3571
- normalizedHeight / appState.zoom.value
3623
+ normalizedHeight / appState.zoom.value,
3624
+ scale
3572
3625
  );
3573
3626
  }
3574
3627
  const groupsToBeAddedToFrame = /* @__PURE__ */ new Set();
@@ -3730,6 +3783,7 @@ var renderStaticScene = (renderConfig, throttle) => {
3730
3783
 
3731
3784
  // renderer/staticSvgScene.ts
3732
3785
  import {
3786
+ BOUND_TEXT_PADDING,
3733
3787
  FRAME_STYLE as FRAME_STYLE2,
3734
3788
  MAX_DECIMALS_FOR_SVG_EXPORT,
3735
3789
  SVG_NS,
@@ -3740,7 +3794,11 @@ import {
3740
3794
  isTestEnv as isTestEnv2,
3741
3795
  getVerticalOffset,
3742
3796
  applyDarkModeFilter as applyDarkModeFilter3,
3743
- MIME_TYPES as MIME_TYPES4
3797
+ MIME_TYPES as MIME_TYPES4,
3798
+ STICKY_NOTE_EDGE_SHADOW_OPACITY,
3799
+ STICKY_NOTE_EDGE_SHADOW_WIDTH,
3800
+ STICKY_NOTE_FOOTER,
3801
+ STICKY_NOTE_SHADOW_OPACITY
3744
3802
  } from "@excalidraw/common";
3745
3803
  import { normalizeLink, toValidURL } from "@excalidraw/common";
3746
3804
  import { hashString } from "@excalidraw/element";
@@ -3761,6 +3819,10 @@ import {
3761
3819
  import { getContainingFrame } from "@excalidraw/element";
3762
3820
  import { getCornerRadius, isPathALoop } from "@excalidraw/element";
3763
3821
  import { ShapeCache as ShapeCache2 } from "@excalidraw/element";
3822
+ import {
3823
+ getStickyNoteFooter,
3824
+ getStickyNotePathCommands
3825
+ } from "@excalidraw/element";
3764
3826
  import { getElementAbsoluteCoords as getElementAbsoluteCoords3 } from "@excalidraw/element";
3765
3827
  var roughSVGDrawWithPrecision = (rsvg, drawable, precision) => {
3766
3828
  if (typeof precision === "undefined") {
@@ -3825,6 +3887,99 @@ var renderElementToSvg = (element, elementsMap, rsvg, svgRoot, files, offsetX, o
3825
3887
  case "selection": {
3826
3888
  throw new Error("Selection rendering is not supported for SVG");
3827
3889
  }
3890
+ case "stickynote": {
3891
+ const getPathData = (commands2) => commands2.map((command) => {
3892
+ if (command.type === "move") {
3893
+ return `M ${command.point.x} ${command.point.y}`;
3894
+ }
3895
+ if (command.type === "line") {
3896
+ return `L ${command.point.x} ${command.point.y}`;
3897
+ }
3898
+ return `Q ${command.control.x} ${command.control.y} ${command.point.x} ${command.point.y}`;
3899
+ }).join(" ").concat(" Z");
3900
+ const createPath = (commands2, fill, fillOpacity) => {
3901
+ const path = svgRoot.ownerDocument.createElementNS(SVG_NS, "path");
3902
+ path.setAttribute("d", getPathData(commands2));
3903
+ path.setAttribute("fill", fill);
3904
+ if (typeof fillOpacity !== "undefined") {
3905
+ path.setAttribute("fill-opacity", `${fillOpacity}`);
3906
+ }
3907
+ path.setAttribute("stroke", "none");
3908
+ return path;
3909
+ };
3910
+ const group = svgRoot.ownerDocument.createElementNS(SVG_NS, "g");
3911
+ group.setAttribute(
3912
+ "transform",
3913
+ `translate(${offsetX || 0} ${offsetY || 0}) rotate(${degree} ${cx} ${cy})`
3914
+ );
3915
+ if (opacity !== 1) {
3916
+ group.setAttribute("opacity", `${opacity}`);
3917
+ }
3918
+ const shadow = createPath(
3919
+ getStickyNotePathCommands(element, { shadow: true }),
3920
+ "#000",
3921
+ STICKY_NOTE_SHADOW_OPACITY
3922
+ );
3923
+ const commands = getStickyNotePathCommands(element);
3924
+ const rect = createPath(
3925
+ commands,
3926
+ applyDarkModeFilter3(
3927
+ element.backgroundColor,
3928
+ renderConfig.theme === THEME4.DARK
3929
+ )
3930
+ );
3931
+ const clipPath = svgRoot.ownerDocument.createElementNS(
3932
+ SVG_NS,
3933
+ "clipPath"
3934
+ );
3935
+ clipPath.setAttribute("id", `sticky-note-clipPath-${element.id}`);
3936
+ clipPath.setAttribute("clipPathUnits", "userSpaceOnUse");
3937
+ clipPath.appendChild(createPath(commands, "#000"));
3938
+ addToRoot(clipPath, element);
3939
+ const edgeShadow = createPath(commands, "none");
3940
+ edgeShadow.setAttribute("stroke", "#000");
3941
+ edgeShadow.setAttribute(
3942
+ "stroke-opacity",
3943
+ `${STICKY_NOTE_EDGE_SHADOW_OPACITY}`
3944
+ );
3945
+ edgeShadow.setAttribute(
3946
+ "stroke-width",
3947
+ `${STICKY_NOTE_EDGE_SHADOW_WIDTH * 2}`
3948
+ );
3949
+ edgeShadow.setAttribute("clip-path", `url(#${clipPath.id})`);
3950
+ group.appendChild(shadow);
3951
+ group.appendChild(rect);
3952
+ group.appendChild(edgeShadow);
3953
+ const footer = getStickyNoteFooter(element);
3954
+ if (footer) {
3955
+ const dateText = svgRoot.ownerDocument.createElementNS(SVG_NS, "text");
3956
+ dateText.setAttribute("x", `${footer.x}`);
3957
+ dateText.setAttribute("y", `${footer.y}`);
3958
+ dateText.setAttribute("font-family", STICKY_NOTE_FOOTER.fontFamily);
3959
+ dateText.setAttribute("font-size", `${STICKY_NOTE_FOOTER.fontSize}px`);
3960
+ dateText.setAttribute("text-anchor", "end");
3961
+ dateText.setAttribute("direction", "ltr");
3962
+ dateText.setAttribute(
3963
+ "fill",
3964
+ applyDarkModeFilter3(
3965
+ element.strokeColor,
3966
+ renderConfig.theme === THEME4.DARK
3967
+ )
3968
+ );
3969
+ dateText.setAttribute("fill-opacity", `${STICKY_NOTE_FOOTER.opacity}`);
3970
+ dateText.textContent = footer.text;
3971
+ group.appendChild(dateText);
3972
+ }
3973
+ const g = maybeWrapNodesInFrameClipPath(
3974
+ element,
3975
+ root,
3976
+ [group],
3977
+ renderConfig.frameRendering,
3978
+ elementsMap
3979
+ );
3980
+ addToRoot(g || group, element);
3981
+ break;
3982
+ }
3828
3983
  case "rectangle":
3829
3984
  case "diamond":
3830
3985
  case "ellipse": {
@@ -3974,13 +4129,19 @@ var renderElementToSvg = (element, elementsMap, rsvg, svgRoot, files, offsetX, o
3974
4129
  boundText,
3975
4130
  elementsMap
3976
4131
  );
3977
- const maskX = offsetX + boundTextCoords.x - element.x;
3978
- const maskY = offsetY + boundTextCoords.y - element.y;
4132
+ const maskX = offsetX + boundTextCoords.x - element.x - BOUND_TEXT_PADDING;
4133
+ const maskY = offsetY + boundTextCoords.y - element.y - BOUND_TEXT_PADDING;
3979
4134
  maskRectInvisible.setAttribute("x", maskX.toString());
3980
4135
  maskRectInvisible.setAttribute("y", maskY.toString());
3981
4136
  maskRectInvisible.setAttribute("fill", "#000");
3982
- maskRectInvisible.setAttribute("width", `${boundText.width}`);
3983
- maskRectInvisible.setAttribute("height", `${boundText.height}`);
4137
+ maskRectInvisible.setAttribute(
4138
+ "width",
4139
+ `${boundText.width + BOUND_TEXT_PADDING * 2}`
4140
+ );
4141
+ maskRectInvisible.setAttribute(
4142
+ "height",
4143
+ `${boundText.height + BOUND_TEXT_PADDING * 2}`
4144
+ );
3984
4145
  maskRectInvisible.setAttribute("opacity", "1");
3985
4146
  maskPath.appendChild(maskRectInvisible);
3986
4147
  }
@@ -4674,11 +4835,17 @@ var getCanvasSize = (elements, exportPadding) => {
4674
4835
  };
4675
4836
 
4676
4837
  // data/restore.ts
4677
- import { isFiniteNumber, isValidPoint, pointFrom as pointFrom3 } from "@excalidraw/math";
4838
+ import {
4839
+ clamp as clamp3,
4840
+ isFiniteNumber,
4841
+ isValidPoint,
4842
+ pointFrom as pointFrom3
4843
+ } from "@excalidraw/math";
4678
4844
  import {
4679
4845
  colorToHex,
4680
4846
  COLOR_TOP_PICKS_SLOTS,
4681
4847
  DEFAULT_FONT_FAMILY as DEFAULT_FONT_FAMILY2,
4848
+ DEFAULT_FONT_SIZE as DEFAULT_FONT_SIZE2,
4682
4849
  DEFAULT_STROKE_STREAMLINE,
4683
4850
  DEFAULT_TEXT_ALIGN as DEFAULT_TEXT_ALIGN2,
4684
4851
  DEFAULT_VERTICAL_ALIGN,
@@ -4696,7 +4863,8 @@ import {
4696
4863
  normalizeLink as normalizeLink2,
4697
4864
  getLineHeight,
4698
4865
  STROKE_WIDTH,
4699
- STROKE_WIDTH_KEYS
4866
+ STROKE_WIDTH_KEYS,
4867
+ isTransparent
4700
4868
  } from "@excalidraw/common";
4701
4869
  import {
4702
4870
  calculateFixedPointForNonElbowArrowBinding,
@@ -4713,8 +4881,17 @@ import {
4713
4881
  validateElbowPoints
4714
4882
  } from "@excalidraw/element";
4715
4883
  import { LinearElementEditor as LinearElementEditor2 } from "@excalidraw/element";
4716
- import { bumpVersion } from "@excalidraw/element";
4717
- import { getContainerElement as getContainerElement3 } from "@excalidraw/element";
4884
+ import {
4885
+ bumpVersion,
4886
+ getStickyNoteLayout,
4887
+ isStickyNoteBoundText,
4888
+ normalizeStickyNote,
4889
+ normalizeStickyNoteBackgroundColor,
4890
+ normalizeStickyNoteFontSize,
4891
+ normalizeStickyNoteStrokeColor
4892
+ } from "@excalidraw/element";
4893
+ import { getBoundTextElement as getBoundTextElement3, getContainerElement as getContainerElement3 } from "@excalidraw/element";
4894
+ import { isStickyNoteElement } from "@excalidraw/element";
4718
4895
  import { detectLineHeight } from "@excalidraw/element";
4719
4896
  import {
4720
4897
  isArrowBoundToElement,
@@ -4802,6 +4979,7 @@ var AllowedExcalidrawActiveTools = {
4802
4979
  image: true,
4803
4980
  arrow: true,
4804
4981
  freedraw: true,
4982
+ stickynote: true,
4805
4983
  eraser: false,
4806
4984
  custom: true,
4807
4985
  frame: true,
@@ -4945,6 +5123,7 @@ var restoreElementWithProperties = (element, extra) => {
4945
5123
  } : null,
4946
5124
  boundElements: element.boundElementIds ? element.boundElementIds.map((id) => ({ type: "arrow", id })) : element.boundElements ?? [],
4947
5125
  updated: element.updated ?? getUpdatedTimestamp(),
5126
+ created: element.created ?? null,
4948
5127
  link: element.link ? normalizeLink2(element.link) : null,
4949
5128
  locked: element.locked ?? false
4950
5129
  };
@@ -4976,6 +5155,9 @@ var restoreElement = (element, targetElementsMap, existingElementsMap, opts) =>
4976
5155
  fontSize = parseFloat(fontPx);
4977
5156
  fontFamily = getFontFamilyByName(_fontFamily);
4978
5157
  }
5158
+ if (!isFiniteNumber(fontSize)) {
5159
+ fontSize = DEFAULT_FONT_SIZE2;
5160
+ }
4979
5161
  const text = typeof element.text === "string" && element.text || "";
4980
5162
  const lineHeight = element.lineHeight || (element.height ? (
4981
5163
  // detect line-height from current element height and font-size
@@ -4994,7 +5176,11 @@ var restoreElement = (element, targetElementsMap, existingElementsMap, opts) =>
4994
5176
  containerId: element.containerId ?? null,
4995
5177
  originalText: element.originalText || text,
4996
5178
  autoResize: element.autoResize ?? true,
4997
- lineHeight
5179
+ lineHeight,
5180
+ labelPosition: isFiniteNumber(element.labelPosition) ? clamp3(element.labelPosition, 0, 1) : null,
5181
+ // only meaningful for sticky note labels; reconciled against the
5182
+ // container in `restoreStickyNotes` once bindings are repaired
5183
+ baseFontSize: isFiniteNumber(element.baseFontSize) ? normalizeStickyNoteFontSize(element.baseFontSize) : null
4998
5184
  });
4999
5185
  if (opts?.deleteInvisibleElements && !text && !element.isDeleted) {
5000
5186
  element = { ...element, originalText: text, isDeleted: true };
@@ -5115,6 +5301,12 @@ var restoreElement = (element, targetElementsMap, existingElementsMap, opts) =>
5115
5301
  case "iframe":
5116
5302
  case "embeddable":
5117
5303
  return restoreElementWithProperties(element, {});
5304
+ case "stickynote":
5305
+ return normalizeStickyNote(
5306
+ restoreElementWithProperties(element, {
5307
+ baseHeight: element.baseHeight ?? element.maxHeight ?? element.height
5308
+ })
5309
+ );
5118
5310
  case "magicframe":
5119
5311
  case "frame":
5120
5312
  return restoreElementWithProperties(element, {
@@ -5185,6 +5377,43 @@ var repairFrameMembership = (element, elementsMap) => {
5185
5377
  }
5186
5378
  }
5187
5379
  };
5380
+ var restoreStickyNotes = (elements, elementsMap, opts) => {
5381
+ for (const element of elements) {
5382
+ if (!isTextElement4(element) || element.isDeleted) {
5383
+ continue;
5384
+ }
5385
+ if (isStickyNoteBoundText(element, elementsMap)) {
5386
+ const container = elementsMap.get(element.containerId);
5387
+ const strokeColor = normalizeStickyNoteStrokeColor(
5388
+ isTransparent(element.strokeColor) ? container?.strokeColor : element.strokeColor
5389
+ );
5390
+ Object.assign(element, {
5391
+ baseFontSize: normalizeStickyNoteFontSize(
5392
+ element.baseFontSize ?? element.fontSize
5393
+ ),
5394
+ strokeColor
5395
+ });
5396
+ if (container && container.strokeColor !== strokeColor) {
5397
+ Object.assign(container, { strokeColor });
5398
+ }
5399
+ } else if (element.baseFontSize != null) {
5400
+ Object.assign(element, { baseFontSize: null });
5401
+ }
5402
+ }
5403
+ if (opts.refreshDimensions) {
5404
+ for (const element of elements) {
5405
+ if (!isStickyNoteElement(element) || element.isDeleted) {
5406
+ continue;
5407
+ }
5408
+ const textElement = getBoundTextElement3(element, elementsMap);
5409
+ const layout = getStickyNoteLayout(element, textElement);
5410
+ Object.assign(element, layout.container);
5411
+ if (textElement && layout.text) {
5412
+ Object.assign(textElement, layout.text);
5413
+ }
5414
+ }
5415
+ }
5416
+ };
5188
5417
  var restoreElements = (targetElements, existingElements, opts) => {
5189
5418
  const existingIds = /* @__PURE__ */ new Set();
5190
5419
  const targetElementsMap = arrayToMap3(targetElements || []);
@@ -5239,7 +5468,8 @@ var restoreElements = (targetElements, existingElements, opts) => {
5239
5468
  } else if (element.boundElements) {
5240
5469
  repairContainerElement(element, restoredElementsMap);
5241
5470
  }
5242
- if (opts.refreshDimensions && isTextElement4(element)) {
5471
+ if (opts.refreshDimensions && isTextElement4(element) && // sticky labels are refitted together with their note below
5472
+ !isStickyNoteBoundText(element, restoredElementsMap)) {
5243
5473
  Object.assign(
5244
5474
  element,
5245
5475
  refreshTextDimensions(
@@ -5258,6 +5488,9 @@ var restoreElements = (targetElements, existingElements, opts) => {
5258
5488
  }
5259
5489
  }
5260
5490
  }
5491
+ restoreStickyNotes(restoredElements, restoredElementsMap, {
5492
+ refreshDimensions: !!opts.refreshDimensions
5493
+ });
5261
5494
  const repairedElements = repairBoundTextElementOrder(restoredElements);
5262
5495
  return repairedElements.map((element) => {
5263
5496
  if (isElbowArrow(element) && !isArrowBoundToElement(element) && !validateElbowPoints(element.points)) {
@@ -5378,6 +5611,12 @@ var restoreAppState = (appState, localAppState) => {
5378
5611
  ),
5379
5612
  bucketFill: restoreColorTopPicksList(
5380
5613
  nextAppState.colorTopPicks?.bucketFill
5614
+ ),
5615
+ stickyNoteStroke: restoreColorTopPicksList(
5616
+ nextAppState.colorTopPicks?.stickyNoteStroke
5617
+ ),
5618
+ stickyNoteBackground: restoreColorTopPicksList(
5619
+ nextAppState.colorTopPicks?.stickyNoteBackground
5381
5620
  )
5382
5621
  };
5383
5622
  if (appState.currentItemStrokeWidth !== void 0) {
@@ -5412,6 +5651,12 @@ var restoreAppState = (appState, localAppState) => {
5412
5651
  gridStep: getNormalizedGridStep(
5413
5652
  isFiniteNumber(appState.gridStep) ? appState.gridStep : DEFAULT_GRID_STEP2
5414
5653
  ),
5654
+ currentItemStickynoteStrokeColor: normalizeStickyNoteStrokeColor(
5655
+ nextAppState.currentItemStickynoteStrokeColor
5656
+ ),
5657
+ currentItemStickynoteBackgroundColor: normalizeStickyNoteBackgroundColor(
5658
+ nextAppState.currentItemStickynoteBackgroundColor
5659
+ ),
5415
5660
  editingFrame: null
5416
5661
  };
5417
5662
  };
@@ -5455,7 +5700,7 @@ var parseFileContents = async (blob) => {
5455
5700
  let contents;
5456
5701
  if (blob.type === MIME_TYPES6.png) {
5457
5702
  try {
5458
- return await (await import("./data/image-OPX5T4TO.js")).decodePngMetadata(blob);
5703
+ return await (await import("./data/image-KWAGZKDR.js")).decodePngMetadata(blob);
5459
5704
  } catch (error) {
5460
5705
  if (error.message === "INVALID") {
5461
5706
  throw new ImageSceneDataError(
@@ -5535,19 +5780,20 @@ var loadSceneOrLibraryFromBlob = async (blob, localAppState, localElements, file
5535
5780
  throw error;
5536
5781
  }
5537
5782
  if (isValidExcalidrawData(data)) {
5783
+ const elements = restoreElements(data.elements, localElements, {
5784
+ repairBindings: true,
5785
+ deleteInvisibleElements: true
5786
+ });
5538
5787
  return {
5539
5788
  type: MIME_TYPES6.excalidraw,
5540
5789
  data: {
5541
- elements: restoreElements(data.elements, localElements, {
5542
- repairBindings: true,
5543
- deleteInvisibleElements: true
5544
- }),
5790
+ elements,
5545
5791
  appState: restoreAppState(
5546
5792
  {
5547
5793
  theme: localAppState?.theme,
5548
5794
  fileHandle: fileHandle || blob.handle || null,
5549
5795
  ...cleanAppStateForExport(data.appState || {}),
5550
- ...localAppState ? getScrollToContentState(data.elements || [], localAppState) : {}
5796
+ ...localAppState ? getScrollToContentState(elements, localAppState) : {}
5551
5797
  },
5552
5798
  localAppState
5553
5799
  ),
@@ -5871,6 +6117,8 @@ export {
5871
6117
  getSelectedElements,
5872
6118
  getTargetElements,
5873
6119
  hasBackground,
6120
+ hasFillStyle,
6121
+ hasRoughness,
5874
6122
  hasStrokeWidth,
5875
6123
  hasStrokeStyle,
5876
6124
  hasFreedrawMode,
@@ -5894,7 +6142,9 @@ export {
5894
6142
  saveLibraryAsJSON,
5895
6143
  getLinkHandleFromCoords,
5896
6144
  isPointHittingLink,
6145
+ getSelectionColor,
5897
6146
  fillCircle,
6147
+ snapScrollToDevicePixels,
5898
6148
  getNormalizedCanvasDimensions,
5899
6149
  bootstrapCanvas,
5900
6150
  strokeRectWithRotation_simple,
@@ -5931,4 +6181,4 @@ export {
5931
6181
  createFile,
5932
6182
  normalizeFile
5933
6183
  };
5934
- //# sourceMappingURL=chunk-6WU4HLK7.js.map
6184
+ //# sourceMappingURL=chunk-N7DCBD6G.js.map