Compare commits

..

2209 Commits

Author SHA1 Message Date
Excalidraw Bot
c507d1726a New translations en.json (Portuguese) 2025-02-04 11:04:24 +01:00
Excalidraw Bot
d6ef71c15c New translations en.json (German) 2025-01-22 20:35:23 +01:00
Excalidraw Bot
4b9978cd57 New translations en.json (Slovak) 2025-01-21 03:20:22 +01:00
Excalidraw Bot
79cac89d45 New translations en.json (Hindi) 2025-01-16 07:15:41 +01:00
Excalidraw Bot
2651ce2e9b New translations en.json (Marathi) 2025-01-16 07:15:40 +01:00
Excalidraw Bot
6c3c6f26d9 New translations en.json (Chinese Simplified) 2025-01-16 01:06:46 +01:00
Excalidraw Bot
38da08662c New translations en.json (Spanish) 2025-01-14 14:59:30 +01:00
Excalidraw Bot
571053aec9 New translations en.json (Romanian) 2025-01-14 11:01:30 +01:00
Excalidraw Bot
88b3d9b6a5 New translations en.json (Russian) 2025-01-13 19:17:34 +01:00
Excalidraw Bot
f2b9da3255 New translations en.json (German) 2025-01-13 18:13:41 +01:00
Excalidraw Bot
ba4a9f1e82 New translations en.json (Karakalpak) 2025-01-13 17:08:29 +01:00
Excalidraw Bot
90ee80a3fa New translations en.json (Kabyle) 2025-01-13 17:08:28 +01:00
Excalidraw Bot
01c6cbefbc New translations en.json (Bengali, India) 2025-01-13 17:08:27 +01:00
Excalidraw Bot
8aee0f5f24 New translations en.json (German, Switzerland) 2025-01-13 17:08:26 +01:00
Excalidraw Bot
d865bfb985 New translations en.json (Occitan) 2025-01-13 17:08:25 +01:00
Excalidraw Bot
4ac707927a New translations en.json (Norwegian Bokmal) 2025-01-13 17:08:24 +01:00
Excalidraw Bot
e102ee38cd New translations en.json (Uzbek) 2025-01-13 17:08:23 +01:00
Excalidraw Bot
4df31a063a New translations en.json (Sinhala) 2025-01-13 17:08:21 +01:00
Excalidraw Bot
f8e0e7cda9 New translations en.json (Chinese Traditional, Hong Kong) 2025-01-13 17:08:20 +01:00
Excalidraw Bot
bfd79929b7 New translations en.json (Burmese) 2025-01-13 17:08:19 +01:00
Excalidraw Bot
182df6516a New translations en.json (Hindi) 2025-01-13 17:08:17 +01:00
Excalidraw Bot
08840c89ca New translations en.json (Azerbaijani) 2025-01-13 17:08:16 +01:00
Excalidraw Bot
30cf52e15c New translations en.json (Latvian) 2025-01-13 17:08:15 +01:00
Excalidraw Bot
09f2f38ce7 New translations en.json (Kazakh) 2025-01-13 17:08:14 +01:00
Excalidraw Bot
df54053d44 New translations en.json (Norwegian Nynorsk) 2025-01-13 17:08:13 +01:00
Excalidraw Bot
1850a09ffd New translations en.json (Thai) 2025-01-13 17:08:11 +01:00
Excalidraw Bot
16e2694301 New translations en.json (Marathi) 2025-01-13 17:08:10 +01:00
Excalidraw Bot
48fdd416e4 New translations en.json (Bengali) 2025-01-13 17:08:09 +01:00
Excalidraw Bot
0e71b552a0 New translations en.json (Tamil) 2025-01-13 17:08:08 +01:00
Excalidraw Bot
201df105a0 New translations en.json (Khmer) 2025-01-13 17:08:06 +01:00
Excalidraw Bot
8b0297e024 New translations en.json (Persian) 2025-01-13 17:08:05 +01:00
Excalidraw Bot
88f2d3d848 New translations en.json (Indonesian) 2025-01-13 17:08:04 +01:00
Excalidraw Bot
2262458d08 New translations en.json (Portuguese, Brazilian) 2025-01-13 17:08:02 +01:00
Excalidraw Bot
367dbb6a20 New translations en.json (Galician) 2025-01-13 17:08:01 +01:00
Excalidraw Bot
15bb6af068 New translations en.json (Vietnamese) 2025-01-13 17:08:00 +01:00
Excalidraw Bot
0da5f82b4b New translations en.json (Chinese Simplified) 2025-01-13 17:07:58 +01:00
Excalidraw Bot
b6fadd90c6 New translations en.json (Ukrainian) 2025-01-13 17:07:57 +01:00
Excalidraw Bot
f4dd5ced14 New translations en.json (Turkish) 2025-01-13 17:07:56 +01:00
Excalidraw Bot
67b4a6083e New translations en.json (Swedish) 2025-01-13 17:07:54 +01:00
Excalidraw Bot
d011d8ffbe New translations en.json (Slovenian) 2025-01-13 17:07:53 +01:00
Excalidraw Bot
9341ae94fe New translations en.json (Russian) 2025-01-13 17:07:52 +01:00
Excalidraw Bot
5d9d93e400 New translations en.json (Portuguese) 2025-01-13 17:07:51 +01:00
Excalidraw Bot
8660a48958 New translations en.json (Polish) 2025-01-13 17:07:49 +01:00
Excalidraw Bot
361cb1b94c New translations en.json (Punjabi) 2025-01-13 17:07:48 +01:00
Excalidraw Bot
4282f3c2dc New translations en.json (Dutch) 2025-01-13 17:07:47 +01:00
Excalidraw Bot
37ee37caaa New translations en.json (Lithuanian) 2025-01-13 17:07:46 +01:00
Excalidraw Bot
9ef56c2b20 New translations en.json (Kurdish) 2025-01-13 17:07:44 +01:00
Excalidraw Bot
7f235f5830 New translations en.json (Japanese) 2025-01-13 17:07:43 +01:00
Excalidraw Bot
cbe30a553f New translations en.json (Italian) 2025-01-13 17:07:42 +01:00
Excalidraw Bot
28eef4fc08 New translations en.json (Finnish) 2025-01-13 17:07:41 +01:00
Excalidraw Bot
10bf4dae6b New translations en.json (Basque) 2025-01-13 17:07:39 +01:00
Excalidraw Bot
ccb2b9e5e2 New translations en.json (Greek) 2025-01-13 17:07:38 +01:00
Excalidraw Bot
25c9334ebe New translations en.json (German) 2025-01-13 17:07:36 +01:00
Excalidraw Bot
057a5b555a New translations en.json (Danish) 2025-01-13 17:07:34 +01:00
Excalidraw Bot
7adb935619 New translations en.json (Czech) 2025-01-13 17:07:33 +01:00
Excalidraw Bot
6d6bb7a6d0 New translations en.json (Catalan) 2025-01-13 17:07:31 +01:00
Excalidraw Bot
7fa8edcdfe New translations en.json (Bulgarian) 2025-01-13 17:07:29 +01:00
Excalidraw Bot
63facdd1b3 New translations en.json (Arabic) 2025-01-13 17:07:28 +01:00
Excalidraw Bot
0ead775db7 New translations en.json (Spanish) 2025-01-13 17:07:27 +01:00
Excalidraw Bot
5af0f1c11e New translations en.json (French) 2025-01-13 17:07:25 +01:00
Excalidraw Bot
fd5c2b81d8 New translations en.json (Romanian) 2025-01-13 17:07:24 +01:00
Excalidraw Bot
052e456826 New translations en.json (Chinese Traditional) 2025-01-13 17:07:23 +01:00
Excalidraw Bot
0e71e2e49b New translations en.json (Korean) 2025-01-13 17:07:22 +01:00
Excalidraw Bot
0d50481428 New translations en.json (Hungarian) 2025-01-13 17:07:21 +01:00
Excalidraw Bot
c82882e7e4 New translations en.json (Hebrew) 2025-01-13 17:07:19 +01:00
Excalidraw Bot
62bd7cca34 New translations en.json (Slovak) 2025-01-13 17:07:18 +01:00
Excalidraw Bot
0e37679c89 New translations en.json (Slovak) 2025-01-13 02:34:56 +01:00
Excalidraw Bot
cfcac1d74d New translations en.json (Turkish) 2025-01-09 20:19:36 +01:00
Excalidraw Bot
f8935be5fd New translations en.json (Chinese Traditional) 2025-01-07 08:35:18 +01:00
Excalidraw Bot
2ad3c1e3a0 New translations en.json (Russian) 2025-01-06 20:51:27 +01:00
Excalidraw Bot
8c69e77458 New translations en.json (Spanish) 2025-01-06 17:36:56 +01:00
Excalidraw Bot
7c60960708 New translations en.json (Chinese Simplified) 2025-01-06 06:18:41 +01:00
Excalidraw Bot
c050f50920 New translations en.json (Slovenian) 2025-01-05 23:23:46 +01:00
Excalidraw Bot
fc0364e49b New translations en.json (German) 2025-01-05 23:23:44 +01:00
Excalidraw Bot
1c2bc960e3 New translations en.json (Romanian) 2025-01-05 23:23:43 +01:00
Excalidraw Bot
fa3e95e62d New translations en.json (Karakalpak) 2025-01-05 22:14:04 +01:00
Excalidraw Bot
91ff8ece0d New translations en.json (Kabyle) 2025-01-05 22:14:03 +01:00
Excalidraw Bot
08241465c4 New translations en.json (Bengali, India) 2025-01-05 22:14:02 +01:00
Excalidraw Bot
4a70e3c8c6 New translations en.json (German, Switzerland) 2025-01-05 22:14:01 +01:00
Excalidraw Bot
58ae2ef67f New translations en.json (Occitan) 2025-01-05 22:14:00 +01:00
Excalidraw Bot
d4474ce348 New translations en.json (Norwegian Bokmal) 2025-01-05 22:13:59 +01:00
Excalidraw Bot
a02df75456 New translations en.json (Uzbek) 2025-01-05 22:13:58 +01:00
Excalidraw Bot
e0d1d4ae53 New translations en.json (Sinhala) 2025-01-05 22:13:57 +01:00
Excalidraw Bot
91f906d122 New translations en.json (Chinese Traditional, Hong Kong) 2025-01-05 22:13:56 +01:00
Excalidraw Bot
8e76a3576a New translations en.json (Burmese) 2025-01-05 22:13:55 +01:00
Excalidraw Bot
575ba7c167 New translations en.json (Hindi) 2025-01-05 22:13:54 +01:00
Excalidraw Bot
f4ea623e65 New translations en.json (Azerbaijani) 2025-01-05 22:13:52 +01:00
Excalidraw Bot
a74946d8ba New translations en.json (Latvian) 2025-01-05 22:13:51 +01:00
Excalidraw Bot
5cf9ce5a19 New translations en.json (Kazakh) 2025-01-05 22:13:50 +01:00
Excalidraw Bot
06b26a347e New translations en.json (Norwegian Nynorsk) 2025-01-05 22:13:50 +01:00
Excalidraw Bot
4a071e90e8 New translations en.json (Thai) 2025-01-05 22:13:48 +01:00
Excalidraw Bot
11e7ea11df New translations en.json (Marathi) 2025-01-05 22:13:48 +01:00
Excalidraw Bot
01b0ac438c New translations en.json (Bengali) 2025-01-05 22:13:46 +01:00
Excalidraw Bot
3b6c1fdbaa New translations en.json (Tamil) 2025-01-05 22:13:45 +01:00
Excalidraw Bot
a6119a0910 New translations en.json (Khmer) 2025-01-05 22:13:44 +01:00
Excalidraw Bot
c42898a939 New translations en.json (Persian) 2025-01-05 22:13:43 +01:00
Excalidraw Bot
aaa239113f New translations en.json (Indonesian) 2025-01-05 22:13:42 +01:00
Excalidraw Bot
110d3d7c69 New translations en.json (Portuguese, Brazilian) 2025-01-05 22:13:41 +01:00
Excalidraw Bot
1e9fe91adf New translations en.json (Galician) 2025-01-05 22:13:40 +01:00
Excalidraw Bot
b8baa27839 New translations en.json (Vietnamese) 2025-01-05 22:13:39 +01:00
Excalidraw Bot
c1c2091a88 New translations en.json (Chinese Simplified) 2025-01-05 22:13:38 +01:00
Excalidraw Bot
8f7aa71a4c New translations en.json (Ukrainian) 2025-01-05 22:13:37 +01:00
Excalidraw Bot
d38ea58a27 New translations en.json (Turkish) 2025-01-05 22:13:36 +01:00
Excalidraw Bot
cb62a51426 New translations en.json (Swedish) 2025-01-05 22:13:35 +01:00
Excalidraw Bot
c300216307 New translations en.json (Slovenian) 2025-01-05 22:13:34 +01:00
Excalidraw Bot
a01bbedada New translations en.json (Russian) 2025-01-05 22:13:33 +01:00
Excalidraw Bot
0d9e1e8f92 New translations en.json (Portuguese) 2025-01-05 22:13:32 +01:00
Excalidraw Bot
93a95db1b2 New translations en.json (Polish) 2025-01-05 22:13:31 +01:00
Excalidraw Bot
b22d830b3b New translations en.json (Punjabi) 2025-01-05 22:13:30 +01:00
Excalidraw Bot
de09e6867c New translations en.json (Dutch) 2025-01-05 22:13:29 +01:00
Excalidraw Bot
6f37102175 New translations en.json (Lithuanian) 2025-01-05 22:13:28 +01:00
Excalidraw Bot
351aac987b New translations en.json (Kurdish) 2025-01-05 22:13:27 +01:00
Excalidraw Bot
9c534fe870 New translations en.json (Japanese) 2025-01-05 22:13:26 +01:00
Excalidraw Bot
fbe2745b2d New translations en.json (Italian) 2025-01-05 22:13:25 +01:00
Excalidraw Bot
cfa03593a6 New translations en.json (Finnish) 2025-01-05 22:13:24 +01:00
Excalidraw Bot
b13771496f New translations en.json (Basque) 2025-01-05 22:13:23 +01:00
Excalidraw Bot
a7cc1247d1 New translations en.json (Greek) 2025-01-05 22:13:22 +01:00
Excalidraw Bot
323008553e New translations en.json (German) 2025-01-05 22:13:21 +01:00
Excalidraw Bot
253017fe8e New translations en.json (Danish) 2025-01-05 22:13:20 +01:00
Excalidraw Bot
97ee0973dd New translations en.json (Czech) 2025-01-05 22:13:19 +01:00
Excalidraw Bot
a0f3c50ceb New translations en.json (Catalan) 2025-01-05 22:13:18 +01:00
Excalidraw Bot
0a9ae2505d New translations en.json (Bulgarian) 2025-01-05 22:13:17 +01:00
Excalidraw Bot
5bb7a37121 New translations en.json (Arabic) 2025-01-05 22:13:16 +01:00
Excalidraw Bot
532c4bb639 New translations en.json (Spanish) 2025-01-05 22:13:15 +01:00
Excalidraw Bot
218c9ef1c3 New translations en.json (French) 2025-01-05 22:13:14 +01:00
Excalidraw Bot
21016e21a5 New translations en.json (Romanian) 2025-01-05 22:13:13 +01:00
Excalidraw Bot
20ca0ccf12 New translations en.json (Chinese Traditional) 2025-01-05 22:13:12 +01:00
Excalidraw Bot
a96c2013b7 New translations en.json (Korean) 2025-01-05 22:13:10 +01:00
Excalidraw Bot
bf9733f7ef New translations en.json (Hungarian) 2025-01-05 22:13:09 +01:00
Excalidraw Bot
7566d96b35 New translations en.json (Hebrew) 2025-01-05 22:13:08 +01:00
Excalidraw Bot
4b8642d1d0 New translations en.json (Slovak) 2025-01-05 22:13:07 +01:00
Excalidraw Bot
3ca773f54d New translations en.json (Hungarian) 2024-12-31 16:17:49 +01:00
Excalidraw Bot
3dbdfdcffc New translations en.json (Hungarian) 2024-12-31 15:16:38 +01:00
Excalidraw Bot
4acea43b12 New translations en.json (Slovak) 2024-12-30 10:40:20 +01:00
Excalidraw Bot
aabc4b701e New translations en.json (Slovak) 2024-12-30 08:55:51 +01:00
Excalidraw Bot
1325c85a48 New translations en.json (Hebrew) 2024-12-28 00:16:03 +01:00
Excalidraw Bot
3f3134435e New translations en.json (Hebrew) 2024-12-27 22:51:12 +01:00
Excalidraw Bot
2d370b9360 New translations en.json (Chinese Traditional) 2024-12-23 10:29:20 +01:00
Excalidraw Bot
dab6df1a77 New translations en.json (Korean) 2024-12-23 07:42:22 +01:00
Excalidraw Bot
4390f6d75e New translations en.json (Romanian) 2024-12-18 11:57:51 +01:00
Excalidraw Bot
4d1730882b New translations en.json (Polish) 2024-12-18 10:37:52 +01:00
Excalidraw Bot
6bff123aea New translations en.json (Chinese Simplified) 2024-12-18 04:04:53 +01:00
Excalidraw Bot
e255caefc5 New translations en.json (German) 2024-12-17 21:04:56 +01:00
Excalidraw Bot
a62ebd7f71 New translations en.json (Hindi) 2024-12-17 18:15:21 +01:00
Excalidraw Bot
376d25ad8b New translations en.json (Marathi) 2024-12-17 18:15:19 +01:00
Excalidraw Bot
dfc89f9d6e New translations en.json (Russian) 2024-12-17 15:27:00 +01:00
Excalidraw Bot
62114e309f New translations en.json (Portuguese) 2024-12-17 15:26:58 +01:00
Excalidraw Bot
c6901cae98 New translations en.json (Karakalpak) 2024-12-17 14:11:42 +01:00
Excalidraw Bot
d4b760f7b3 New translations en.json (Kabyle) 2024-12-17 14:11:41 +01:00
Excalidraw Bot
5e21607153 New translations en.json (Bengali, India) 2024-12-17 14:11:40 +01:00
Excalidraw Bot
3e79c6caab New translations en.json (German, Switzerland) 2024-12-17 14:11:38 +01:00
Excalidraw Bot
fee26ea12c New translations en.json (Occitan) 2024-12-17 14:11:37 +01:00
Excalidraw Bot
b551e5336c New translations en.json (Norwegian Bokmal) 2024-12-17 14:11:36 +01:00
Excalidraw Bot
172ecace2f New translations en.json (Uzbek) 2024-12-17 14:11:35 +01:00
Excalidraw Bot
e146d42598 New translations en.json (Sinhala) 2024-12-17 14:11:33 +01:00
Excalidraw Bot
0546406d4b New translations en.json (Chinese Traditional, Hong Kong) 2024-12-17 14:11:32 +01:00
Excalidraw Bot
4a5ca8d3ea New translations en.json (Burmese) 2024-12-17 14:11:31 +01:00
Excalidraw Bot
267341b9b7 New translations en.json (Hindi) 2024-12-17 14:11:29 +01:00
Excalidraw Bot
c3a15bc297 New translations en.json (Azerbaijani) 2024-12-17 14:11:28 +01:00
Excalidraw Bot
4b1d99fbf4 New translations en.json (Latvian) 2024-12-17 14:11:27 +01:00
Excalidraw Bot
c4c1193094 New translations en.json (Kazakh) 2024-12-17 14:11:25 +01:00
Excalidraw Bot
03adc9b7bc New translations en.json (Norwegian Nynorsk) 2024-12-17 14:11:24 +01:00
Excalidraw Bot
fd491e45e9 New translations en.json (Thai) 2024-12-17 14:11:23 +01:00
Excalidraw Bot
a19c1d64e4 New translations en.json (Marathi) 2024-12-17 14:11:21 +01:00
Excalidraw Bot
836c8f2dba New translations en.json (Bengali) 2024-12-17 14:11:20 +01:00
Excalidraw Bot
01f2001a0d New translations en.json (Tamil) 2024-12-17 14:11:19 +01:00
Excalidraw Bot
8136b719bd New translations en.json (Khmer) 2024-12-17 14:11:18 +01:00
Excalidraw Bot
20870a78c2 New translations en.json (Persian) 2024-12-17 14:11:16 +01:00
Excalidraw Bot
e741a6f370 New translations en.json (Portuguese, Brazilian) 2024-12-17 14:11:15 +01:00
Excalidraw Bot
e76ef06074 New translations en.json (Galician) 2024-12-17 14:11:14 +01:00
Excalidraw Bot
0fd05e34c4 New translations en.json (Vietnamese) 2024-12-17 14:11:12 +01:00
Excalidraw Bot
b11c80361a New translations en.json (Chinese Traditional) 2024-12-17 14:11:11 +01:00
Excalidraw Bot
f19c0d14ed New translations en.json (Ukrainian) 2024-12-17 14:11:09 +01:00
Excalidraw Bot
b242a9df79 New translations en.json (Turkish) 2024-12-17 14:11:07 +01:00
Excalidraw Bot
9fed9613fa New translations en.json (Russian) 2024-12-17 14:11:06 +01:00
Excalidraw Bot
01fa484a5e New translations en.json (Polish) 2024-12-17 14:11:04 +01:00
Excalidraw Bot
9a7e1710a4 New translations en.json (Punjabi) 2024-12-17 14:11:03 +01:00
Excalidraw Bot
d1957e4056 New translations en.json (Dutch) 2024-12-17 14:11:02 +01:00
Excalidraw Bot
68c96c5c9f New translations en.json (Lithuanian) 2024-12-17 14:11:00 +01:00
Excalidraw Bot
617897be5b New translations en.json (Kurdish) 2024-12-17 14:10:59 +01:00
Excalidraw Bot
b116388c7e New translations en.json (Korean) 2024-12-17 14:10:57 +01:00
Excalidraw Bot
473d4da923 New translations en.json (Japanese) 2024-12-17 14:10:56 +01:00
Excalidraw Bot
4c15aa2cf2 New translations en.json (Indonesian) 2024-12-17 14:10:55 +01:00
Excalidraw Bot
73f1d98d06 New translations en.json (Portuguese) 2024-12-17 14:10:53 +01:00
Excalidraw Bot
4e75a68ad3 New translations en.json (Chinese Simplified) 2024-12-17 14:10:52 +01:00
Excalidraw Bot
c0cf71a6f5 New translations en.json (Swedish) 2024-12-17 14:10:50 +01:00
Excalidraw Bot
4b5b7e8f5a New translations en.json (Slovenian) 2024-12-17 14:10:49 +01:00
Excalidraw Bot
e0dff46a28 New translations en.json (Slovak) 2024-12-17 14:10:48 +01:00
Excalidraw Bot
505b6ace2b New translations en.json (Italian) 2024-12-17 14:10:47 +01:00
Excalidraw Bot
4845574506 New translations en.json (Hungarian) 2024-12-17 14:10:45 +01:00
Excalidraw Bot
a9f69d750b New translations en.json (Hebrew) 2024-12-17 14:10:44 +01:00
Excalidraw Bot
f883167acc New translations en.json (Finnish) 2024-12-17 14:10:43 +01:00
Excalidraw Bot
3d89b04ac4 New translations en.json (Basque) 2024-12-17 14:10:42 +01:00
Excalidraw Bot
3ffa6c93e4 New translations en.json (Greek) 2024-12-17 14:10:40 +01:00
Excalidraw Bot
6be95e9fbf New translations en.json (German) 2024-12-17 14:10:39 +01:00
Excalidraw Bot
be0d4241e4 New translations en.json (Danish) 2024-12-17 14:10:37 +01:00
Excalidraw Bot
dc0b951dfa New translations en.json (Catalan) 2024-12-17 14:10:36 +01:00
Excalidraw Bot
b92b0ec82b New translations en.json (Bulgarian) 2024-12-17 14:10:35 +01:00
Excalidraw Bot
774fd07ca8 New translations en.json (Arabic) 2024-12-17 14:10:34 +01:00
Excalidraw Bot
a18a1ace4d New translations en.json (Spanish) 2024-12-17 14:10:32 +01:00
Excalidraw Bot
728ac246d5 New translations en.json (French) 2024-12-17 14:10:31 +01:00
Excalidraw Bot
a1b5ff5372 New translations en.json (Romanian) 2024-12-17 14:10:30 +01:00
Excalidraw Bot
80b98ca5e4 New translations en.json (Czech) 2024-12-17 14:10:28 +01:00
Excalidraw Bot
4d22570b55 New translations en.json (Czech) 2024-12-17 12:44:37 +01:00
Excalidraw Bot
f1a2bb6677 New translations en.json (Indonesian) 2024-12-16 00:25:54 +01:00
Excalidraw Bot
b213e344fb New translations en.json (Indonesian) 2024-12-15 23:23:04 +01:00
Excalidraw Bot
ed61daeb16 New translations en.json (Portuguese) 2024-12-15 21:05:23 +01:00
Excalidraw Bot
4e752e95a3 New translations en.json (Chinese Simplified) 2024-12-12 03:59:20 +01:00
Excalidraw Bot
e459e07af5 New translations en.json (Swedish) 2024-12-09 08:39:44 +01:00
Excalidraw Bot
1aa82f1c80 New translations en.json (Slovak) 2024-12-07 17:51:15 +01:00
Excalidraw Bot
ae9dca08b5 New translations en.json (Slovak) 2024-12-07 16:55:39 +01:00
Excalidraw Bot
7af0ba734d New translations en.json (Slovenian) 2024-12-03 07:13:08 +01:00
Excalidraw Bot
d200ee2d0d New translations en.json (Italian) 2024-12-01 16:32:30 +01:00
Excalidraw Bot
597bde73d4 New translations en.json (Persian) 2024-11-30 14:11:06 +01:00
Excalidraw Bot
44642e29e4 New translations en.json (Persian) 2024-11-30 13:08:35 +01:00
Excalidraw Bot
d01091c094 New translations en.json (Persian) 2024-11-30 12:05:49 +01:00
Excalidraw Bot
9cbe0a89a7 New translations en.json (Chinese Traditional) 2024-11-28 15:43:42 +01:00
Excalidraw Bot
09c53b975e New translations en.json (Hindi) 2024-11-27 06:51:41 +01:00
Excalidraw Bot
356d13cae7 New translations en.json (Marathi) 2024-11-27 06:51:40 +01:00
Excalidraw Bot
37a3caf5a9 New translations en.json (Hindi) 2024-11-27 05:10:53 +01:00
Excalidraw Bot
baaad3a443 New translations en.json (Marathi) 2024-11-27 05:10:52 +01:00
Excalidraw Bot
d679f40082 New translations en.json (Chinese Simplified) 2024-11-26 23:12:40 +01:00
Excalidraw Bot
9a7cd4f7ef New translations en.json (Russian) 2024-11-26 21:32:27 +01:00
Excalidraw Bot
f94ca28f79 New translations en.json (German) 2024-11-26 20:27:07 +01:00
Excalidraw Bot
f264ae11f4 New translations en.json (Romanian) 2024-11-26 20:27:06 +01:00
Excalidraw Bot
d864979a03 New translations en.json (Karakalpak) 2024-11-26 19:16:20 +01:00
Excalidraw Bot
0a6d3d1adb New translations en.json (Kabyle) 2024-11-26 19:16:19 +01:00
Excalidraw Bot
1d9a5047ad New translations en.json (Bengali, India) 2024-11-26 19:16:18 +01:00
Excalidraw Bot
e3ec60d5f0 New translations en.json (German, Switzerland) 2024-11-26 19:16:16 +01:00
Excalidraw Bot
7d13b85641 New translations en.json (Occitan) 2024-11-26 19:16:15 +01:00
Excalidraw Bot
5d507846bc New translations en.json (Norwegian Bokmal) 2024-11-26 19:16:14 +01:00
Excalidraw Bot
b75e141298 New translations en.json (Uzbek) 2024-11-26 19:16:13 +01:00
Excalidraw Bot
884c74fbb2 New translations en.json (Sinhala) 2024-11-26 19:16:12 +01:00
Excalidraw Bot
bcf4d508f1 New translations en.json (Chinese Traditional, Hong Kong) 2024-11-26 19:16:11 +01:00
Excalidraw Bot
dc539e6820 New translations en.json (Burmese) 2024-11-26 19:16:10 +01:00
Excalidraw Bot
6f2eb61779 New translations en.json (Hindi) 2024-11-26 19:16:08 +01:00
Excalidraw Bot
9f616b80ad New translations en.json (Azerbaijani) 2024-11-26 19:16:07 +01:00
Excalidraw Bot
054616a1cc New translations en.json (Latvian) 2024-11-26 19:16:06 +01:00
Excalidraw Bot
cec851802c New translations en.json (Kazakh) 2024-11-26 19:16:04 +01:00
Excalidraw Bot
3a0185547b New translations en.json (Norwegian Nynorsk) 2024-11-26 19:16:03 +01:00
Excalidraw Bot
3ff94c62d8 New translations en.json (Thai) 2024-11-26 19:16:02 +01:00
Excalidraw Bot
5c389ba4f8 New translations en.json (Marathi) 2024-11-26 19:16:01 +01:00
Excalidraw Bot
17e68174e0 New translations en.json (Bengali) 2024-11-26 19:15:59 +01:00
Excalidraw Bot
e709161793 New translations en.json (Tamil) 2024-11-26 19:15:58 +01:00
Excalidraw Bot
20f73f04d0 New translations en.json (Khmer) 2024-11-26 19:15:57 +01:00
Excalidraw Bot
fbac5eca10 New translations en.json (Persian) 2024-11-26 19:15:55 +01:00
Excalidraw Bot
cad57ed57f New translations en.json (Portuguese, Brazilian) 2024-11-26 19:15:54 +01:00
Excalidraw Bot
4df28ca379 New translations en.json (Galician) 2024-11-26 19:15:53 +01:00
Excalidraw Bot
1a89311bf1 New translations en.json (Vietnamese) 2024-11-26 19:15:52 +01:00
Excalidraw Bot
e419fbf34f New translations en.json (Chinese Traditional) 2024-11-26 19:15:50 +01:00
Excalidraw Bot
84f2ab1730 New translations en.json (Chinese Simplified) 2024-11-26 19:15:49 +01:00
Excalidraw Bot
4d0d230a2a New translations en.json (Ukrainian) 2024-11-26 19:15:48 +01:00
Excalidraw Bot
b1c73bfa1d New translations en.json (Turkish) 2024-11-26 19:15:47 +01:00
Excalidraw Bot
f6b5f846a0 New translations en.json (Swedish) 2024-11-26 19:15:45 +01:00
Excalidraw Bot
db0f79925b New translations en.json (Slovenian) 2024-11-26 19:15:43 +01:00
Excalidraw Bot
f23ba3ef04 New translations en.json (Slovak) 2024-11-26 19:15:42 +01:00
Excalidraw Bot
8c0adc2057 New translations en.json (Russian) 2024-11-26 19:15:41 +01:00
Excalidraw Bot
a9276c6be4 New translations en.json (Portuguese) 2024-11-26 19:15:39 +01:00
Excalidraw Bot
e9239f7cd6 New translations en.json (Polish) 2024-11-26 19:15:38 +01:00
Excalidraw Bot
3607ed03a4 New translations en.json (Punjabi) 2024-11-26 19:15:37 +01:00
Excalidraw Bot
0fbc118070 New translations en.json (Dutch) 2024-11-26 19:15:34 +01:00
Excalidraw Bot
6a620a5384 New translations en.json (Lithuanian) 2024-11-26 19:15:33 +01:00
Excalidraw Bot
c87d215ca7 New translations en.json (Kurdish) 2024-11-26 19:15:32 +01:00
Excalidraw Bot
2a31a1ff29 New translations en.json (Korean) 2024-11-26 19:15:30 +01:00
Excalidraw Bot
cdc50c727e New translations en.json (Japanese) 2024-11-26 19:15:29 +01:00
Excalidraw Bot
73c788b92a New translations en.json (Italian) 2024-11-26 19:15:28 +01:00
Excalidraw Bot
b14ddf04bd New translations en.json (Hungarian) 2024-11-26 19:15:26 +01:00
Excalidraw Bot
2099a5a9ce New translations en.json (Hebrew) 2024-11-26 19:15:25 +01:00
Excalidraw Bot
e645dde8cb New translations en.json (Finnish) 2024-11-26 19:15:23 +01:00
Excalidraw Bot
481c01a2f1 New translations en.json (Basque) 2024-11-26 19:15:22 +01:00
Excalidraw Bot
3cbff07c4d New translations en.json (Greek) 2024-11-26 19:15:21 +01:00
Excalidraw Bot
afff916b38 New translations en.json (German) 2024-11-26 19:15:19 +01:00
Excalidraw Bot
89b4bf9ba9 New translations en.json (Danish) 2024-11-26 19:15:18 +01:00
Excalidraw Bot
0d2c2589ff New translations en.json (Czech) 2024-11-26 19:15:17 +01:00
Excalidraw Bot
8bad0ff2f4 New translations en.json (Bulgarian) 2024-11-26 19:15:15 +01:00
Excalidraw Bot
5f395cb853 New translations en.json (Arabic) 2024-11-26 19:15:14 +01:00
Excalidraw Bot
7fff5d5b81 New translations en.json (Spanish) 2024-11-26 19:15:12 +01:00
Excalidraw Bot
b025fee131 New translations en.json (French) 2024-11-26 19:15:11 +01:00
Excalidraw Bot
be6bed7ef6 New translations en.json (Romanian) 2024-11-26 19:15:10 +01:00
Excalidraw Bot
14d3a5d24c New translations en.json (Indonesian) 2024-11-26 19:15:09 +01:00
Excalidraw Bot
185e8c2872 New translations en.json (Catalan) 2024-11-26 19:15:07 +01:00
Excalidraw Bot
911acf5563 New translations en.json (Indonesian) 2024-11-26 18:06:22 +01:00
Excalidraw Bot
06f4d4bdf6 New translations en.json (Catalan) 2024-11-19 12:11:10 +01:00
Excalidraw Bot
51df6af4d5 New translations en.json (Catalan) 2024-11-19 09:45:38 +01:00
Excalidraw Bot
2b82cfeb17 New translations en.json (Persian) 2024-11-06 16:00:23 +01:00
Excalidraw Bot
45412a5b9f New translations en.json (Persian) 2024-11-06 14:10:19 +01:00
Excalidraw Bot
0d02fe5357 New translations en.json (Portuguese, Brazilian) 2024-11-05 21:43:37 +01:00
Excalidraw Bot
7173691477 New translations en.json (Chinese Simplified) 2024-10-26 12:43:37 +02:00
Excalidraw Bot
48b9a4d5dc New translations en.json (Hindi) 2024-10-24 09:47:16 +02:00
Excalidraw Bot
76dd970ded New translations en.json (Marathi) 2024-10-24 09:47:14 +02:00
Excalidraw Bot
9c963374c1 New translations en.json (Marathi) 2024-10-24 07:40:11 +02:00
Excalidraw Bot
9be077c0af New translations en.json (Polish) 2024-10-23 14:28:30 +02:00
Excalidraw Bot
6980e289ba New translations en.json (Thai) 2024-10-23 13:16:18 +02:00
Excalidraw Bot
4ac09f6b2b New translations en.json (Polish) 2024-10-23 13:16:16 +02:00
Excalidraw Bot
62e9b39ac5 New translations en.json (Chinese Traditional) 2024-10-23 06:40:53 +02:00
Excalidraw Bot
f9b0d26c7f New translations en.json (German) 2024-10-22 19:44:31 +02:00
Excalidraw Bot
43e8ae3bdd New translations en.json (Romanian) 2024-10-22 12:29:39 +02:00
Excalidraw Bot
695c2580cd New translations en.json (Slovenian) 2024-10-22 06:25:46 +02:00
Excalidraw Bot
41a7111e19 New translations en.json (Karakalpak) 2024-10-21 23:42:54 +02:00
Excalidraw Bot
0338f74b45 New translations en.json (Kabyle) 2024-10-21 23:42:53 +02:00
Excalidraw Bot
baa1858a95 New translations en.json (Bengali, India) 2024-10-21 23:42:52 +02:00
Excalidraw Bot
e011b47e58 New translations en.json (German, Switzerland) 2024-10-21 23:42:51 +02:00
Excalidraw Bot
a97c8a0360 New translations en.json (Occitan) 2024-10-21 23:42:50 +02:00
Excalidraw Bot
976ffab80f New translations en.json (Norwegian Bokmal) 2024-10-21 23:42:49 +02:00
Excalidraw Bot
84a363fe4d New translations en.json (Uzbek) 2024-10-21 23:42:48 +02:00
Excalidraw Bot
62d05d7f25 New translations en.json (Sinhala) 2024-10-21 23:42:47 +02:00
Excalidraw Bot
66e5170691 New translations en.json (Chinese Traditional, Hong Kong) 2024-10-21 23:42:46 +02:00
Excalidraw Bot
da16dd3eff New translations en.json (Burmese) 2024-10-21 23:42:44 +02:00
Excalidraw Bot
00f0f85cd8 New translations en.json (Hindi) 2024-10-21 23:42:43 +02:00
Excalidraw Bot
8c864ea97b New translations en.json (Azerbaijani) 2024-10-21 23:42:42 +02:00
Excalidraw Bot
b20083c572 New translations en.json (Latvian) 2024-10-21 23:42:41 +02:00
Excalidraw Bot
c91a774849 New translations en.json (Kazakh) 2024-10-21 23:42:40 +02:00
Excalidraw Bot
835be2ae12 New translations en.json (Norwegian Nynorsk) 2024-10-21 23:42:39 +02:00
Excalidraw Bot
3831c17d45 New translations en.json (Thai) 2024-10-21 23:42:38 +02:00
Excalidraw Bot
3b2779dacc New translations en.json (Marathi) 2024-10-21 23:42:36 +02:00
Excalidraw Bot
31a0a79438 New translations en.json (Bengali) 2024-10-21 23:42:35 +02:00
Excalidraw Bot
310e04cd63 New translations en.json (Tamil) 2024-10-21 23:42:34 +02:00
Excalidraw Bot
ebd84c318d New translations en.json (Khmer) 2024-10-21 23:42:33 +02:00
Excalidraw Bot
3b5a918176 New translations en.json (Persian) 2024-10-21 23:42:32 +02:00
Excalidraw Bot
c878278c4c New translations en.json (Indonesian) 2024-10-21 23:42:31 +02:00
Excalidraw Bot
2fb60ffdd2 New translations en.json (Portuguese, Brazilian) 2024-10-21 23:42:30 +02:00
Excalidraw Bot
3ed09450bf New translations en.json (Galician) 2024-10-21 23:42:29 +02:00
Excalidraw Bot
6ba9228ee1 New translations en.json (Vietnamese) 2024-10-21 23:42:27 +02:00
Excalidraw Bot
9cbc5fe090 New translations en.json (Chinese Traditional) 2024-10-21 23:42:26 +02:00
Excalidraw Bot
4cb605f65e New translations en.json (Ukrainian) 2024-10-21 23:42:25 +02:00
Excalidraw Bot
b9f7b1b927 New translations en.json (Slovenian) 2024-10-21 23:42:24 +02:00
Excalidraw Bot
1ce313ef8d New translations en.json (Russian) 2024-10-21 23:42:23 +02:00
Excalidraw Bot
92f40dee15 New translations en.json (Portuguese) 2024-10-21 23:42:22 +02:00
Excalidraw Bot
349d4336c4 New translations en.json (Polish) 2024-10-21 23:42:21 +02:00
Excalidraw Bot
d678395574 New translations en.json (Punjabi) 2024-10-21 23:42:20 +02:00
Excalidraw Bot
699a08aed7 New translations en.json (Dutch) 2024-10-21 23:42:18 +02:00
Excalidraw Bot
eb17963a56 New translations en.json (Lithuanian) 2024-10-21 23:42:17 +02:00
Excalidraw Bot
0be2c0be9d New translations en.json (Kurdish) 2024-10-21 23:42:16 +02:00
Excalidraw Bot
3e52ed7c45 New translations en.json (Japanese) 2024-10-21 23:42:15 +02:00
Excalidraw Bot
84a89d4f74 New translations en.json (Italian) 2024-10-21 23:42:14 +02:00
Excalidraw Bot
80cc680fff New translations en.json (Hungarian) 2024-10-21 23:42:13 +02:00
Excalidraw Bot
255f47483f New translations en.json (Hebrew) 2024-10-21 23:42:12 +02:00
Excalidraw Bot
10f5c6b509 New translations en.json (Finnish) 2024-10-21 23:42:11 +02:00
Excalidraw Bot
6e0fac82d3 New translations en.json (Basque) 2024-10-21 23:42:10 +02:00
Excalidraw Bot
2be2924fa0 New translations en.json (Greek) 2024-10-21 23:42:09 +02:00
Excalidraw Bot
9fd4565e4a New translations en.json (German) 2024-10-21 23:42:07 +02:00
Excalidraw Bot
4e5ea9c740 New translations en.json (Danish) 2024-10-21 23:42:06 +02:00
Excalidraw Bot
0ab0d44cd3 New translations en.json (Czech) 2024-10-21 23:42:05 +02:00
Excalidraw Bot
6c26b4e569 New translations en.json (Catalan) 2024-10-21 23:42:04 +02:00
Excalidraw Bot
5b0253d3a6 New translations en.json (Bulgarian) 2024-10-21 23:42:03 +02:00
Excalidraw Bot
28a654fccc New translations en.json (Arabic) 2024-10-21 23:42:02 +02:00
Excalidraw Bot
bda68283d3 New translations en.json (Spanish) 2024-10-21 23:42:00 +02:00
Excalidraw Bot
eb7140181d New translations en.json (Romanian) 2024-10-21 23:41:59 +02:00
Excalidraw Bot
9b93b1c568 New translations en.json (French) 2024-10-21 23:41:58 +02:00
Excalidraw Bot
d32aed4330 New translations en.json (Chinese Simplified) 2024-10-21 23:41:57 +02:00
Excalidraw Bot
419f9f2a2f New translations en.json (Korean) 2024-10-21 23:41:56 +02:00
Excalidraw Bot
86dfb3dff2 New translations en.json (Slovak) 2024-10-21 23:41:55 +02:00
Excalidraw Bot
4a650dc607 New translations en.json (Swedish) 2024-10-21 23:41:54 +02:00
Excalidraw Bot
6db2847d10 New translations en.json (Turkish) 2024-10-21 23:41:53 +02:00
Excalidraw Bot
0c24264185 New translations en.json (French) 2024-10-21 17:02:51 +02:00
Excalidraw Bot
9391e8090a New translations en.json (Slovak) 2024-10-20 19:51:59 +02:00
Excalidraw Bot
c0c3ca85d7 New translations en.json (Russian) 2024-10-18 10:39:46 +02:00
Excalidraw Bot
d183629ca4 New translations en.json (Chinese Simplified) 2024-10-18 07:52:05 +02:00
Excalidraw Bot
cd4846f8aa New translations en.json (Chinese Traditional) 2024-10-18 05:37:32 +02:00
Excalidraw Bot
997bd7f6b3 New translations en.json (Polish) 2024-10-17 23:06:53 +02:00
Excalidraw Bot
a93a36c94a New translations en.json (Slovenian) 2024-10-17 21:45:50 +02:00
Excalidraw Bot
84314ed5ec New translations en.json (German) 2024-10-17 21:45:49 +02:00
Excalidraw Bot
ae09870836 New translations en.json (Karakalpak) 2024-10-17 20:17:04 +02:00
Excalidraw Bot
bff8aaee01 New translations en.json (Kabyle) 2024-10-17 20:17:02 +02:00
Excalidraw Bot
b059d9ac0b New translations en.json (Bengali, India) 2024-10-17 20:17:01 +02:00
Excalidraw Bot
46c9b1d2a9 New translations en.json (German, Switzerland) 2024-10-17 20:17:00 +02:00
Excalidraw Bot
3e36e07d80 New translations en.json (Occitan) 2024-10-17 20:16:59 +02:00
Excalidraw Bot
0080bcfce5 New translations en.json (Norwegian Bokmal) 2024-10-17 20:16:58 +02:00
Excalidraw Bot
0bd6ce4b47 New translations en.json (Uzbek) 2024-10-17 20:16:57 +02:00
Excalidraw Bot
f4c88d5669 New translations en.json (Sinhala) 2024-10-17 20:16:56 +02:00
Excalidraw Bot
b6038126c5 New translations en.json (Chinese Traditional, Hong Kong) 2024-10-17 20:16:55 +02:00
Excalidraw Bot
5ab897112c New translations en.json (Burmese) 2024-10-17 20:16:54 +02:00
Excalidraw Bot
1b2d4e59a3 New translations en.json (Hindi) 2024-10-17 20:16:53 +02:00
Excalidraw Bot
569860cde6 New translations en.json (Azerbaijani) 2024-10-17 20:16:51 +02:00
Excalidraw Bot
7de2e0975d New translations en.json (Latvian) 2024-10-17 20:16:50 +02:00
Excalidraw Bot
653bcd7898 New translations en.json (Kazakh) 2024-10-17 20:16:49 +02:00
Excalidraw Bot
733b0b45ce New translations en.json (Norwegian Nynorsk) 2024-10-17 20:16:48 +02:00
Excalidraw Bot
ed2c4ccbba New translations en.json (Thai) 2024-10-17 20:16:47 +02:00
Excalidraw Bot
aab15eef3e New translations en.json (Marathi) 2024-10-17 20:16:45 +02:00
Excalidraw Bot
ce7ede5fb0 New translations en.json (Bengali) 2024-10-17 20:16:44 +02:00
Excalidraw Bot
944ffba66f New translations en.json (Tamil) 2024-10-17 20:16:43 +02:00
Excalidraw Bot
e600142ee6 New translations en.json (Khmer) 2024-10-17 20:16:42 +02:00
Excalidraw Bot
3a3e9f8701 New translations en.json (Persian) 2024-10-17 20:16:40 +02:00
Excalidraw Bot
dfdfeae79f New translations en.json (Indonesian) 2024-10-17 20:16:39 +02:00
Excalidraw Bot
a6b49fa014 New translations en.json (Portuguese, Brazilian) 2024-10-17 20:16:38 +02:00
Excalidraw Bot
a706962edd New translations en.json (Galician) 2024-10-17 20:16:37 +02:00
Excalidraw Bot
e69fd9f2f8 New translations en.json (Vietnamese) 2024-10-17 20:16:36 +02:00
Excalidraw Bot
3f7b5034e7 New translations en.json (Chinese Traditional) 2024-10-17 20:16:35 +02:00
Excalidraw Bot
fcbecec034 New translations en.json (Ukrainian) 2024-10-17 20:16:34 +02:00
Excalidraw Bot
e77fc90d90 New translations en.json (Slovenian) 2024-10-17 20:16:32 +02:00
Excalidraw Bot
112b16d9df New translations en.json (Russian) 2024-10-17 20:16:30 +02:00
Excalidraw Bot
dc4e625750 New translations en.json (Portuguese) 2024-10-17 20:16:29 +02:00
Excalidraw Bot
a25eae3edd New translations en.json (Polish) 2024-10-17 20:16:28 +02:00
Excalidraw Bot
7f58444112 New translations en.json (Punjabi) 2024-10-17 20:16:27 +02:00
Excalidraw Bot
6527ee5a11 New translations en.json (Dutch) 2024-10-17 20:16:25 +02:00
Excalidraw Bot
52a2558d11 New translations en.json (Lithuanian) 2024-10-17 20:16:24 +02:00
Excalidraw Bot
21a56e4a0b New translations en.json (Kurdish) 2024-10-17 20:16:23 +02:00
Excalidraw Bot
c2fdeda13e New translations en.json (Japanese) 2024-10-17 20:16:22 +02:00
Excalidraw Bot
4e0f644a55 New translations en.json (Italian) 2024-10-17 20:16:21 +02:00
Excalidraw Bot
257ffe1c07 New translations en.json (Hungarian) 2024-10-17 20:16:20 +02:00
Excalidraw Bot
5416ee4c7c New translations en.json (Hebrew) 2024-10-17 20:16:19 +02:00
Excalidraw Bot
833314cf7a New translations en.json (Finnish) 2024-10-17 20:16:17 +02:00
Excalidraw Bot
359c2c2bc6 New translations en.json (Basque) 2024-10-17 20:16:16 +02:00
Excalidraw Bot
e8e734be56 New translations en.json (Greek) 2024-10-17 20:16:15 +02:00
Excalidraw Bot
556e38edce New translations en.json (German) 2024-10-17 20:16:14 +02:00
Excalidraw Bot
aaeddcf0e1 New translations en.json (Danish) 2024-10-17 20:16:13 +02:00
Excalidraw Bot
6139cb6d98 New translations en.json (Czech) 2024-10-17 20:16:12 +02:00
Excalidraw Bot
aff50136ef New translations en.json (Catalan) 2024-10-17 20:16:11 +02:00
Excalidraw Bot
8a8c60adab New translations en.json (Bulgarian) 2024-10-17 20:16:09 +02:00
Excalidraw Bot
c09b46e964 New translations en.json (Arabic) 2024-10-17 20:16:08 +02:00
Excalidraw Bot
ed7ffe00a3 New translations en.json (Spanish) 2024-10-17 20:16:07 +02:00
Excalidraw Bot
67b8e63637 New translations en.json (Romanian) 2024-10-17 20:16:06 +02:00
Excalidraw Bot
c6a8e4de1e New translations en.json (French) 2024-10-17 20:16:05 +02:00
Excalidraw Bot
59982f4d84 New translations en.json (Chinese Simplified) 2024-10-17 20:16:04 +02:00
Excalidraw Bot
ab6e573497 New translations en.json (Korean) 2024-10-17 20:16:02 +02:00
Excalidraw Bot
dd377b2a0f New translations en.json (Slovak) 2024-10-17 20:16:01 +02:00
Excalidraw Bot
c6607c4d19 New translations en.json (Swedish) 2024-10-17 20:16:00 +02:00
Excalidraw Bot
f881d98ae7 New translations en.json (Turkish) 2024-10-17 20:15:59 +02:00
Excalidraw Bot
7a88e72f82 New translations en.json (French) 2024-10-15 13:15:42 +02:00
Excalidraw Bot
d132221f9f New translations en.json (Chinese Simplified) 2024-10-14 05:51:53 +02:00
Excalidraw Bot
46a7204d41 New translations en.json (Korean) 2024-10-12 10:18:26 +02:00
Excalidraw Bot
c46038b47e New translations en.json (Korean) 2024-10-12 09:08:57 +02:00
Excalidraw Bot
1ec6828470 New translations en.json (Slovak) 2024-10-05 09:29:19 +02:00
Excalidraw Bot
8d5d10b352 New translations en.json (Swedish) 2024-10-04 16:47:21 +02:00
Excalidraw Bot
09585d312b New translations en.json (Swedish) 2024-10-04 15:02:33 +02:00
Excalidraw Bot
7e8b2ad87e New translations en.json (Turkish) 2024-10-03 15:45:15 +02:00
Excalidraw Bot
26c6bd8942 New translations en.json (Portuguese, Brazilian) 2024-10-01 18:35:44 +02:00
Excalidraw Bot
d198280f6c New translations en.json (Chinese Simplified) 2024-09-26 12:55:03 +02:00
Excalidraw Bot
573adc72a2 New translations en.json (Japanese) 2024-09-26 12:55:01 +02:00
Excalidraw Bot
94dcc50578 New translations en.json (Hebrew) 2024-09-20 11:33:55 +02:00
Excalidraw Bot
1b8591d297 New translations en.json (Hebrew) 2024-09-20 09:16:14 +02:00
Excalidraw Bot
a3afb5551b New translations en.json (Chinese Traditional) 2024-09-16 05:50:12 +02:00
Excalidraw Bot
cda10a8aff New translations en.json (Persian) 2024-09-13 23:05:05 +02:00
Excalidraw Bot
a0d7a0a178 New translations en.json (Polish) 2024-09-12 18:49:55 +02:00
Excalidraw Bot
c94e69abbb New translations en.json (Polish) 2024-09-12 15:08:27 +02:00
Excalidraw Bot
c1227e5e65 New translations en.json (Ukrainian) 2024-09-12 14:10:48 +02:00
Excalidraw Bot
f535d1a2c1 New translations en.json (Hindi) 2024-09-12 08:06:48 +02:00
Excalidraw Bot
a2be6780de New translations en.json (Marathi) 2024-09-12 08:06:47 +02:00
Excalidraw Bot
fc174d14c4 New translations en.json (Hindi) 2024-09-12 07:08:04 +02:00
Excalidraw Bot
69fef3808b New translations en.json (Marathi) 2024-09-12 07:08:03 +02:00
Excalidraw Bot
d63e67f1ef New translations en.json (Russian) 2024-09-11 22:32:08 +02:00
Excalidraw Bot
bbbde64199 New translations en.json (Slovenian) 2024-09-11 20:55:49 +02:00
Excalidraw Bot
136eb8bbad New translations en.json (German) 2024-09-11 20:55:47 +02:00
Excalidraw Bot
220952d014 New translations en.json (Romanian) 2024-09-11 20:55:46 +02:00
Excalidraw Bot
789ccd857a New translations en.json (Hindi) 2024-09-11 19:34:29 +02:00
Excalidraw Bot
4270b2c013 New translations en.json (Marathi) 2024-09-11 19:34:24 +02:00
Excalidraw Bot
98f432ff8e New translations en.json (Chinese Traditional) 2024-09-11 19:34:19 +02:00
Excalidraw Bot
3aeb0dde1f New translations en.json (Swedish) 2024-09-11 19:34:15 +02:00
Excalidraw Bot
a6e3e4c1d9 New translations en.json (Slovenian) 2024-09-11 19:34:14 +02:00
Excalidraw Bot
34defc0327 New translations en.json (Russian) 2024-09-11 19:34:13 +02:00
Excalidraw Bot
a76508746a New translations en.json (Portuguese) 2024-09-11 19:34:12 +02:00
Excalidraw Bot
624c80e80a New translations en.json (German) 2024-09-11 19:34:03 +02:00
Excalidraw Bot
0f695e41e1 New translations en.json (Romanian) 2024-09-11 19:33:58 +02:00
Excalidraw Bot
13dbb4fcc5 New translations en.json (Polish) 2024-09-11 19:33:56 +02:00
Excalidraw Bot
59d5d7e0b5 New translations en.json (German, Switzerland) 2024-09-11 19:33:55 +02:00
Excalidraw Bot
8f6323fd38 New translations en.json (Hindi) 2024-09-11 11:46:51 +02:00
Excalidraw Bot
4f5ba867be New translations en.json (Marathi) 2024-09-11 11:46:49 +02:00
Excalidraw Bot
2ff791a31b New translations en.json (Polish) 2024-09-11 11:46:48 +02:00
Excalidraw Bot
678b8edb87 New translations en.json (Romanian) 2024-09-10 21:20:50 +02:00
Excalidraw Bot
6e29b3ad25 New translations en.json (Swedish) 2024-09-10 09:34:34 +02:00
Excalidraw Bot
31e812c084 New translations en.json (Slovenian) 2024-09-10 09:34:32 +02:00
Excalidraw Bot
4b3dd5ba71 New translations en.json (Chinese Traditional) 2024-09-10 06:19:12 +02:00
Excalidraw Bot
941219be23 New translations en.json (Russian) 2024-09-09 23:40:22 +02:00
Excalidraw Bot
c74ee59fee New translations en.json (Portuguese) 2024-09-09 21:08:26 +02:00
Excalidraw Bot
b35bcdb09e New translations en.json (German) 2024-09-09 19:49:08 +02:00
Excalidraw Bot
e3fdaf7e9d New translations en.json (Karakalpak) 2024-09-09 17:31:44 +02:00
Excalidraw Bot
55b438017f New translations en.json (Kabyle) 2024-09-09 17:31:43 +02:00
Excalidraw Bot
52a95589d6 New translations en.json (Bengali, India) 2024-09-09 17:31:42 +02:00
Excalidraw Bot
e1351768c8 New translations en.json (Occitan) 2024-09-09 17:31:40 +02:00
Excalidraw Bot
03867d184a New translations en.json (Norwegian Bokmal) 2024-09-09 17:31:39 +02:00
Excalidraw Bot
63511c149a New translations en.json (Uzbek) 2024-09-09 17:31:38 +02:00
Excalidraw Bot
28aa841d8e New translations en.json (Sinhala) 2024-09-09 17:31:35 +02:00
Excalidraw Bot
cbd1d07c91 New translations en.json (Chinese Traditional, Hong Kong) 2024-09-09 17:31:34 +02:00
Excalidraw Bot
b8add8f2ed New translations en.json (Burmese) 2024-09-09 17:31:33 +02:00
Excalidraw Bot
632e9d492f New translations en.json (Hindi) 2024-09-09 17:31:32 +02:00
Excalidraw Bot
5f848e58c3 New translations en.json (Azerbaijani) 2024-09-09 17:31:31 +02:00
Excalidraw Bot
f67c30d062 New translations en.json (Latvian) 2024-09-09 17:31:29 +02:00
Excalidraw Bot
195b05cd44 New translations en.json (Kazakh) 2024-09-09 17:31:28 +02:00
Excalidraw Bot
09ebef19dd New translations en.json (Norwegian Nynorsk) 2024-09-09 17:31:27 +02:00
Excalidraw Bot
d465b5df2a New translations en.json (Thai) 2024-09-09 17:31:26 +02:00
Excalidraw Bot
8a88c67b60 New translations en.json (Marathi) 2024-09-09 17:31:24 +02:00
Excalidraw Bot
4f3acdee72 New translations en.json (Bengali) 2024-09-09 17:31:23 +02:00
Excalidraw Bot
dab9274cdd New translations en.json (Tamil) 2024-09-09 17:31:22 +02:00
Excalidraw Bot
b0991c13d9 New translations en.json (Khmer) 2024-09-09 17:31:21 +02:00
Excalidraw Bot
0d727dd01a New translations en.json (Indonesian) 2024-09-09 17:31:20 +02:00
Excalidraw Bot
d4b6a1a89c New translations en.json (Portuguese, Brazilian) 2024-09-09 17:31:19 +02:00
Excalidraw Bot
425736cb55 New translations en.json (Galician) 2024-09-09 17:31:18 +02:00
Excalidraw Bot
094f35e1a1 New translations en.json (Vietnamese) 2024-09-09 17:31:17 +02:00
Excalidraw Bot
6f93afcbd7 New translations en.json (Chinese Traditional) 2024-09-09 17:31:16 +02:00
Excalidraw Bot
71678ed812 New translations en.json (Chinese Simplified) 2024-09-09 17:31:14 +02:00
Excalidraw Bot
d19c45d42c New translations en.json (Ukrainian) 2024-09-09 17:31:13 +02:00
Excalidraw Bot
9d29320bc0 New translations en.json (Turkish) 2024-09-09 17:31:12 +02:00
Excalidraw Bot
f083ba7f8d New translations en.json (Swedish) 2024-09-09 17:31:11 +02:00
Excalidraw Bot
bfa4205bf7 New translations en.json (Slovenian) 2024-09-09 17:31:10 +02:00
Excalidraw Bot
c4d3cb7d4e New translations en.json (Slovak) 2024-09-09 17:31:09 +02:00
Excalidraw Bot
1fe128e53b New translations en.json (Russian) 2024-09-09 17:31:07 +02:00
Excalidraw Bot
25f3c1486c New translations en.json (Portuguese) 2024-09-09 17:31:06 +02:00
Excalidraw Bot
620f837b82 New translations en.json (Punjabi) 2024-09-09 17:31:05 +02:00
Excalidraw Bot
65a58cb080 New translations en.json (Dutch) 2024-09-09 17:31:04 +02:00
Excalidraw Bot
f9d9d8eefc New translations en.json (Lithuanian) 2024-09-09 17:31:03 +02:00
Excalidraw Bot
5f5d8dea8a New translations en.json (Kurdish) 2024-09-09 17:31:01 +02:00
Excalidraw Bot
230827cba5 New translations en.json (Korean) 2024-09-09 17:31:00 +02:00
Excalidraw Bot
53c7487113 New translations en.json (Japanese) 2024-09-09 17:30:59 +02:00
Excalidraw Bot
d5b4287f41 New translations en.json (Italian) 2024-09-09 17:30:58 +02:00
Excalidraw Bot
c29b7a5c7a New translations en.json (Hungarian) 2024-09-09 17:30:57 +02:00
Excalidraw Bot
a56dd2a529 New translations en.json (Hebrew) 2024-09-09 17:30:55 +02:00
Excalidraw Bot
14b59805a2 New translations en.json (Finnish) 2024-09-09 17:30:54 +02:00
Excalidraw Bot
e01e1be3de New translations en.json (Basque) 2024-09-09 17:30:53 +02:00
Excalidraw Bot
d403251fd7 New translations en.json (German) 2024-09-09 17:30:52 +02:00
Excalidraw Bot
d46c9d35b7 New translations en.json (Danish) 2024-09-09 17:30:51 +02:00
Excalidraw Bot
5fa9193415 New translations en.json (Czech) 2024-09-09 17:30:50 +02:00
Excalidraw Bot
239767be22 New translations en.json (Catalan) 2024-09-09 17:30:49 +02:00
Excalidraw Bot
7ce49d3566 New translations en.json (Bulgarian) 2024-09-09 17:30:48 +02:00
Excalidraw Bot
e228cca96b New translations en.json (Arabic) 2024-09-09 17:30:47 +02:00
Excalidraw Bot
92f2b0b0e1 New translations en.json (Spanish) 2024-09-09 17:30:45 +02:00
Excalidraw Bot
01d1639141 New translations en.json (French) 2024-09-09 17:30:44 +02:00
Excalidraw Bot
11272a101f New translations en.json (Romanian) 2024-09-09 17:30:43 +02:00
Excalidraw Bot
d2bdb7ab0b New translations en.json (Greek) 2024-09-09 17:30:42 +02:00
Excalidraw Bot
bc0d3b1a67 New translations en.json (Polish) 2024-09-09 17:30:41 +02:00
Excalidraw Bot
e2451d9c7f New translations en.json (German, Switzerland) 2024-09-09 17:30:40 +02:00
Excalidraw Bot
670887e3f3 New translations en.json (Persian) 2024-09-09 17:30:38 +02:00
Excalidraw Bot
345e3535b4 New translations en.json (Slovak) 2024-09-05 15:45:17 +02:00
Excalidraw Bot
5eeeba0333 New translations en.json (Hebrew) 2024-09-03 23:55:19 +02:00
Excalidraw Bot
df351f3b30 New translations en.json (Portuguese) 2024-09-03 19:33:06 +02:00
Excalidraw Bot
29d5da3e66 New translations en.json (French) 2024-09-03 11:35:20 +02:00
Excalidraw Bot
12d35d3da3 New translations en.json (Ukrainian) 2024-08-31 17:08:12 +02:00
Excalidraw Bot
a067dd0faa New translations en.json (Greek) 2024-08-31 13:53:33 +02:00
Excalidraw Bot
4758d28ac1 New translations en.json (Portuguese, Brazilian) 2024-08-31 07:10:40 +02:00
Excalidraw Bot
bfc9692ad1 New translations en.json (Italian) 2024-08-30 14:42:21 +02:00
Excalidraw Bot
a23fef8afe New translations en.json (Chinese Traditional) 2024-08-28 16:34:09 +02:00
Excalidraw Bot
2827117eb4 New translations en.json (Polish) 2024-08-27 22:22:10 +02:00
Excalidraw Bot
e11d71d9c1 New translations en.json (German) 2024-08-27 13:48:03 +02:00
Excalidraw Bot
0aacafc032 New translations en.json (Romanian) 2024-08-27 11:46:25 +02:00
Excalidraw Bot
573e947b31 New translations en.json (Russian) 2024-08-27 10:37:45 +02:00
Excalidraw Bot
128e5a0ef0 New translations en.json (Hindi) 2024-08-27 08:40:04 +02:00
Excalidraw Bot
114033dde4 New translations en.json (Marathi) 2024-08-27 08:40:03 +02:00
Excalidraw Bot
3cc0f2e452 New translations en.json (Slovenian) 2024-08-27 08:40:01 +02:00
Excalidraw Bot
28a08686a8 New translations en.json (Russian) 2024-08-27 08:40:00 +02:00
Excalidraw Bot
100e47307b New translations en.json (Chinese Simplified) 2024-08-27 06:53:14 +02:00
Excalidraw Bot
254e6f4d30 New translations en.json (Karakalpak) 2024-08-27 00:32:35 +02:00
Excalidraw Bot
d63d5a2602 New translations en.json (Kabyle) 2024-08-27 00:32:34 +02:00
Excalidraw Bot
729cdc0c2b New translations en.json (Bengali, India) 2024-08-27 00:32:33 +02:00
Excalidraw Bot
253ac4af2d New translations en.json (Occitan) 2024-08-27 00:32:32 +02:00
Excalidraw Bot
63863f2530 New translations en.json (Norwegian Bokmal) 2024-08-27 00:32:31 +02:00
Excalidraw Bot
3bd04e55ab New translations en.json (Uzbek) 2024-08-27 00:32:30 +02:00
Excalidraw Bot
8fd9b5c791 New translations en.json (Sinhala) 2024-08-27 00:32:29 +02:00
Excalidraw Bot
3c7671f160 New translations en.json (Chinese Traditional, Hong Kong) 2024-08-27 00:32:28 +02:00
Excalidraw Bot
16b50fad38 New translations en.json (Burmese) 2024-08-27 00:32:27 +02:00
Excalidraw Bot
a09bd51978 New translations en.json (Hindi) 2024-08-27 00:32:26 +02:00
Excalidraw Bot
829624199b New translations en.json (Azerbaijani) 2024-08-27 00:32:25 +02:00
Excalidraw Bot
3fa3460d1a New translations en.json (Latvian) 2024-08-27 00:32:24 +02:00
Excalidraw Bot
309c1252a6 New translations en.json (Kazakh) 2024-08-27 00:32:23 +02:00
Excalidraw Bot
444673a54e New translations en.json (Norwegian Nynorsk) 2024-08-27 00:32:22 +02:00
Excalidraw Bot
0f58f4dbeb New translations en.json (Thai) 2024-08-27 00:32:21 +02:00
Excalidraw Bot
bbb4d88c2a New translations en.json (Marathi) 2024-08-27 00:32:20 +02:00
Excalidraw Bot
ad0964116a New translations en.json (Bengali) 2024-08-27 00:32:19 +02:00
Excalidraw Bot
91a58912ce New translations en.json (Tamil) 2024-08-27 00:32:18 +02:00
Excalidraw Bot
2c8a913770 New translations en.json (Khmer) 2024-08-27 00:32:17 +02:00
Excalidraw Bot
c37b4ee3f7 New translations en.json (Indonesian) 2024-08-27 00:32:16 +02:00
Excalidraw Bot
85726121a8 New translations en.json (Portuguese, Brazilian) 2024-08-27 00:32:15 +02:00
Excalidraw Bot
1b65578c44 New translations en.json (Galician) 2024-08-27 00:32:14 +02:00
Excalidraw Bot
24fe9663f0 New translations en.json (Vietnamese) 2024-08-27 00:32:13 +02:00
Excalidraw Bot
a54bccf04e New translations en.json (Chinese Traditional) 2024-08-27 00:32:12 +02:00
Excalidraw Bot
50777b6b43 New translations en.json (Chinese Simplified) 2024-08-27 00:32:11 +02:00
Excalidraw Bot
fde9dfe20f New translations en.json (Ukrainian) 2024-08-27 00:32:10 +02:00
Excalidraw Bot
d2ddce8012 New translations en.json (Turkish) 2024-08-27 00:32:09 +02:00
Excalidraw Bot
09a3831733 New translations en.json (Swedish) 2024-08-27 00:32:07 +02:00
Excalidraw Bot
a036419535 New translations en.json (Slovenian) 2024-08-27 00:32:06 +02:00
Excalidraw Bot
e278d51713 New translations en.json (Slovak) 2024-08-27 00:32:05 +02:00
Excalidraw Bot
fcfafce65b New translations en.json (Russian) 2024-08-27 00:32:04 +02:00
Excalidraw Bot
886eb2c588 New translations en.json (Portuguese) 2024-08-27 00:32:03 +02:00
Excalidraw Bot
cfa71f5045 New translations en.json (Punjabi) 2024-08-27 00:32:02 +02:00
Excalidraw Bot
f5c100ed62 New translations en.json (Dutch) 2024-08-27 00:32:01 +02:00
Excalidraw Bot
bd6f81b088 New translations en.json (Lithuanian) 2024-08-27 00:32:00 +02:00
Excalidraw Bot
13f2105589 New translations en.json (Kurdish) 2024-08-27 00:31:59 +02:00
Excalidraw Bot
80e9e037ea New translations en.json (Korean) 2024-08-27 00:31:58 +02:00
Excalidraw Bot
98a6ea7e3a New translations en.json (Japanese) 2024-08-27 00:31:57 +02:00
Excalidraw Bot
83b72ace65 New translations en.json (Italian) 2024-08-27 00:31:56 +02:00
Excalidraw Bot
406fb15bd9 New translations en.json (Hungarian) 2024-08-27 00:31:55 +02:00
Excalidraw Bot
a50b9be1de New translations en.json (Hebrew) 2024-08-27 00:31:54 +02:00
Excalidraw Bot
71cc6a3bfd New translations en.json (Finnish) 2024-08-27 00:31:53 +02:00
Excalidraw Bot
ec99637bb2 New translations en.json (Basque) 2024-08-27 00:31:52 +02:00
Excalidraw Bot
5d4ee260b3 New translations en.json (German) 2024-08-27 00:31:51 +02:00
Excalidraw Bot
32e295ed8c New translations en.json (Danish) 2024-08-27 00:31:50 +02:00
Excalidraw Bot
c22843a7f1 New translations en.json (Czech) 2024-08-27 00:31:49 +02:00
Excalidraw Bot
be155a676f New translations en.json (Catalan) 2024-08-27 00:31:48 +02:00
Excalidraw Bot
7288582ef2 New translations en.json (Bulgarian) 2024-08-27 00:31:47 +02:00
Excalidraw Bot
e1376f3f74 New translations en.json (Arabic) 2024-08-27 00:31:46 +02:00
Excalidraw Bot
7f25d2f5b5 New translations en.json (Spanish) 2024-08-27 00:31:45 +02:00
Excalidraw Bot
e36f9f56d0 New translations en.json (French) 2024-08-27 00:31:44 +02:00
Excalidraw Bot
2cf88adca9 New translations en.json (Romanian) 2024-08-27 00:31:43 +02:00
Excalidraw Bot
07ad3271b4 New translations en.json (Greek) 2024-08-27 00:31:42 +02:00
Excalidraw Bot
6861334dad New translations en.json (Polish) 2024-08-27 00:31:41 +02:00
Excalidraw Bot
fbc27a7fd1 New translations en.json (German, Switzerland) 2024-08-27 00:31:40 +02:00
Excalidraw Bot
557aa9fa33 New translations en.json (Persian) 2024-08-27 00:31:39 +02:00
Excalidraw Bot
376c7590b5 New translations en.json (Catalan) 2024-08-21 08:56:29 +02:00
Excalidraw Bot
f258ab3a4e New translations en.json (Karakalpak) 2024-08-20 18:38:10 +02:00
Excalidraw Bot
c4f6ff7acc New translations en.json (Kabyle) 2024-08-20 18:38:09 +02:00
Excalidraw Bot
b0e7b86670 New translations en.json (Bengali, India) 2024-08-20 18:38:08 +02:00
Excalidraw Bot
723e1f7b78 New translations en.json (Occitan) 2024-08-20 18:38:07 +02:00
Excalidraw Bot
e6ac11c33d New translations en.json (Norwegian Bokmal) 2024-08-20 18:38:06 +02:00
Excalidraw Bot
fbc5f0460d New translations en.json (Uzbek) 2024-08-20 18:38:05 +02:00
Excalidraw Bot
4c81264c8c New translations en.json (Sinhala) 2024-08-20 18:38:04 +02:00
Excalidraw Bot
fd6750f4cf New translations en.json (Chinese Traditional, Hong Kong) 2024-08-20 18:38:02 +02:00
Excalidraw Bot
c5fed6cdf1 New translations en.json (Burmese) 2024-08-20 18:38:01 +02:00
Excalidraw Bot
4e9f6f3e0e New translations en.json (Hindi) 2024-08-20 18:38:00 +02:00
Excalidraw Bot
b9b37c2b33 New translations en.json (Azerbaijani) 2024-08-20 18:37:59 +02:00
Excalidraw Bot
679a293a18 New translations en.json (Latvian) 2024-08-20 18:37:58 +02:00
Excalidraw Bot
d51dca6c40 New translations en.json (Kazakh) 2024-08-20 18:37:57 +02:00
Excalidraw Bot
a0f0aaab05 New translations en.json (Norwegian Nynorsk) 2024-08-20 18:37:55 +02:00
Excalidraw Bot
5af4b4e7ce New translations en.json (Thai) 2024-08-20 18:37:54 +02:00
Excalidraw Bot
c688d4cbe4 New translations en.json (Marathi) 2024-08-20 18:37:53 +02:00
Excalidraw Bot
c98d4795fb New translations en.json (Bengali) 2024-08-20 18:37:52 +02:00
Excalidraw Bot
c3ceace600 New translations en.json (Tamil) 2024-08-20 18:37:51 +02:00
Excalidraw Bot
3dd2ef328c New translations en.json (Khmer) 2024-08-20 18:37:50 +02:00
Excalidraw Bot
1f75307d2f New translations en.json (Indonesian) 2024-08-20 18:37:48 +02:00
Excalidraw Bot
b1b1cacddf New translations en.json (Portuguese, Brazilian) 2024-08-20 18:37:47 +02:00
Excalidraw Bot
ed564b64ec New translations en.json (Galician) 2024-08-20 18:37:46 +02:00
Excalidraw Bot
6eb4c1e59f New translations en.json (Vietnamese) 2024-08-20 18:37:45 +02:00
Excalidraw Bot
4009c4d69c New translations en.json (Chinese Traditional) 2024-08-20 18:37:44 +02:00
Excalidraw Bot
c143334183 New translations en.json (Chinese Simplified) 2024-08-20 18:37:43 +02:00
Excalidraw Bot
bddacee80d New translations en.json (Ukrainian) 2024-08-20 18:37:42 +02:00
Excalidraw Bot
e6d5fa793d New translations en.json (Turkish) 2024-08-20 18:37:40 +02:00
Excalidraw Bot
ffc0752cba New translations en.json (Swedish) 2024-08-20 18:37:39 +02:00
Excalidraw Bot
a8de15517a New translations en.json (Slovenian) 2024-08-20 18:37:38 +02:00
Excalidraw Bot
a6fb388f5d New translations en.json (Slovak) 2024-08-20 18:37:37 +02:00
Excalidraw Bot
1a61e8f98a New translations en.json (Russian) 2024-08-20 18:37:35 +02:00
Excalidraw Bot
defbbc327c New translations en.json (Portuguese) 2024-08-20 18:37:34 +02:00
Excalidraw Bot
12f5d3c516 New translations en.json (Punjabi) 2024-08-20 18:37:33 +02:00
Excalidraw Bot
045f75161e New translations en.json (Dutch) 2024-08-20 18:37:32 +02:00
Excalidraw Bot
dfcbfaf155 New translations en.json (Lithuanian) 2024-08-20 18:37:31 +02:00
Excalidraw Bot
d233f3b60f New translations en.json (Kurdish) 2024-08-20 18:37:30 +02:00
Excalidraw Bot
b4e84e1cb9 New translations en.json (Korean) 2024-08-20 18:37:29 +02:00
Excalidraw Bot
630991b85a New translations en.json (Japanese) 2024-08-20 18:37:27 +02:00
Excalidraw Bot
2afbb7b0cd New translations en.json (Italian) 2024-08-20 18:37:26 +02:00
Excalidraw Bot
e95f4bd56a New translations en.json (Hungarian) 2024-08-20 18:37:25 +02:00
Excalidraw Bot
88b7830aa7 New translations en.json (Hebrew) 2024-08-20 18:37:24 +02:00
Excalidraw Bot
035d6b8b95 New translations en.json (Finnish) 2024-08-20 18:37:22 +02:00
Excalidraw Bot
d3f1d67e82 New translations en.json (Basque) 2024-08-20 18:37:21 +02:00
Excalidraw Bot
27b3e5ad99 New translations en.json (German) 2024-08-20 18:37:20 +02:00
Excalidraw Bot
7512deca3d New translations en.json (Danish) 2024-08-20 18:37:19 +02:00
Excalidraw Bot
66eaa610d1 New translations en.json (Czech) 2024-08-20 18:37:17 +02:00
Excalidraw Bot
6e4dcd4829 New translations en.json (Catalan) 2024-08-20 18:37:16 +02:00
Excalidraw Bot
d24c462d1c New translations en.json (Bulgarian) 2024-08-20 18:37:14 +02:00
Excalidraw Bot
070b693163 New translations en.json (Arabic) 2024-08-20 18:37:13 +02:00
Excalidraw Bot
12c697a67c New translations en.json (Spanish) 2024-08-20 18:37:11 +02:00
Excalidraw Bot
8e260bb8f0 New translations en.json (French) 2024-08-20 18:37:09 +02:00
Excalidraw Bot
62c096deb2 New translations en.json (Romanian) 2024-08-20 18:37:08 +02:00
Excalidraw Bot
afddbd88c6 New translations en.json (Greek) 2024-08-20 18:37:06 +02:00
Excalidraw Bot
e907c2cb98 New translations en.json (Polish) 2024-08-20 18:37:05 +02:00
Excalidraw Bot
4f1df9a3bf New translations en.json (German, Switzerland) 2024-08-20 18:37:03 +02:00
Excalidraw Bot
3ac658dd26 New translations en.json (Persian) 2024-08-20 18:37:01 +02:00
Excalidraw Bot
1c5581be0d New translations en.json (Portuguese) 2024-08-20 16:04:08 +02:00
Excalidraw Bot
6a0a34e0e7 New translations en.json (Vietnamese) 2024-08-18 16:30:42 +02:00
Excalidraw Bot
f560a7da67 New translations en.json (Greek) 2024-08-15 21:43:42 +02:00
Excalidraw Bot
2d4f69f83f New translations en.json (Chinese Simplified) 2024-08-13 07:18:53 +02:00
Excalidraw Bot
c124d99010 New translations en.json (Swedish) 2024-08-13 07:18:52 +02:00
Excalidraw Bot
59e5678151 New translations en.json (Polish) 2024-08-12 13:40:48 +02:00
Excalidraw Bot
a179dd38cf New translations en.json (Chinese Traditional) 2024-08-12 11:58:44 +02:00
Excalidraw Bot
e014ffb5b3 New translations en.json (Romanian) 2024-08-12 09:54:49 +02:00
Excalidraw Bot
21453a4858 New translations en.json (Slovenian) 2024-08-11 21:52:58 +02:00
Excalidraw Bot
58b78e0744 New translations en.json (German) 2024-08-11 21:52:57 +02:00
Excalidraw Bot
ba14b526ab New translations en.json (Polish) 2024-08-11 20:55:44 +02:00
Excalidraw Bot
3aacd5baba New translations en.json (Karakalpak) 2024-08-11 19:53:34 +02:00
Excalidraw Bot
4625f1f01a New translations en.json (Kabyle) 2024-08-11 19:53:33 +02:00
Excalidraw Bot
8395c84aa9 New translations en.json (Bengali, India) 2024-08-11 19:53:32 +02:00
Excalidraw Bot
ee6d0a2a2c New translations en.json (Occitan) 2024-08-11 19:53:31 +02:00
Excalidraw Bot
0d91a3ee98 New translations en.json (Norwegian Bokmal) 2024-08-11 19:53:30 +02:00
Excalidraw Bot
5036bac094 New translations en.json (Uzbek) 2024-08-11 19:53:29 +02:00
Excalidraw Bot
b82556aafd New translations en.json (Sinhala) 2024-08-11 19:53:27 +02:00
Excalidraw Bot
50d04b5802 New translations en.json (Chinese Traditional, Hong Kong) 2024-08-11 19:53:26 +02:00
Excalidraw Bot
fd917664e7 New translations en.json (Burmese) 2024-08-11 19:53:25 +02:00
Excalidraw Bot
b3da75f525 New translations en.json (Hindi) 2024-08-11 19:53:23 +02:00
Excalidraw Bot
93d61a66c1 New translations en.json (Azerbaijani) 2024-08-11 19:53:22 +02:00
Excalidraw Bot
bed4fb9556 New translations en.json (Latvian) 2024-08-11 19:53:21 +02:00
Excalidraw Bot
7567ea5b20 New translations en.json (Kazakh) 2024-08-11 19:53:20 +02:00
Excalidraw Bot
964c253fb8 New translations en.json (Norwegian Nynorsk) 2024-08-11 19:53:19 +02:00
Excalidraw Bot
dba1ac4ac6 New translations en.json (Thai) 2024-08-11 19:53:18 +02:00
Excalidraw Bot
f30f1e9eff New translations en.json (Marathi) 2024-08-11 19:53:17 +02:00
Excalidraw Bot
a74bbb0549 New translations en.json (Bengali) 2024-08-11 19:53:16 +02:00
Excalidraw Bot
b5cc1b4ee0 New translations en.json (Tamil) 2024-08-11 19:53:15 +02:00
Excalidraw Bot
3df2c55850 New translations en.json (Khmer) 2024-08-11 19:53:14 +02:00
Excalidraw Bot
0e0b3c62bb New translations en.json (Indonesian) 2024-08-11 19:53:13 +02:00
Excalidraw Bot
ef9b51b47c New translations en.json (Portuguese, Brazilian) 2024-08-11 19:53:12 +02:00
Excalidraw Bot
972db67e55 New translations en.json (Galician) 2024-08-11 19:53:10 +02:00
Excalidraw Bot
e61102d919 New translations en.json (Vietnamese) 2024-08-11 19:53:09 +02:00
Excalidraw Bot
460ea95712 New translations en.json (Chinese Traditional) 2024-08-11 19:53:08 +02:00
Excalidraw Bot
be199f7abb New translations en.json (Chinese Simplified) 2024-08-11 19:53:07 +02:00
Excalidraw Bot
710bffc99c New translations en.json (Ukrainian) 2024-08-11 19:53:06 +02:00
Excalidraw Bot
dec4acdf27 New translations en.json (Turkish) 2024-08-11 19:53:05 +02:00
Excalidraw Bot
dfd70691a9 New translations en.json (Swedish) 2024-08-11 19:53:04 +02:00
Excalidraw Bot
50f7c9d484 New translations en.json (Slovenian) 2024-08-11 19:53:03 +02:00
Excalidraw Bot
f755b09d0d New translations en.json (Slovak) 2024-08-11 19:53:02 +02:00
Excalidraw Bot
70db9f695d New translations en.json (Russian) 2024-08-11 19:53:01 +02:00
Excalidraw Bot
7523ef5869 New translations en.json (Portuguese) 2024-08-11 19:53:00 +02:00
Excalidraw Bot
b7bc8e43ff New translations en.json (Punjabi) 2024-08-11 19:52:59 +02:00
Excalidraw Bot
21c4bac6fc New translations en.json (Dutch) 2024-08-11 19:52:58 +02:00
Excalidraw Bot
e90f450bce New translations en.json (Lithuanian) 2024-08-11 19:52:57 +02:00
Excalidraw Bot
816d3b4b9f New translations en.json (Kurdish) 2024-08-11 19:52:56 +02:00
Excalidraw Bot
9c41187f82 New translations en.json (Korean) 2024-08-11 19:52:55 +02:00
Excalidraw Bot
24b3f87fb3 New translations en.json (Japanese) 2024-08-11 19:52:54 +02:00
Excalidraw Bot
acdae07f35 New translations en.json (Italian) 2024-08-11 19:52:53 +02:00
Excalidraw Bot
a8a67eee74 New translations en.json (Hungarian) 2024-08-11 19:52:52 +02:00
Excalidraw Bot
88fe797d83 New translations en.json (Hebrew) 2024-08-11 19:52:51 +02:00
Excalidraw Bot
d832cfdf71 New translations en.json (Finnish) 2024-08-11 19:52:50 +02:00
Excalidraw Bot
4af813173c New translations en.json (Basque) 2024-08-11 19:52:48 +02:00
Excalidraw Bot
ceeef17c00 New translations en.json (German) 2024-08-11 19:52:47 +02:00
Excalidraw Bot
90a609e7fb New translations en.json (Danish) 2024-08-11 19:52:46 +02:00
Excalidraw Bot
4091d1ef45 New translations en.json (Czech) 2024-08-11 19:52:45 +02:00
Excalidraw Bot
8bfbb60161 New translations en.json (Catalan) 2024-08-11 19:52:44 +02:00
Excalidraw Bot
cea8eb7c35 New translations en.json (Bulgarian) 2024-08-11 19:52:43 +02:00
Excalidraw Bot
339904c990 New translations en.json (Arabic) 2024-08-11 19:52:42 +02:00
Excalidraw Bot
05a087a83d New translations en.json (Spanish) 2024-08-11 19:52:41 +02:00
Excalidraw Bot
c82509b5d2 New translations en.json (French) 2024-08-11 19:52:41 +02:00
Excalidraw Bot
b8ba1918c9 New translations en.json (Romanian) 2024-08-11 19:52:40 +02:00
Excalidraw Bot
f12bf79694 New translations en.json (Greek) 2024-08-11 19:52:38 +02:00
Excalidraw Bot
0b276a371e New translations en.json (Polish) 2024-08-11 19:52:37 +02:00
Excalidraw Bot
0902c97806 New translations en.json (German, Switzerland) 2024-08-11 19:52:36 +02:00
Excalidraw Bot
32d460878d New translations en.json (Persian) 2024-08-11 19:52:35 +02:00
Excalidraw Bot
9a379fb81c New translations en.json (Slovak) 2024-08-11 09:14:17 +02:00
Excalidraw Bot
2f207b561a New translations en.json (Slovak) 2024-08-11 07:50:50 +02:00
Excalidraw Bot
14304f8402 New translations en.json (Romanian) 2024-08-10 18:30:16 +02:00
Excalidraw Bot
d9421730a4 New translations en.json (German) 2024-08-09 20:49:39 +02:00
Excalidraw Bot
fe71ee55c6 New translations en.json (Chinese Traditional) 2024-08-09 09:10:20 +02:00
Excalidraw Bot
8b9cfc82ea New translations en.json (Chinese Traditional) 2024-08-09 07:50:42 +02:00
Excalidraw Bot
2384ac65c3 New translations en.json (Karakalpak) 2024-08-08 23:39:51 +02:00
Excalidraw Bot
71d487762e New translations en.json (Kabyle) 2024-08-08 23:39:49 +02:00
Excalidraw Bot
089136d6e6 New translations en.json (Bengali, India) 2024-08-08 23:39:48 +02:00
Excalidraw Bot
f9955e079e New translations en.json (Occitan) 2024-08-08 23:39:47 +02:00
Excalidraw Bot
1471f87845 New translations en.json (Norwegian Bokmal) 2024-08-08 23:39:46 +02:00
Excalidraw Bot
9467d53088 New translations en.json (Uzbek) 2024-08-08 23:39:45 +02:00
Excalidraw Bot
20eec11057 New translations en.json (Sinhala) 2024-08-08 23:39:44 +02:00
Excalidraw Bot
49dd1c376f New translations en.json (Chinese Traditional, Hong Kong) 2024-08-08 23:39:43 +02:00
Excalidraw Bot
47b4cc67fc New translations en.json (Burmese) 2024-08-08 23:39:42 +02:00
Excalidraw Bot
b4707a1f9f New translations en.json (Hindi) 2024-08-08 23:39:41 +02:00
Excalidraw Bot
c79060a5a4 New translations en.json (Azerbaijani) 2024-08-08 23:39:40 +02:00
Excalidraw Bot
3881f18b01 New translations en.json (Latvian) 2024-08-08 23:39:38 +02:00
Excalidraw Bot
a0d5fbac19 New translations en.json (Kazakh) 2024-08-08 23:39:37 +02:00
Excalidraw Bot
56cb6e7b4f New translations en.json (Norwegian Nynorsk) 2024-08-08 23:39:36 +02:00
Excalidraw Bot
2cc02f02b1 New translations en.json (Thai) 2024-08-08 23:39:35 +02:00
Excalidraw Bot
8f790a65a6 New translations en.json (Marathi) 2024-08-08 23:39:34 +02:00
Excalidraw Bot
fcd7f8daf4 New translations en.json (Bengali) 2024-08-08 23:39:33 +02:00
Excalidraw Bot
6db4b713eb New translations en.json (Tamil) 2024-08-08 23:39:32 +02:00
Excalidraw Bot
f902a93ea1 New translations en.json (Khmer) 2024-08-08 23:39:31 +02:00
Excalidraw Bot
a5e07e633d New translations en.json (Indonesian) 2024-08-08 23:39:30 +02:00
Excalidraw Bot
484a10779b New translations en.json (Portuguese, Brazilian) 2024-08-08 23:39:29 +02:00
Excalidraw Bot
62a9a97323 New translations en.json (Galician) 2024-08-08 23:39:28 +02:00
Excalidraw Bot
37d581abb7 New translations en.json (Vietnamese) 2024-08-08 23:39:27 +02:00
Excalidraw Bot
036f973fa2 New translations en.json (Chinese Traditional) 2024-08-08 23:39:26 +02:00
Excalidraw Bot
f4eeb8038e New translations en.json (Chinese Simplified) 2024-08-08 23:39:24 +02:00
Excalidraw Bot
a29c8365d9 New translations en.json (Ukrainian) 2024-08-08 23:39:23 +02:00
Excalidraw Bot
5d420f54a7 New translations en.json (Turkish) 2024-08-08 23:39:22 +02:00
Excalidraw Bot
35f4ab615f New translations en.json (Swedish) 2024-08-08 23:39:21 +02:00
Excalidraw Bot
043eadf13c New translations en.json (Slovenian) 2024-08-08 23:39:20 +02:00
Excalidraw Bot
a24077c0be New translations en.json (Slovak) 2024-08-08 23:39:19 +02:00
Excalidraw Bot
f958c99a84 New translations en.json (Russian) 2024-08-08 23:39:18 +02:00
Excalidraw Bot
cca43eee02 New translations en.json (Portuguese) 2024-08-08 23:39:17 +02:00
Excalidraw Bot
0d6e9c9537 New translations en.json (Punjabi) 2024-08-08 23:39:16 +02:00
Excalidraw Bot
9c94ea1544 New translations en.json (Dutch) 2024-08-08 23:39:15 +02:00
Excalidraw Bot
fb6804fbd3 New translations en.json (Lithuanian) 2024-08-08 23:39:13 +02:00
Excalidraw Bot
68c6247272 New translations en.json (Kurdish) 2024-08-08 23:39:12 +02:00
Excalidraw Bot
18042a880d New translations en.json (Korean) 2024-08-08 23:39:11 +02:00
Excalidraw Bot
ac06d58d48 New translations en.json (Japanese) 2024-08-08 23:39:10 +02:00
Excalidraw Bot
05d462a07d New translations en.json (Italian) 2024-08-08 23:39:09 +02:00
Excalidraw Bot
ab26013d32 New translations en.json (Hungarian) 2024-08-08 23:39:08 +02:00
Excalidraw Bot
2dcb0ccc1a New translations en.json (Hebrew) 2024-08-08 23:39:07 +02:00
Excalidraw Bot
73f5f9ce9b New translations en.json (Finnish) 2024-08-08 23:39:06 +02:00
Excalidraw Bot
b4fcde00d1 New translations en.json (Basque) 2024-08-08 23:39:05 +02:00
Excalidraw Bot
9d1a01d56d New translations en.json (German) 2024-08-08 23:39:04 +02:00
Excalidraw Bot
f6375b77d5 New translations en.json (Danish) 2024-08-08 23:39:02 +02:00
Excalidraw Bot
ff1c9b3405 New translations en.json (Czech) 2024-08-08 23:39:01 +02:00
Excalidraw Bot
9465e45c97 New translations en.json (Catalan) 2024-08-08 23:39:00 +02:00
Excalidraw Bot
a573fe6b71 New translations en.json (Bulgarian) 2024-08-08 23:38:59 +02:00
Excalidraw Bot
98655e64d5 New translations en.json (Arabic) 2024-08-08 23:38:58 +02:00
Excalidraw Bot
d35214c11b New translations en.json (Spanish) 2024-08-08 23:38:57 +02:00
Excalidraw Bot
2f813d00ed New translations en.json (French) 2024-08-08 23:38:56 +02:00
Excalidraw Bot
580724793b New translations en.json (Romanian) 2024-08-08 23:38:55 +02:00
Excalidraw Bot
fcb9b36b96 New translations en.json (Greek) 2024-08-08 23:38:54 +02:00
Excalidraw Bot
18e37b3abf New translations en.json (Polish) 2024-08-08 23:38:53 +02:00
Excalidraw Bot
379977edbe New translations en.json (German, Switzerland) 2024-08-08 23:38:52 +02:00
Excalidraw Bot
bf061edb78 New translations en.json (Persian) 2024-08-08 23:38:51 +02:00
Excalidraw Bot
616f84bc22 New translations en.json (Romanian) 2024-08-05 08:20:26 +02:00
Excalidraw Bot
a16be8b5c5 New translations en.json (Chinese Traditional) 2024-08-04 18:10:36 +02:00
Excalidraw Bot
296e50678a New translations en.json (Chinese Traditional) 2024-08-04 16:52:27 +02:00
Excalidraw Bot
a6bfa82517 New translations en.json (Hindi) 2024-08-03 17:31:40 +02:00
Excalidraw Bot
050ba515d6 New translations en.json (Marathi) 2024-08-03 17:31:39 +02:00
Excalidraw Bot
d5f559803f New translations en.json (German) 2024-08-02 19:51:09 +02:00
Excalidraw Bot
d0e64458ad New translations en.json (Swedish) 2024-08-02 11:43:46 +02:00
Excalidraw Bot
7715aa6360 New translations en.json (Catalan) 2024-08-02 11:43:45 +02:00
Excalidraw Bot
12e196efee New translations en.json (Chinese Simplified) 2024-08-02 01:53:35 +02:00
Excalidraw Bot
bae2574225 New translations en.json (Russian) 2024-08-01 23:14:35 +02:00
Excalidraw Bot
3137d222ad New translations en.json (Greek) 2024-08-01 23:14:34 +02:00
Excalidraw Bot
4dd0273105 New translations en.json (Slovenian) 2024-08-01 21:17:21 +02:00
Excalidraw Bot
b52ed3425f New translations en.json (Karakalpak) 2024-08-01 20:17:19 +02:00
Excalidraw Bot
9ed6b2576d New translations en.json (Kabyle) 2024-08-01 20:17:18 +02:00
Excalidraw Bot
c5d0401fe1 New translations en.json (Bengali, India) 2024-08-01 20:17:17 +02:00
Excalidraw Bot
da352d54e3 New translations en.json (Occitan) 2024-08-01 20:17:16 +02:00
Excalidraw Bot
40acfd5a25 New translations en.json (Norwegian Bokmal) 2024-08-01 20:17:15 +02:00
Excalidraw Bot
469ab67b2b New translations en.json (Uzbek) 2024-08-01 20:17:13 +02:00
Excalidraw Bot
94c8ca8ced New translations en.json (Sinhala) 2024-08-01 20:17:12 +02:00
Excalidraw Bot
096d6cdb80 New translations en.json (Chinese Traditional, Hong Kong) 2024-08-01 20:17:11 +02:00
Excalidraw Bot
a35abe3398 New translations en.json (Burmese) 2024-08-01 20:17:10 +02:00
Excalidraw Bot
d987d60c14 New translations en.json (Hindi) 2024-08-01 20:17:09 +02:00
Excalidraw Bot
04c2778906 New translations en.json (Azerbaijani) 2024-08-01 20:17:07 +02:00
Excalidraw Bot
e823664f11 New translations en.json (Latvian) 2024-08-01 20:17:06 +02:00
Excalidraw Bot
e09532fd6d New translations en.json (Kazakh) 2024-08-01 20:17:05 +02:00
Excalidraw Bot
26126fd2a5 New translations en.json (Norwegian Nynorsk) 2024-08-01 20:17:04 +02:00
Excalidraw Bot
e8bdb88744 New translations en.json (Thai) 2024-08-01 20:17:02 +02:00
Excalidraw Bot
b91cebbe52 New translations en.json (Marathi) 2024-08-01 20:17:01 +02:00
Excalidraw Bot
90082d3c0d New translations en.json (Bengali) 2024-08-01 20:17:00 +02:00
Excalidraw Bot
de6f6e26c2 New translations en.json (Tamil) 2024-08-01 20:16:59 +02:00
Excalidraw Bot
8ae8cab963 New translations en.json (Khmer) 2024-08-01 20:16:57 +02:00
Excalidraw Bot
436fe171ca New translations en.json (Indonesian) 2024-08-01 20:16:56 +02:00
Excalidraw Bot
0f7f5e0f15 New translations en.json (Portuguese, Brazilian) 2024-08-01 20:16:55 +02:00
Excalidraw Bot
3da680ad39 New translations en.json (Galician) 2024-08-01 20:16:54 +02:00
Excalidraw Bot
91d688d60d New translations en.json (Vietnamese) 2024-08-01 20:16:52 +02:00
Excalidraw Bot
eea678f3c2 New translations en.json (Chinese Traditional) 2024-08-01 20:16:51 +02:00
Excalidraw Bot
87ddb85ce7 New translations en.json (German, Switzerland) 2024-08-01 20:16:50 +02:00
Excalidraw Bot
01619e0dba New translations en.json (Persian) 2024-08-01 20:16:49 +02:00
Excalidraw Bot
63289b016b New translations en.json (Chinese Simplified) 2024-08-01 20:16:48 +02:00
Excalidraw Bot
466bfc5808 New translations en.json (Ukrainian) 2024-08-01 20:16:46 +02:00
Excalidraw Bot
8509ad4ea8 New translations en.json (Turkish) 2024-08-01 20:16:45 +02:00
Excalidraw Bot
f607f3ff01 New translations en.json (Swedish) 2024-08-01 20:16:44 +02:00
Excalidraw Bot
ac4942e64a New translations en.json (Slovenian) 2024-08-01 20:16:43 +02:00
Excalidraw Bot
df32b9e73c New translations en.json (Slovak) 2024-08-01 20:16:42 +02:00
Excalidraw Bot
f924b05782 New translations en.json (Russian) 2024-08-01 20:16:40 +02:00
Excalidraw Bot
804e408f0b New translations en.json (Portuguese) 2024-08-01 20:16:39 +02:00
Excalidraw Bot
5cf811f565 New translations en.json (Punjabi) 2024-08-01 20:16:38 +02:00
Excalidraw Bot
b0e307af53 New translations en.json (Dutch) 2024-08-01 20:16:37 +02:00
Excalidraw Bot
2b64bea8b8 New translations en.json (Lithuanian) 2024-08-01 20:16:35 +02:00
Excalidraw Bot
b938a4eeca New translations en.json (Kurdish) 2024-08-01 20:16:34 +02:00
Excalidraw Bot
ce1babba5a New translations en.json (Korean) 2024-08-01 20:16:33 +02:00
Excalidraw Bot
bdedd55a41 New translations en.json (Japanese) 2024-08-01 20:16:32 +02:00
Excalidraw Bot
fefce6a17b New translations en.json (Italian) 2024-08-01 20:16:30 +02:00
Excalidraw Bot
a9f7c54c74 New translations en.json (Hungarian) 2024-08-01 20:16:29 +02:00
Excalidraw Bot
77bb5164ed New translations en.json (Hebrew) 2024-08-01 20:16:28 +02:00
Excalidraw Bot
aa50fcf3e5 New translations en.json (Finnish) 2024-08-01 20:16:26 +02:00
Excalidraw Bot
101616769f New translations en.json (Basque) 2024-08-01 20:16:25 +02:00
Excalidraw Bot
d86fc99a00 New translations en.json (German) 2024-08-01 20:16:24 +02:00
Excalidraw Bot
d2d1155b18 New translations en.json (Danish) 2024-08-01 20:16:23 +02:00
Excalidraw Bot
a96576d1b2 New translations en.json (Czech) 2024-08-01 20:16:22 +02:00
Excalidraw Bot
6d7f05414b New translations en.json (Catalan) 2024-08-01 20:16:21 +02:00
Excalidraw Bot
f23b6e9350 New translations en.json (Bulgarian) 2024-08-01 20:16:19 +02:00
Excalidraw Bot
391db4a941 New translations en.json (Arabic) 2024-08-01 20:16:18 +02:00
Excalidraw Bot
eccb403da1 New translations en.json (Spanish) 2024-08-01 20:16:17 +02:00
Excalidraw Bot
cd567c3d7e New translations en.json (French) 2024-08-01 20:16:16 +02:00
Excalidraw Bot
570d5c3f15 New translations en.json (Romanian) 2024-08-01 20:16:14 +02:00
Excalidraw Bot
f5a6dffa0b New translations en.json (Greek) 2024-08-01 20:16:13 +02:00
Excalidraw Bot
7507dad1de New translations en.json (Polish) 2024-08-01 20:16:12 +02:00
Excalidraw Bot
844b52eff6 New translations en.json (Russian) 2024-08-01 12:06:17 +02:00
Excalidraw Bot
1ce7dedf67 New translations en.json (Slovak) 2024-07-29 08:46:17 +02:00
Excalidraw Bot
47e3460a0b New translations en.json (Greek) 2024-07-27 23:56:49 +02:00
Excalidraw Bot
d8fbc3236e New translations en.json (French) 2024-07-27 22:55:43 +02:00
Excalidraw Bot
fb78fee714 New translations en.json (Greek) 2024-07-27 22:55:42 +02:00
Excalidraw Bot
27b7338fb8 New translations en.json (Greek) 2024-07-27 21:59:59 +02:00
Excalidraw Bot
439319d77b New translations en.json (Ukrainian) 2024-07-27 10:34:54 +02:00
Excalidraw Bot
49baa6e291 New translations en.json (Ukrainian) 2024-07-27 09:31:27 +02:00
Excalidraw Bot
04eac5ed57 New translations en.json (Chinese Traditional) 2024-07-26 13:44:07 +02:00
Excalidraw Bot
3635c88325 New translations en.json (Catalan) 2024-07-26 11:22:23 +02:00
Excalidraw Bot
8b4fdd368a New translations en.json (Romanian) 2024-07-26 08:23:59 +02:00
Excalidraw Bot
70303a9662 New translations en.json (Russian) 2024-07-25 22:12:04 +02:00
Excalidraw Bot
a6b5ee5f91 New translations en.json (German) 2024-07-25 22:12:03 +02:00
Excalidraw Bot
fad2dc5f57 New translations en.json (Slovenian) 2024-07-25 20:32:19 +02:00
Excalidraw Bot
ffb90b6adb New translations en.json (Karakalpak) 2024-07-25 19:06:18 +02:00
Excalidraw Bot
0c63d297bb New translations en.json (Kabyle) 2024-07-25 19:06:17 +02:00
Excalidraw Bot
0066c94a74 New translations en.json (Bengali, India) 2024-07-25 19:06:16 +02:00
Excalidraw Bot
6c995f172c New translations en.json (Occitan) 2024-07-25 19:06:15 +02:00
Excalidraw Bot
0fd575172f New translations en.json (Norwegian Bokmal) 2024-07-25 19:06:14 +02:00
Excalidraw Bot
f84766f497 New translations en.json (Uzbek) 2024-07-25 19:06:13 +02:00
Excalidraw Bot
2795a33335 New translations en.json (Sinhala) 2024-07-25 19:06:12 +02:00
Excalidraw Bot
dc07d39761 New translations en.json (Chinese Traditional, Hong Kong) 2024-07-25 19:06:10 +02:00
Excalidraw Bot
074ece4fa4 New translations en.json (Burmese) 2024-07-25 19:06:09 +02:00
Excalidraw Bot
affa10abe8 New translations en.json (Hindi) 2024-07-25 19:06:08 +02:00
Excalidraw Bot
68712692fb New translations en.json (Azerbaijani) 2024-07-25 19:06:07 +02:00
Excalidraw Bot
4764f661a3 New translations en.json (Latvian) 2024-07-25 19:06:06 +02:00
Excalidraw Bot
e79d4e8ce6 New translations en.json (Kazakh) 2024-07-25 19:06:05 +02:00
Excalidraw Bot
19ecdea035 New translations en.json (Norwegian Nynorsk) 2024-07-25 19:06:04 +02:00
Excalidraw Bot
0519f6de47 New translations en.json (Thai) 2024-07-25 19:06:02 +02:00
Excalidraw Bot
7407ae0f31 New translations en.json (Marathi) 2024-07-25 19:06:01 +02:00
Excalidraw Bot
887de107ef New translations en.json (Bengali) 2024-07-25 19:06:00 +02:00
Excalidraw Bot
1c471944d1 New translations en.json (Tamil) 2024-07-25 19:05:59 +02:00
Excalidraw Bot
69ee56a228 New translations en.json (Khmer) 2024-07-25 19:05:58 +02:00
Excalidraw Bot
5371082087 New translations en.json (Indonesian) 2024-07-25 19:05:57 +02:00
Excalidraw Bot
2709ccdb56 New translations en.json (Portuguese, Brazilian) 2024-07-25 19:05:56 +02:00
Excalidraw Bot
02361a92dc New translations en.json (Galician) 2024-07-25 19:05:54 +02:00
Excalidraw Bot
175c931ddc New translations en.json (Vietnamese) 2024-07-25 19:05:53 +02:00
Excalidraw Bot
350ba84864 New translations en.json (Chinese Traditional) 2024-07-25 19:05:52 +02:00
Excalidraw Bot
9cca06ac84 New translations en.json (Chinese Simplified) 2024-07-25 19:05:51 +02:00
Excalidraw Bot
5eb4a3a448 New translations en.json (Ukrainian) 2024-07-25 19:05:50 +02:00
Excalidraw Bot
e2a9974791 New translations en.json (Turkish) 2024-07-25 19:05:49 +02:00
Excalidraw Bot
40322d37b6 New translations en.json (Swedish) 2024-07-25 19:05:48 +02:00
Excalidraw Bot
e42426655d New translations en.json (Slovenian) 2024-07-25 19:05:47 +02:00
Excalidraw Bot
d6b0990e2d New translations en.json (Slovak) 2024-07-25 19:05:46 +02:00
Excalidraw Bot
54c1909b9e New translations en.json (Russian) 2024-07-25 19:05:45 +02:00
Excalidraw Bot
7c8daea65b New translations en.json (Portuguese) 2024-07-25 19:05:43 +02:00
Excalidraw Bot
9b6ba7ada6 New translations en.json (Punjabi) 2024-07-25 19:05:42 +02:00
Excalidraw Bot
df389c37a4 New translations en.json (Dutch) 2024-07-25 19:05:41 +02:00
Excalidraw Bot
b616db2ab5 New translations en.json (Lithuanian) 2024-07-25 19:05:40 +02:00
Excalidraw Bot
c43d16f435 New translations en.json (Kurdish) 2024-07-25 19:05:39 +02:00
Excalidraw Bot
9d9c65dcbd New translations en.json (Korean) 2024-07-25 19:05:38 +02:00
Excalidraw Bot
3b01f2cfd4 New translations en.json (Japanese) 2024-07-25 19:05:37 +02:00
Excalidraw Bot
e29d4cbbdc New translations en.json (Italian) 2024-07-25 19:05:36 +02:00
Excalidraw Bot
de73b0df95 New translations en.json (Hungarian) 2024-07-25 19:05:34 +02:00
Excalidraw Bot
bdca46fb3f New translations en.json (Hebrew) 2024-07-25 19:05:33 +02:00
Excalidraw Bot
89e7e0507f New translations en.json (Finnish) 2024-07-25 19:05:32 +02:00
Excalidraw Bot
1092769eaf New translations en.json (Basque) 2024-07-25 19:05:31 +02:00
Excalidraw Bot
76c95fadd9 New translations en.json (German) 2024-07-25 19:05:30 +02:00
Excalidraw Bot
40a945c5c6 New translations en.json (Danish) 2024-07-25 19:05:29 +02:00
Excalidraw Bot
fc029f1581 New translations en.json (Czech) 2024-07-25 19:05:28 +02:00
Excalidraw Bot
160e8c6f08 New translations en.json (Catalan) 2024-07-25 19:05:27 +02:00
Excalidraw Bot
52ac6020dc New translations en.json (Bulgarian) 2024-07-25 19:05:26 +02:00
Excalidraw Bot
966404b2fb New translations en.json (Arabic) 2024-07-25 19:05:25 +02:00
Excalidraw Bot
d151c8be9c New translations en.json (Spanish) 2024-07-25 19:05:24 +02:00
Excalidraw Bot
bf2852b46b New translations en.json (French) 2024-07-25 19:05:23 +02:00
Excalidraw Bot
8d9710795b New translations en.json (Romanian) 2024-07-25 19:05:22 +02:00
Excalidraw Bot
a706856b2a New translations en.json (Greek) 2024-07-25 19:05:21 +02:00
Excalidraw Bot
5362326d91 New translations en.json (Polish) 2024-07-25 19:05:20 +02:00
Excalidraw Bot
a450687669 New translations en.json (German, Switzerland) 2024-07-25 19:05:18 +02:00
Excalidraw Bot
ca31245625 New translations en.json (Persian) 2024-07-25 19:05:17 +02:00
Excalidraw Bot
ea14136124 New translations en.json (Greek) 2024-07-22 22:45:54 +02:00
Excalidraw Bot
69f0b70f65 New translations en.json (Greek) 2024-07-22 21:35:33 +02:00
Excalidraw Bot
6998bef4a5 New translations en.json (Polish) 2024-07-21 22:15:48 +02:00
Excalidraw Bot
ffbeee5e5e New translations en.json (Polish) 2024-07-21 21:09:52 +02:00
Excalidraw Bot
55a203a413 New translations en.json (German, Switzerland) 2024-07-12 10:20:12 +02:00
Excalidraw Bot
d6e91d4cdb New translations en.json (Persian) 2024-07-12 10:20:11 +02:00
Excalidraw Bot
b70bc98b4b New translations en.json (Slovak) 2024-07-06 13:31:55 +02:00
Excalidraw Bot
aaf30dc34e New translations en.json (Slovak) 2024-07-06 11:51:10 +02:00
Excalidraw Bot
d44e0071f0 New translations en.json (Bulgarian) 2024-07-05 12:26:22 +02:00
Excalidraw Bot
790f1a65dc New translations en.json (Bulgarian) 2024-07-05 10:24:50 +02:00
Excalidraw Bot
f7e809c756 New translations en.json (Turkish) 2024-06-29 05:14:14 +02:00
Excalidraw Bot
4ee7585115 New translations en.json (Turkish) 2024-06-29 04:12:41 +02:00
Excalidraw Bot
5a7dd4da43 New translations en.json (Hindi) 2024-06-24 08:46:30 +02:00
Excalidraw Bot
176030fe23 New translations en.json (Marathi) 2024-06-24 08:46:28 +02:00
Excalidraw Bot
ecd17e23b8 New translations en.json (Azerbaijani) 2024-06-18 09:10:44 +02:00
Excalidraw Bot
26df1db785 New translations en.json (Italian) 2024-06-18 09:10:43 +02:00
Excalidraw Bot
5666a0d027 New translations en.json (Azerbaijani) 2024-06-18 07:50:05 +02:00
Excalidraw Bot
43956387b6 Auto commit: Calculate translation coverage 2024-06-17 08:17:41 +00:00
Excalidraw Bot
a6c594a4fa New translations en.json (Hindi) 2024-06-17 10:17:25 +02:00
Excalidraw Bot
733c5881b0 New translations en.json (Marathi) 2024-06-17 10:17:24 +02:00
Excalidraw Bot
6017f5b5a3 Auto commit: Calculate translation coverage 2024-06-17 06:34:30 +00:00
Excalidraw Bot
db4c6f8901 New translations en.json (Marathi) 2024-06-17 08:34:15 +02:00
Excalidraw Bot
73d17e6c08 Auto commit: Calculate translation coverage 2024-06-15 20:24:58 +00:00
Excalidraw Bot
8bc520f05f New translations en.json (French) 2024-06-15 22:24:47 +02:00
Excalidraw Bot
8794935ecb Auto commit: Calculate translation coverage 2024-06-15 18:39:29 +00:00
Excalidraw Bot
9ec989fbef New translations en.json (French) 2024-06-15 20:39:15 +02:00
Excalidraw Bot
470fd2e90c Auto commit: Calculate translation coverage 2024-06-15 14:54:20 +00:00
Excalidraw Bot
67d9217c2c New translations en.json (Occitan) 2024-06-15 16:54:06 +02:00
Excalidraw Bot
fc5f238985 Auto commit: Calculate translation coverage 2024-06-14 19:33:56 +00:00
Excalidraw Bot
9442c0c9ed New translations en.json (Portuguese) 2024-06-14 21:33:43 +02:00
Excalidraw Bot
5afbf5a459 Auto commit: Calculate translation coverage 2024-06-13 20:16:52 +00:00
Excalidraw Bot
a8408a5344 New translations en.json (Chinese Traditional) 2024-06-13 22:16:40 +02:00
Excalidraw Bot
ecf5f2a472 Auto commit: Calculate translation coverage 2024-06-13 08:42:20 +00:00
Excalidraw Bot
66a635eea3 New translations en.json (Romanian) 2024-06-13 10:42:07 +02:00
Excalidraw Bot
316c8b85f8 Auto commit: Calculate translation coverage 2024-06-13 07:34:44 +00:00
Excalidraw Bot
7bfb114ca4 New translations en.json (Swedish) 2024-06-13 09:34:32 +02:00
Excalidraw Bot
8eddf43b93 New translations en.json (Slovenian) 2024-06-13 09:34:30 +02:00
Excalidraw Bot
e83a7b7f93 New translations en.json (Russian) 2024-06-13 09:34:29 +02:00
Excalidraw Bot
c370a5bfeb Auto commit: Calculate translation coverage 2024-06-13 05:11:57 +00:00
Excalidraw Bot
0a0edfa77d New translations en.json (Slovenian) 2024-06-13 07:11:44 +02:00
Excalidraw Bot
e49845e097 Auto commit: Calculate translation coverage 2024-06-13 00:39:11 +00:00
Excalidraw Bot
0cef729b9d New translations en.json (Chinese Simplified) 2024-06-13 02:38:57 +02:00
Excalidraw Bot
59f9d60230 Auto commit: Calculate translation coverage 2024-06-12 23:32:44 +00:00
Excalidraw Bot
8c93c24be5 New translations en.json (Spanish) 2024-06-13 01:32:32 +02:00
Excalidraw Bot
c31f1031ba Auto commit: Calculate translation coverage 2024-06-12 21:05:10 +00:00
Excalidraw Bot
033d32f2e9 New translations en.json (Occitan) 2024-06-12 23:04:31 +02:00
Excalidraw Bot
c9723ca98c Auto commit: Calculate translation coverage 2024-06-12 18:50:51 +00:00
Excalidraw Bot
018372206d New translations en.json (Karakalpak) 2024-06-12 20:49:18 +02:00
Excalidraw Bot
f55a873706 New translations en.json (Kabyle) 2024-06-12 20:49:17 +02:00
Excalidraw Bot
666ad7a867 New translations en.json (Bengali, India) 2024-06-12 20:49:16 +02:00
Excalidraw Bot
a032634c31 New translations en.json (Occitan) 2024-06-12 20:49:15 +02:00
Excalidraw Bot
a5c07896c0 New translations en.json (Norwegian Bokmal) 2024-06-12 20:49:13 +02:00
Excalidraw Bot
c169aebe71 New translations en.json (Uzbek) 2024-06-12 20:49:12 +02:00
Excalidraw Bot
24420ca3b0 New translations en.json (Sinhala) 2024-06-12 20:49:11 +02:00
Excalidraw Bot
9ac67ea8df New translations en.json (Chinese Traditional, Hong Kong) 2024-06-12 20:49:10 +02:00
Excalidraw Bot
23d2c69a7c New translations en.json (Burmese) 2024-06-12 20:49:09 +02:00
Excalidraw Bot
06adcc87d2 New translations en.json (Hindi) 2024-06-12 20:49:08 +02:00
Excalidraw Bot
8a0bf98c41 New translations en.json (Azerbaijani) 2024-06-12 20:49:06 +02:00
Excalidraw Bot
e50436e88c New translations en.json (Latvian) 2024-06-12 20:49:05 +02:00
Excalidraw Bot
dc1b99c4fd New translations en.json (Kazakh) 2024-06-12 20:49:04 +02:00
Excalidraw Bot
468c30792a New translations en.json (Norwegian Nynorsk) 2024-06-12 20:49:03 +02:00
Excalidraw Bot
a9d9457f58 New translations en.json (Thai) 2024-06-12 20:49:02 +02:00
Excalidraw Bot
fcc9f611db New translations en.json (Marathi) 2024-06-12 20:49:00 +02:00
Excalidraw Bot
ecdf65e937 New translations en.json (Bengali) 2024-06-12 20:48:59 +02:00
Excalidraw Bot
643c3da142 New translations en.json (Tamil) 2024-06-12 20:48:58 +02:00
Excalidraw Bot
0e7c995af6 New translations en.json (Khmer) 2024-06-12 20:48:57 +02:00
Excalidraw Bot
f1738bda97 New translations en.json (Persian) 2024-06-12 20:48:55 +02:00
Excalidraw Bot
ede64dc114 New translations en.json (Indonesian) 2024-06-12 20:48:54 +02:00
Excalidraw Bot
42938ac5c5 New translations en.json (Portuguese, Brazilian) 2024-06-12 20:48:53 +02:00
Excalidraw Bot
d7125c969f New translations en.json (Galician) 2024-06-12 20:48:52 +02:00
Excalidraw Bot
37535456c3 New translations en.json (Vietnamese) 2024-06-12 20:48:51 +02:00
Excalidraw Bot
afd2efafe4 New translations en.json (Chinese Traditional) 2024-06-12 20:48:50 +02:00
Excalidraw Bot
67e2a97bfb New translations en.json (Chinese Simplified) 2024-06-12 20:48:49 +02:00
Excalidraw Bot
8d4f5174b2 New translations en.json (Ukrainian) 2024-06-12 20:48:47 +02:00
Excalidraw Bot
271466015b New translations en.json (Turkish) 2024-06-12 20:48:46 +02:00
Excalidraw Bot
6b52e63c57 New translations en.json (Swedish) 2024-06-12 20:48:45 +02:00
Excalidraw Bot
dc5f07105f New translations en.json (Slovenian) 2024-06-12 20:48:44 +02:00
Excalidraw Bot
24ea232cdc New translations en.json (Russian) 2024-06-12 20:48:43 +02:00
Excalidraw Bot
49cac6ed74 New translations en.json (Portuguese) 2024-06-12 20:48:41 +02:00
Excalidraw Bot
680b26f069 New translations en.json (Polish) 2024-06-12 20:48:40 +02:00
Excalidraw Bot
cdc2920522 New translations en.json (Punjabi) 2024-06-12 20:48:39 +02:00
Excalidraw Bot
b52ff062f8 New translations en.json (Dutch) 2024-06-12 20:48:38 +02:00
Excalidraw Bot
1aed1d64f5 New translations en.json (Lithuanian) 2024-06-12 20:48:37 +02:00
Excalidraw Bot
971e09ccc2 New translations en.json (Kurdish) 2024-06-12 20:48:35 +02:00
Excalidraw Bot
aed3f16d61 New translations en.json (Korean) 2024-06-12 20:48:34 +02:00
Excalidraw Bot
56a6563bb3 New translations en.json (Japanese) 2024-06-12 20:48:33 +02:00
Excalidraw Bot
18366513e4 New translations en.json (Italian) 2024-06-12 20:48:32 +02:00
Excalidraw Bot
b7c5435de0 New translations en.json (Hungarian) 2024-06-12 20:48:31 +02:00
Excalidraw Bot
778f2fd540 New translations en.json (Hebrew) 2024-06-12 20:48:29 +02:00
Excalidraw Bot
4649bbd853 New translations en.json (Finnish) 2024-06-12 20:48:28 +02:00
Excalidraw Bot
572c1e3bba New translations en.json (Greek) 2024-06-12 20:48:27 +02:00
Excalidraw Bot
772b232f70 New translations en.json (German) 2024-06-12 20:48:26 +02:00
Excalidraw Bot
86ca8872f5 New translations en.json (Danish) 2024-06-12 20:48:24 +02:00
Excalidraw Bot
2e001220c0 New translations en.json (Czech) 2024-06-12 20:48:23 +02:00
Excalidraw Bot
edf1a62d92 New translations en.json (Catalan) 2024-06-12 20:48:22 +02:00
Excalidraw Bot
605d18b9c5 New translations en.json (Bulgarian) 2024-06-12 20:48:21 +02:00
Excalidraw Bot
834b254a4a New translations en.json (Arabic) 2024-06-12 20:48:20 +02:00
Excalidraw Bot
2513479221 New translations en.json (Spanish) 2024-06-12 20:48:19 +02:00
Excalidraw Bot
41bdf1634d New translations en.json (French) 2024-06-12 20:48:18 +02:00
Excalidraw Bot
4ff5f9ece3 New translations en.json (Romanian) 2024-06-12 20:48:17 +02:00
Excalidraw Bot
6d730443c8 New translations en.json (Basque) 2024-06-12 20:48:16 +02:00
Excalidraw Bot
f7d52c580e New translations en.json (Slovak) 2024-06-12 20:48:14 +02:00
Excalidraw Bot
f0bc165b62 Auto commit: Calculate translation coverage 2024-06-07 11:23:03 +00:00
Excalidraw Bot
d6950a5f88 New translations en.json (Basque) 2024-06-07 13:22:49 +02:00
Excalidraw Bot
07c5d52267 Auto commit: Calculate translation coverage 2024-05-31 16:03:00 +00:00
Excalidraw Bot
bac18cb22f New translations en.json (Slovak) 2024-05-31 18:02:47 +02:00
Excalidraw Bot
f7873520c5 Auto commit: Calculate translation coverage 2024-05-22 10:30:48 +00:00
Excalidraw Bot
1acac43403 New translations en.json (Portuguese) 2024-05-22 12:30:36 +02:00
Excalidraw Bot
3b6a48e955 Auto commit: Calculate translation coverage 2024-05-16 13:26:35 +00:00
Excalidraw Bot
ef51ebb020 New translations en.json (Polish) 2024-05-16 15:26:21 +02:00
Excalidraw Bot
05864777df Auto commit: Calculate translation coverage 2024-05-16 07:13:51 +00:00
Excalidraw Bot
c8b2916c4f New translations en.json (Romanian) 2024-05-16 09:13:38 +02:00
Excalidraw Bot
3f05e42578 Auto commit: Calculate translation coverage 2024-05-16 05:31:07 +00:00
Excalidraw Bot
26e046a102 New translations en.json (Swedish) 2024-05-16 07:30:54 +02:00
Excalidraw Bot
3fc76b9927 New translations en.json (Chinese Traditional) 2024-05-16 04:26:34 +02:00
Excalidraw Bot
85c71304ab Auto commit: Calculate translation coverage 2024-05-15 23:33:43 +00:00
Excalidraw Bot
f6ddf56967 New translations en.json (Chinese Simplified) 2024-05-16 01:33:28 +02:00
Excalidraw Bot
9a59a18033 Auto commit: Calculate translation coverage 2024-05-15 18:07:51 +00:00
Excalidraw Bot
f55dc10b1e New translations en.json (German) 2024-05-15 20:07:39 +02:00
Excalidraw Bot
7128c6ed6c Auto commit: Calculate translation coverage 2024-05-15 17:06:58 +00:00
Excalidraw Bot
b80290f1c0 New translations en.json (Slovenian) 2024-05-15 19:06:46 +02:00
Excalidraw Bot
8fb81d2140 Auto commit: Calculate translation coverage 2024-05-15 13:14:17 +00:00
Excalidraw Bot
7a2b187b5f New translations en.json (Karakalpak) 2024-05-15 15:10:41 +02:00
Excalidraw Bot
f1728c7889 New translations en.json (Kabyle) 2024-05-15 15:10:40 +02:00
Excalidraw Bot
97d6c921a1 New translations en.json (Bengali, India) 2024-05-15 15:10:39 +02:00
Excalidraw Bot
e13b82ebe1 New translations en.json (Occitan) 2024-05-15 15:10:37 +02:00
Excalidraw Bot
a72c4959b2 New translations en.json (Norwegian Bokmal) 2024-05-15 15:10:36 +02:00
Excalidraw Bot
739d947ea3 New translations en.json (Uzbek) 2024-05-15 15:10:35 +02:00
Excalidraw Bot
20e8af7298 New translations en.json (Sinhala) 2024-05-15 15:10:34 +02:00
Excalidraw Bot
6064aeea72 New translations en.json (Chinese Traditional, Hong Kong) 2024-05-15 15:10:33 +02:00
Excalidraw Bot
122f8540a0 New translations en.json (Burmese) 2024-05-15 15:10:31 +02:00
Excalidraw Bot
6f0c6ac307 New translations en.json (Hindi) 2024-05-15 15:10:30 +02:00
Excalidraw Bot
bf26f39c8e New translations en.json (Azerbaijani) 2024-05-15 15:10:29 +02:00
Excalidraw Bot
2d71df249f New translations en.json (Latvian) 2024-05-15 15:10:28 +02:00
Excalidraw Bot
2f96c7705e New translations en.json (Kazakh) 2024-05-15 15:10:27 +02:00
Excalidraw Bot
1ea422d4b0 New translations en.json (Norwegian Nynorsk) 2024-05-15 15:10:25 +02:00
Excalidraw Bot
fb519f5210 New translations en.json (Thai) 2024-05-15 15:10:24 +02:00
Excalidraw Bot
5488f8f053 New translations en.json (Marathi) 2024-05-15 15:10:23 +02:00
Excalidraw Bot
3e8297b923 New translations en.json (Bengali) 2024-05-15 15:10:22 +02:00
Excalidraw Bot
324ff7e6f9 New translations en.json (Tamil) 2024-05-15 15:10:21 +02:00
Excalidraw Bot
d5ec2c5036 New translations en.json (Khmer) 2024-05-15 15:10:19 +02:00
Excalidraw Bot
2267d52345 New translations en.json (Persian) 2024-05-15 15:10:18 +02:00
Excalidraw Bot
3adb3c3943 New translations en.json (Indonesian) 2024-05-15 15:10:17 +02:00
Excalidraw Bot
33c7fb9cc3 New translations en.json (Portuguese, Brazilian) 2024-05-15 15:10:16 +02:00
Excalidraw Bot
595d2ca370 New translations en.json (Galician) 2024-05-15 15:10:14 +02:00
Excalidraw Bot
5f588bb474 New translations en.json (Vietnamese) 2024-05-15 15:10:13 +02:00
Excalidraw Bot
96a190538d New translations en.json (Chinese Traditional) 2024-05-15 15:10:12 +02:00
Excalidraw Bot
2237e6be7b New translations en.json (Chinese Simplified) 2024-05-15 15:10:11 +02:00
Excalidraw Bot
6405585cf6 New translations en.json (Ukrainian) 2024-05-15 15:10:10 +02:00
Excalidraw Bot
3116bc4298 New translations en.json (Turkish) 2024-05-15 15:10:09 +02:00
Excalidraw Bot
8b7572d70e New translations en.json (Swedish) 2024-05-15 15:10:08 +02:00
Excalidraw Bot
d6b0cce4c9 New translations en.json (Slovenian) 2024-05-15 15:10:06 +02:00
Excalidraw Bot
f881130398 New translations en.json (Slovak) 2024-05-15 15:10:05 +02:00
Excalidraw Bot
266c4626be New translations en.json (Russian) 2024-05-15 15:10:03 +02:00
Excalidraw Bot
38290a4887 New translations en.json (Portuguese) 2024-05-15 15:10:02 +02:00
Excalidraw Bot
40b10faa7b New translations en.json (Polish) 2024-05-15 15:10:00 +02:00
Excalidraw Bot
a17a122951 New translations en.json (Punjabi) 2024-05-15 15:09:59 +02:00
Excalidraw Bot
0285684c9e New translations en.json (Dutch) 2024-05-15 15:09:58 +02:00
Excalidraw Bot
20c664d9aa New translations en.json (Lithuanian) 2024-05-15 15:09:57 +02:00
Excalidraw Bot
861e9fae97 New translations en.json (Kurdish) 2024-05-15 15:09:56 +02:00
Excalidraw Bot
d86b27e4cd New translations en.json (Korean) 2024-05-15 15:09:55 +02:00
Excalidraw Bot
75f127506e New translations en.json (Japanese) 2024-05-15 15:09:54 +02:00
Excalidraw Bot
4616455ce6 New translations en.json (Italian) 2024-05-15 15:09:53 +02:00
Excalidraw Bot
255e639ea5 New translations en.json (Hungarian) 2024-05-15 15:09:51 +02:00
Excalidraw Bot
1cb1325ee6 New translations en.json (Finnish) 2024-05-15 15:09:50 +02:00
Excalidraw Bot
ebe229c8ed New translations en.json (Basque) 2024-05-15 15:09:49 +02:00
Excalidraw Bot
63f972a889 New translations en.json (Greek) 2024-05-15 15:09:48 +02:00
Excalidraw Bot
e8e03145a3 New translations en.json (German) 2024-05-15 15:09:47 +02:00
Excalidraw Bot
d2db5fb4ed New translations en.json (Danish) 2024-05-15 15:09:46 +02:00
Excalidraw Bot
b9627e639e New translations en.json (Czech) 2024-05-15 15:09:45 +02:00
Excalidraw Bot
9f9678337e New translations en.json (Catalan) 2024-05-15 15:09:44 +02:00
Excalidraw Bot
ba5dc117a4 New translations en.json (Bulgarian) 2024-05-15 15:09:43 +02:00
Excalidraw Bot
a587e9ab58 New translations en.json (Arabic) 2024-05-15 15:09:42 +02:00
Excalidraw Bot
f93f3732f3 New translations en.json (Spanish) 2024-05-15 15:09:40 +02:00
Excalidraw Bot
128bc579ce New translations en.json (French) 2024-05-15 15:09:39 +02:00
Excalidraw Bot
0dd000ce7e New translations en.json (Romanian) 2024-05-15 15:09:38 +02:00
Excalidraw Bot
926d9e6884 New translations en.json (Hebrew) 2024-05-15 15:09:37 +02:00
Excalidraw Bot
04c46eb668 Auto commit: Calculate translation coverage 2024-05-13 06:43:28 +00:00
Excalidraw Bot
7e09d00d62 New translations en.json (Swedish) 2024-05-13 08:43:12 +02:00
Excalidraw Bot
7ef2a08dff Auto commit: Calculate translation coverage 2024-05-10 14:59:37 +00:00
Excalidraw Bot
ca6d0bb98a New translations en.json (Spanish) 2024-05-10 16:59:25 +02:00
Excalidraw Bot
b70393f947 Auto commit: Calculate translation coverage 2024-05-10 10:46:37 +00:00
Excalidraw Bot
df78472681 New translations en.json (French) 2024-05-10 12:46:26 +02:00
Excalidraw Bot
22d201d2c3 New translations en.json (Romanian) 2024-05-10 12:46:25 +02:00
Excalidraw Bot
3263596166 Auto commit: Calculate translation coverage 2024-05-10 09:07:24 +00:00
Excalidraw Bot
43302acd47 New translations en.json (French) 2024-05-10 11:07:14 +02:00
Excalidraw Bot
c92fb897b0 Auto commit: Calculate translation coverage 2024-05-09 21:37:35 +00:00
Excalidraw Bot
969cdb6fa5 New translations en.json (Portuguese) 2024-05-09 23:37:22 +02:00
Excalidraw Bot
b7c273dad3 New translations en.json (Italian) 2024-05-09 19:35:41 +02:00
Excalidraw Bot
6c392443fc New translations en.json (Chinese Traditional) 2024-05-09 16:06:43 +02:00
Excalidraw Bot
71800f2bdf Auto commit: Calculate translation coverage 2024-05-09 09:15:50 +00:00
Excalidraw Bot
81718fb708 New translations en.json (Chinese Simplified) 2024-05-09 11:15:37 +02:00
Excalidraw Bot
6420601d00 New translations en.json (Russian) 2024-05-09 11:15:36 +02:00
Excalidraw Bot
1ba7399adc New translations en.json (Polish) 2024-05-09 11:15:35 +02:00
Excalidraw Bot
2eacd8be18 New translations en.json (German) 2024-05-09 11:15:34 +02:00
Excalidraw Bot
f9055ae50e Auto commit: Calculate translation coverage 2024-05-09 07:35:38 +00:00
Excalidraw Bot
26718821c0 New translations en.json (Polish) 2024-05-09 09:35:22 +02:00
Excalidraw Bot
0339872a2c Auto commit: Calculate translation coverage 2024-05-09 06:31:00 +00:00
Excalidraw Bot
86758895fa New translations en.json (Slovenian) 2024-05-09 08:30:42 +02:00
Excalidraw Bot
6390aef437 Auto commit: Calculate translation coverage 2024-05-08 20:51:00 +00:00
Excalidraw Bot
f782ee3f0e New translations en.json (Karakalpak) 2024-05-08 22:46:17 +02:00
Excalidraw Bot
971b46bb0d New translations en.json (Kabyle) 2024-05-08 22:46:16 +02:00
Excalidraw Bot
cdda24b859 New translations en.json (Bengali, India) 2024-05-08 22:46:15 +02:00
Excalidraw Bot
bdcbdad7ed New translations en.json (Occitan) 2024-05-08 22:46:14 +02:00
Excalidraw Bot
ae955d24fa New translations en.json (Norwegian Bokmal) 2024-05-08 22:46:13 +02:00
Excalidraw Bot
1787fd8612 New translations en.json (Uzbek) 2024-05-08 22:46:12 +02:00
Excalidraw Bot
ea8e86e4a9 New translations en.json (Sinhala) 2024-05-08 22:46:11 +02:00
Excalidraw Bot
2965f7ba26 New translations en.json (Chinese Traditional, Hong Kong) 2024-05-08 22:46:10 +02:00
Excalidraw Bot
f5e156d0d3 New translations en.json (Burmese) 2024-05-08 22:46:09 +02:00
Excalidraw Bot
e14bb1fa3d New translations en.json (Hindi) 2024-05-08 22:46:07 +02:00
Excalidraw Bot
3d8b49f913 New translations en.json (Azerbaijani) 2024-05-08 22:46:06 +02:00
Excalidraw Bot
3e58bebc04 New translations en.json (Latvian) 2024-05-08 22:46:05 +02:00
Excalidraw Bot
69b7e9c80d New translations en.json (Kazakh) 2024-05-08 22:46:04 +02:00
Excalidraw Bot
812d27cc7f New translations en.json (Norwegian Nynorsk) 2024-05-08 22:46:03 +02:00
Excalidraw Bot
7d383e8c00 New translations en.json (Thai) 2024-05-08 22:46:02 +02:00
Excalidraw Bot
036c8c0f59 New translations en.json (Marathi) 2024-05-08 22:46:01 +02:00
Excalidraw Bot
c08d7a771c New translations en.json (Bengali) 2024-05-08 22:46:00 +02:00
Excalidraw Bot
3bcced5d69 New translations en.json (Tamil) 2024-05-08 22:45:59 +02:00
Excalidraw Bot
9d5c90b5af New translations en.json (Khmer) 2024-05-08 22:45:58 +02:00
Excalidraw Bot
404f9328b7 New translations en.json (Persian) 2024-05-08 22:45:57 +02:00
Excalidraw Bot
35b16fcd6d New translations en.json (Indonesian) 2024-05-08 22:45:56 +02:00
Excalidraw Bot
0d83490292 New translations en.json (Portuguese, Brazilian) 2024-05-08 22:45:55 +02:00
Excalidraw Bot
3c1c3bbdd7 New translations en.json (Galician) 2024-05-08 22:45:54 +02:00
Excalidraw Bot
cc6e945a04 New translations en.json (Vietnamese) 2024-05-08 22:45:53 +02:00
Excalidraw Bot
db6ddf6b7c New translations en.json (Chinese Traditional) 2024-05-08 22:45:52 +02:00
Excalidraw Bot
faca670156 New translations en.json (Chinese Simplified) 2024-05-08 22:45:51 +02:00
Excalidraw Bot
07f39be1ff New translations en.json (Ukrainian) 2024-05-08 22:45:50 +02:00
Excalidraw Bot
5e18fe4c7f New translations en.json (Turkish) 2024-05-08 22:45:49 +02:00
Excalidraw Bot
a8312ec874 New translations en.json (Swedish) 2024-05-08 22:45:48 +02:00
Excalidraw Bot
cef937c880 New translations en.json (Slovenian) 2024-05-08 22:45:46 +02:00
Excalidraw Bot
a8e903a3e9 New translations en.json (Slovak) 2024-05-08 22:45:45 +02:00
Excalidraw Bot
c57c830316 New translations en.json (Russian) 2024-05-08 22:45:44 +02:00
Excalidraw Bot
5b56bfe960 New translations en.json (Portuguese) 2024-05-08 22:45:43 +02:00
Excalidraw Bot
7e3eff3b23 New translations en.json (Polish) 2024-05-08 22:45:42 +02:00
Excalidraw Bot
43f42ee9f0 New translations en.json (Punjabi) 2024-05-08 22:45:41 +02:00
Excalidraw Bot
2674fae183 New translations en.json (Dutch) 2024-05-08 22:45:40 +02:00
Excalidraw Bot
17606e6180 New translations en.json (Lithuanian) 2024-05-08 22:45:39 +02:00
Excalidraw Bot
e5592d566e New translations en.json (Kurdish) 2024-05-08 22:45:38 +02:00
Excalidraw Bot
61768c9d81 New translations en.json (Korean) 2024-05-08 22:45:37 +02:00
Excalidraw Bot
65f4537bd0 New translations en.json (Japanese) 2024-05-08 22:45:36 +02:00
Excalidraw Bot
acd4eda04b New translations en.json (Italian) 2024-05-08 22:45:35 +02:00
Excalidraw Bot
b51369ad97 New translations en.json (Hungarian) 2024-05-08 22:45:34 +02:00
Excalidraw Bot
5b9ec81880 New translations en.json (Finnish) 2024-05-08 22:45:33 +02:00
Excalidraw Bot
91b71c8c45 New translations en.json (Basque) 2024-05-08 22:45:32 +02:00
Excalidraw Bot
cab7c52280 New translations en.json (Greek) 2024-05-08 22:45:31 +02:00
Excalidraw Bot
b1f1ae9570 New translations en.json (German) 2024-05-08 22:45:30 +02:00
Excalidraw Bot
79dec7adc7 New translations en.json (Danish) 2024-05-08 22:45:29 +02:00
Excalidraw Bot
6662cc6828 New translations en.json (Czech) 2024-05-08 22:45:28 +02:00
Excalidraw Bot
8511e6d42c New translations en.json (Catalan) 2024-05-08 22:45:27 +02:00
Excalidraw Bot
aa0c056b2f New translations en.json (Bulgarian) 2024-05-08 22:45:26 +02:00
Excalidraw Bot
bacfe9d327 New translations en.json (Arabic) 2024-05-08 22:45:25 +02:00
Excalidraw Bot
193b40ff12 New translations en.json (Spanish) 2024-05-08 22:45:24 +02:00
Excalidraw Bot
020b88c77a New translations en.json (French) 2024-05-08 22:45:23 +02:00
Excalidraw Bot
77726e6606 New translations en.json (Romanian) 2024-05-08 22:45:22 +02:00
Excalidraw Bot
1f055c0bda New translations en.json (Hebrew) 2024-05-08 22:45:21 +02:00
Excalidraw Bot
0189a75ff3 Auto commit: Calculate translation coverage 2024-05-08 19:33:58 +00:00
Excalidraw Bot
60d55753e9 New translations en.json (Portuguese) 2024-05-08 21:33:46 +02:00
Excalidraw Bot
c962575aec Auto commit: Calculate translation coverage 2024-05-08 10:49:45 +00:00
Excalidraw Bot
50da3e0873 New translations en.json (Romanian) 2024-05-08 12:49:33 +02:00
Excalidraw Bot
8b7a5511b7 Auto commit: Calculate translation coverage 2024-05-08 05:01:04 +00:00
Excalidraw Bot
572185898c New translations en.json (Tamil) 2024-05-08 07:00:51 +02:00
Excalidraw Bot
f6ea289a0e New translations en.json (Chinese Traditional) 2024-05-08 05:50:02 +02:00
Excalidraw Bot
dc9b065689 Auto commit: Calculate translation coverage 2024-05-07 19:33:43 +00:00
Excalidraw Bot
a448dc81c4 New translations en.json (German) 2024-05-07 21:33:32 +02:00
Excalidraw Bot
d82dae0776 Auto commit: Calculate translation coverage 2024-05-07 18:35:50 +00:00
Excalidraw Bot
0447ac624d New translations en.json (Tamil) 2024-05-07 20:35:37 +02:00
Excalidraw Bot
b9c040d9ac New translations en.json (Chinese Simplified) 2024-05-07 20:35:36 +02:00
Excalidraw Bot
fc926448ac New translations en.json (Spanish) 2024-05-07 19:40:01 +02:00
Excalidraw Bot
70d85530c7 Auto commit: Calculate translation coverage 2024-05-07 13:49:47 +00:00
Excalidraw Bot
96b515e2fe New translations en.json (Slovenian) 2024-05-07 15:49:36 +02:00
Excalidraw Bot
bced18876d New translations en.json (Russian) 2024-05-07 15:49:35 +02:00
Excalidraw Bot
1be9d67d8a Auto commit: Calculate translation coverage 2024-05-07 12:32:31 +00:00
Excalidraw Bot
bd21a2b57f New translations en.json (Karakalpak) 2024-05-07 14:30:33 +02:00
Excalidraw Bot
8cd33a127c New translations en.json (Kabyle) 2024-05-07 14:30:32 +02:00
Excalidraw Bot
19f15becfe New translations en.json (Bengali, India) 2024-05-07 14:30:30 +02:00
Excalidraw Bot
4f0e0407f1 New translations en.json (Occitan) 2024-05-07 14:30:29 +02:00
Excalidraw Bot
dc1f76988a New translations en.json (Norwegian Bokmal) 2024-05-07 14:30:28 +02:00
Excalidraw Bot
8289f3e0ed New translations en.json (Uzbek) 2024-05-07 14:30:27 +02:00
Excalidraw Bot
a5f517c0d4 New translations en.json (Sinhala) 2024-05-07 14:30:26 +02:00
Excalidraw Bot
3c2cd278f7 New translations en.json (Chinese Traditional, Hong Kong) 2024-05-07 14:30:24 +02:00
Excalidraw Bot
c77e248aee New translations en.json (Burmese) 2024-05-07 14:30:23 +02:00
Excalidraw Bot
2948341728 New translations en.json (Hindi) 2024-05-07 14:30:22 +02:00
Excalidraw Bot
9eaf570ae7 New translations en.json (Azerbaijani) 2024-05-07 14:30:20 +02:00
Excalidraw Bot
5d3637d157 New translations en.json (Latvian) 2024-05-07 14:30:19 +02:00
Excalidraw Bot
955af18a01 New translations en.json (Kazakh) 2024-05-07 14:30:18 +02:00
Excalidraw Bot
77d8fd5493 New translations en.json (Norwegian Nynorsk) 2024-05-07 14:30:17 +02:00
Excalidraw Bot
40e6f4a7f2 New translations en.json (Thai) 2024-05-07 14:30:16 +02:00
Excalidraw Bot
640d838e28 New translations en.json (Marathi) 2024-05-07 14:30:15 +02:00
Excalidraw Bot
aa02c7610e New translations en.json (Bengali) 2024-05-07 14:30:13 +02:00
Excalidraw Bot
d1179f5ada New translations en.json (Tamil) 2024-05-07 14:30:12 +02:00
Excalidraw Bot
6df2d19fbf New translations en.json (Khmer) 2024-05-07 14:30:11 +02:00
Excalidraw Bot
52ba265c71 New translations en.json (Persian) 2024-05-07 14:30:10 +02:00
Excalidraw Bot
00d9e244c2 New translations en.json (Indonesian) 2024-05-07 14:30:08 +02:00
Excalidraw Bot
ee0c58f797 New translations en.json (Portuguese, Brazilian) 2024-05-07 14:30:07 +02:00
Excalidraw Bot
2fd1d1c371 New translations en.json (Galician) 2024-05-07 14:30:06 +02:00
Excalidraw Bot
7a51bc7f5d New translations en.json (Vietnamese) 2024-05-07 14:30:05 +02:00
Excalidraw Bot
28b61d73c8 New translations en.json (Chinese Traditional) 2024-05-07 14:30:03 +02:00
Excalidraw Bot
f8af81fb65 New translations en.json (Chinese Simplified) 2024-05-07 14:30:02 +02:00
Excalidraw Bot
d474fdd404 New translations en.json (Ukrainian) 2024-05-07 14:30:00 +02:00
Excalidraw Bot
1afd2d4030 New translations en.json (Turkish) 2024-05-07 14:29:59 +02:00
Excalidraw Bot
94bc8dd018 New translations en.json (Swedish) 2024-05-07 14:29:58 +02:00
Excalidraw Bot
f3e85108a8 New translations en.json (Slovenian) 2024-05-07 14:29:57 +02:00
Excalidraw Bot
149a7fc32b New translations en.json (Slovak) 2024-05-07 14:29:56 +02:00
Excalidraw Bot
7094c4c9b6 New translations en.json (Russian) 2024-05-07 14:29:55 +02:00
Excalidraw Bot
e7fb9494cb New translations en.json (Portuguese) 2024-05-07 14:29:53 +02:00
Excalidraw Bot
b335a96722 New translations en.json (Polish) 2024-05-07 14:29:52 +02:00
Excalidraw Bot
18f539c709 New translations en.json (Punjabi) 2024-05-07 14:29:51 +02:00
Excalidraw Bot
2bd173501c New translations en.json (Dutch) 2024-05-07 14:29:50 +02:00
Excalidraw Bot
27c47513e8 New translations en.json (Lithuanian) 2024-05-07 14:29:49 +02:00
Excalidraw Bot
bafd3d669b New translations en.json (Kurdish) 2024-05-07 14:29:48 +02:00
Excalidraw Bot
d9a3ec2680 New translations en.json (Korean) 2024-05-07 14:29:47 +02:00
Excalidraw Bot
b28f7b9b81 New translations en.json (Japanese) 2024-05-07 14:29:45 +02:00
Excalidraw Bot
f35b909ba9 New translations en.json (Italian) 2024-05-07 14:29:44 +02:00
Excalidraw Bot
dbe71af81a New translations en.json (Hungarian) 2024-05-07 14:29:43 +02:00
Excalidraw Bot
8a94fd0baf New translations en.json (Finnish) 2024-05-07 14:29:42 +02:00
Excalidraw Bot
b9a4bcb4fc New translations en.json (Basque) 2024-05-07 14:29:41 +02:00
Excalidraw Bot
11f6dd674c New translations en.json (Greek) 2024-05-07 14:29:40 +02:00
Excalidraw Bot
edfdf8ad21 New translations en.json (German) 2024-05-07 14:29:39 +02:00
Excalidraw Bot
40a4928f6e New translations en.json (Danish) 2024-05-07 14:29:38 +02:00
Excalidraw Bot
b35257ab5b New translations en.json (Czech) 2024-05-07 14:29:36 +02:00
Excalidraw Bot
4b9f2a722d New translations en.json (Catalan) 2024-05-07 14:29:35 +02:00
Excalidraw Bot
7c88a7c48b New translations en.json (Bulgarian) 2024-05-07 14:29:34 +02:00
Excalidraw Bot
a8adca5d98 New translations en.json (Arabic) 2024-05-07 14:29:33 +02:00
Excalidraw Bot
ee88a62da8 New translations en.json (Spanish) 2024-05-07 14:29:32 +02:00
Excalidraw Bot
acb23a5a7a New translations en.json (French) 2024-05-07 14:29:30 +02:00
Excalidraw Bot
1b63aa136b New translations en.json (Romanian) 2024-05-07 14:29:29 +02:00
Excalidraw Bot
cea3bb9764 New translations en.json (Hebrew) 2024-05-07 14:29:28 +02:00
Excalidraw Bot
1840949a81 Auto commit: Calculate translation coverage 2024-04-23 20:54:02 +00:00
Excalidraw Bot
b6678560ec New translations en.json (Hebrew) 2024-04-23 22:53:48 +02:00
Excalidraw Bot
01c144de36 Auto commit: Calculate translation coverage 2024-04-23 19:31:24 +00:00
Excalidraw Bot
5f387aeed1 New translations en.json (Hebrew) 2024-04-23 21:31:12 +02:00
Excalidraw Bot
1faad458f6 Auto commit: Calculate translation coverage 2024-04-22 15:39:31 +00:00
Excalidraw Bot
3357340772 New translations en.json (Bengali, India) 2024-04-22 17:39:12 +02:00
Excalidraw Bot
053606e460 New translations en.json (Bengali) 2024-04-22 17:39:11 +02:00
Excalidraw Bot
280bbc3e58 Auto commit: Calculate translation coverage 2024-04-22 14:43:54 +00:00
Excalidraw Bot
6adf3eb827 New translations en.json (Bengali) 2024-04-22 16:43:40 +02:00
Excalidraw Bot
2259ea6e80 Auto commit: Calculate translation coverage 2024-04-17 15:16:08 +00:00
Excalidraw Bot
51eec9d02c New translations en.json (Finnish) 2024-04-17 17:15:54 +02:00
Excalidraw Bot
6dcfe61f2e Auto commit: Calculate translation coverage 2024-04-16 11:45:30 +00:00
Excalidraw Bot
066bcddc82 New translations en.json (Portuguese) 2024-04-16 13:45:15 +02:00
Excalidraw Bot
67866e70cf Auto commit: Calculate translation coverage 2024-04-15 13:28:35 +00:00
Excalidraw Bot
3509c2e812 New translations en.json (Arabic) 2024-04-15 15:28:23 +02:00
Excalidraw Bot
4f0ea27632 Auto commit: Calculate translation coverage 2024-04-15 12:14:28 +00:00
Excalidraw Bot
5eb7b5a63e New translations en.json (Arabic) 2024-04-15 14:14:10 +02:00
Excalidraw Bot
865576946c Auto commit: Calculate translation coverage 2024-04-15 10:53:28 +00:00
Excalidraw Bot
5a376e0015 New translations en.json (Romanian) 2024-04-15 12:53:17 +02:00
Excalidraw Bot
d34d43d730 Auto commit: Calculate translation coverage 2024-04-15 05:38:15 +00:00
Excalidraw Bot
f7b4d9d424 New translations en.json (Swedish) 2024-04-15 07:38:04 +02:00
Excalidraw Bot
10b7e96c00 Auto commit: Calculate translation coverage 2024-04-13 21:41:12 +00:00
Excalidraw Bot
a5c09041e9 New translations en.json (Chinese Simplified) 2024-04-13 23:40:59 +02:00
Excalidraw Bot
c46e268ad0 Auto commit: Calculate translation coverage 2024-04-13 20:27:01 +00:00
Excalidraw Bot
5b6ce786a1 New translations en.json (Chinese Traditional) 2024-04-13 22:26:47 +02:00
Excalidraw Bot
70a2ccb51a New translations en.json (German) 2024-04-13 22:26:46 +02:00
Excalidraw Bot
a89a072cb4 Auto commit: Calculate translation coverage 2024-04-13 17:59:17 +00:00
Excalidraw Bot
65c040c075 New translations en.json (Karakalpak) 2024-04-13 19:55:18 +02:00
Excalidraw Bot
39b9e1e7a0 New translations en.json (Kabyle) 2024-04-13 19:55:17 +02:00
Excalidraw Bot
cb3050294b New translations en.json (Occitan) 2024-04-13 19:55:16 +02:00
Excalidraw Bot
455eeb63b4 New translations en.json (Norwegian Bokmal) 2024-04-13 19:55:15 +02:00
Excalidraw Bot
be4eb1e37e New translations en.json (Uzbek) 2024-04-13 19:55:14 +02:00
Excalidraw Bot
f3ff017e6f New translations en.json (Sinhala) 2024-04-13 19:55:13 +02:00
Excalidraw Bot
56c18f44c7 New translations en.json (Chinese Traditional, Hong Kong) 2024-04-13 19:55:12 +02:00
Excalidraw Bot
da2695ac35 New translations en.json (Burmese) 2024-04-13 19:55:11 +02:00
Excalidraw Bot
5614f1c62f New translations en.json (Azerbaijani) 2024-04-13 19:55:09 +02:00
Excalidraw Bot
b7d9e49039 New translations en.json (Latvian) 2024-04-13 19:55:08 +02:00
Excalidraw Bot
4da5b9e7b6 New translations en.json (Kazakh) 2024-04-13 19:55:07 +02:00
Excalidraw Bot
81958d4a3d New translations en.json (Norwegian Nynorsk) 2024-04-13 19:55:06 +02:00
Excalidraw Bot
12a7eb4885 New translations en.json (Thai) 2024-04-13 19:55:05 +02:00
Excalidraw Bot
dffc310969 New translations en.json (Marathi) 2024-04-13 19:55:05 +02:00
Excalidraw Bot
80ad916f4f New translations en.json (Bengali) 2024-04-13 19:55:04 +02:00
Excalidraw Bot
d216420f30 New translations en.json (Tamil) 2024-04-13 19:55:03 +02:00
Excalidraw Bot
4cf68fa98f New translations en.json (Khmer) 2024-04-13 19:55:02 +02:00
Excalidraw Bot
2996eb0bb5 New translations en.json (Persian) 2024-04-13 19:55:01 +02:00
Excalidraw Bot
422e6ad51e New translations en.json (Indonesian) 2024-04-13 19:55:00 +02:00
Excalidraw Bot
922675bf53 New translations en.json (Portuguese, Brazilian) 2024-04-13 19:54:59 +02:00
Excalidraw Bot
d92f555e93 New translations en.json (Galician) 2024-04-13 19:54:58 +02:00
Excalidraw Bot
48433bc9eb New translations en.json (Vietnamese) 2024-04-13 19:54:57 +02:00
Excalidraw Bot
db3f73c643 New translations en.json (Chinese Traditional) 2024-04-13 19:54:57 +02:00
Excalidraw Bot
ad0f8155a7 New translations en.json (Ukrainian) 2024-04-13 19:54:56 +02:00
Excalidraw Bot
060eee3afd New translations en.json (Turkish) 2024-04-13 19:54:55 +02:00
Excalidraw Bot
407ef4699d New translations en.json (Slovenian) 2024-04-13 19:54:54 +02:00
Excalidraw Bot
1ffb358d59 New translations en.json (Russian) 2024-04-13 19:54:53 +02:00
Excalidraw Bot
d9c4e12642 New translations en.json (Portuguese) 2024-04-13 19:54:52 +02:00
Excalidraw Bot
310f561488 New translations en.json (Polish) 2024-04-13 19:54:51 +02:00
Excalidraw Bot
dcd3636c96 New translations en.json (Punjabi) 2024-04-13 19:54:50 +02:00
Excalidraw Bot
a5442f8b7a New translations en.json (Dutch) 2024-04-13 19:54:50 +02:00
Excalidraw Bot
1dc32d9e0a New translations en.json (Lithuanian) 2024-04-13 19:54:49 +02:00
Excalidraw Bot
a767150e87 New translations en.json (Kurdish) 2024-04-13 19:54:48 +02:00
Excalidraw Bot
9691492f38 New translations en.json (Korean) 2024-04-13 19:54:47 +02:00
Excalidraw Bot
2f52f28631 New translations en.json (Japanese) 2024-04-13 19:54:46 +02:00
Excalidraw Bot
e0bef262a7 New translations en.json (Hungarian) 2024-04-13 19:54:45 +02:00
Excalidraw Bot
4cffdf216d New translations en.json (Hebrew) 2024-04-13 19:54:44 +02:00
Excalidraw Bot
2628d6807c New translations en.json (Finnish) 2024-04-13 19:54:43 +02:00
Excalidraw Bot
3e1012b080 New translations en.json (Basque) 2024-04-13 19:54:43 +02:00
Excalidraw Bot
6e575f2f8b New translations en.json (Greek) 2024-04-13 19:54:42 +02:00
Excalidraw Bot
ec7fa95672 New translations en.json (German) 2024-04-13 19:54:41 +02:00
Excalidraw Bot
753f492c86 New translations en.json (Danish) 2024-04-13 19:54:40 +02:00
Excalidraw Bot
8b04af03a1 New translations en.json (Czech) 2024-04-13 19:54:39 +02:00
Excalidraw Bot
8830f1138d New translations en.json (Catalan) 2024-04-13 19:54:38 +02:00
Excalidraw Bot
4567a16d65 New translations en.json (Bulgarian) 2024-04-13 19:54:37 +02:00
Excalidraw Bot
19eaf8240a New translations en.json (Arabic) 2024-04-13 19:54:36 +02:00
Excalidraw Bot
4a519f47b5 New translations en.json (Spanish) 2024-04-13 19:54:35 +02:00
Excalidraw Bot
edebbffe33 New translations en.json (French) 2024-04-13 19:54:34 +02:00
Excalidraw Bot
156285417b New translations en.json (Romanian) 2024-04-13 19:54:33 +02:00
Excalidraw Bot
cefc312e85 New translations en.json (Hindi) 2024-04-13 19:54:32 +02:00
Excalidraw Bot
c63d5da9e1 New translations en.json (Chinese Simplified) 2024-04-13 19:54:31 +02:00
Excalidraw Bot
a934d975e7 New translations en.json (Swedish) 2024-04-13 19:54:30 +02:00
Excalidraw Bot
f391e7b11a New translations en.json (Slovak) 2024-04-13 19:54:29 +02:00
Excalidraw Bot
7f93f19314 New translations en.json (Italian) 2024-04-13 19:54:29 +02:00
dwelle
cb1454f8db Merge branch 'master' into l10n_master 2024-04-13 18:52:39 +02:00
David Luzar
da2e507298 fix: allow same origin for all necessary domains (#7889) 2024-04-13 18:51:30 +02:00
Excalidraw Bot
df4660c0c1 Auto commit: Calculate translation coverage 2024-04-13 12:29:26 +00:00
Excalidraw Bot
8751b38988 New translations en.json (Slovak) 2024-04-13 14:29:12 +02:00
David Luzar
f59b4f6af4 fix: always make sure we render bound text above containers (#7880) 2024-04-12 21:50:02 +02:00
David Luzar
afcde542f9 fix: parse embeddable srcdoc urls strictly (#7884) 2024-04-12 20:51:17 +02:00
Ryan Di
4689a6b300 fix: hit test for closed sharp curves (#7881) 2024-04-12 12:58:51 +02:00
David Luzar
0ae9b383d6 fix: Gist embed allowing unsafe html (#7883) 2024-04-12 12:57:43 +02:00
David Luzar
f597bd3e01 fix: command palette tweaks and fixes (#7876) 2024-04-11 11:39:19 +02:00
Ryan Di
4987cc53d0 fix: include borders when testing insides of a shape (#7865) 2024-04-09 16:07:36 +02:00
Rinku Chaudhari
d917db438e fix: external link not opening (#7859) 2024-04-09 16:06:49 +02:00
Excalidraw Bot
287836fc6b Auto commit: Calculate translation coverage 2024-04-09 08:38:48 +00:00
Excalidraw Bot
4635477f37 New translations en.json (Swedish) 2024-04-09 10:38:34 +02:00
Excalidraw Bot
89f77ea24a Auto commit: Calculate translation coverage 2024-04-09 04:32:41 +00:00
Excalidraw Bot
3dc38ab06e New translations en.json (Chinese Simplified) 2024-04-09 06:32:30 +02:00
Aakansha Doshi
a33a400f01 fix: add safe check for arrow points length in tranformToExcalidrawElements (#7863)
* fix: add safe check for arrow points length in tranformToExcalidrawElements

* add spec

* throw error only for dev mode

* fix lint
2024-04-09 09:56:21 +05:30
Excalidraw Bot
66a2dcdedc Auto commit: Calculate translation coverage 2024-04-09 03:32:30 +00:00
Excalidraw Bot
fddea948f0 New translations en.json (Marathi) 2024-04-09 05:32:14 +02:00
Excalidraw Bot
229ab44918 New translations en.json (Hindi) 2024-04-09 05:32:13 +02:00
Excalidraw Bot
a6a958de55 New translations en.json (Chinese Traditional) 2024-04-08 21:16:08 +02:00
Excalidraw Bot
c3969dcf12 Auto commit: Calculate translation coverage 2024-04-08 18:06:08 +00:00
Excalidraw Bot
d906fe2531 New translations en.json (German) 2024-04-08 20:05:52 +02:00
Excalidraw Bot
3eaa573951 Auto commit: Calculate translation coverage 2024-04-08 16:49:55 +00:00
Excalidraw Bot
50f98d193d New translations en.json (Slovenian) 2024-04-08 18:49:21 +02:00
Excalidraw Bot
7104d7bf17 New translations en.json (Romanian) 2024-04-08 18:49:20 +02:00
David Luzar
8a162a4cb4 fix: import (#7869) 2024-04-08 16:59:03 +02:00
Excalidraw Bot
9403ef8656 Auto commit: Calculate translation coverage 2024-04-08 14:55:38 +00:00
David Luzar
c6a045d092 fix: theme toggle shortcut event.code (#7868) 2024-04-08 16:55:33 +02:00
Excalidraw Bot
092263b6b1 New translations en.json (Karakalpak) 2024-04-08 16:51:11 +02:00
Excalidraw Bot
6adb44ead4 New translations en.json (Kabyle) 2024-04-08 16:51:10 +02:00
Excalidraw Bot
b71cbe8352 New translations en.json (Occitan) 2024-04-08 16:51:09 +02:00
Excalidraw Bot
576cb578b0 New translations en.json (Norwegian Bokmal) 2024-04-08 16:51:08 +02:00
Excalidraw Bot
7198a613dd New translations en.json (Uzbek) 2024-04-08 16:51:07 +02:00
Excalidraw Bot
24d4eafbd0 New translations en.json (Sinhala) 2024-04-08 16:51:06 +02:00
Excalidraw Bot
8b52f043d5 New translations en.json (Chinese Traditional, Hong Kong) 2024-04-08 16:51:05 +02:00
Excalidraw Bot
6e2c5d7e82 New translations en.json (Burmese) 2024-04-08 16:51:04 +02:00
Excalidraw Bot
ae82cf1704 New translations en.json (Azerbaijani) 2024-04-08 16:51:03 +02:00
Excalidraw Bot
1e0f54b4df New translations en.json (Latvian) 2024-04-08 16:51:02 +02:00
Excalidraw Bot
4624dd5041 New translations en.json (Kazakh) 2024-04-08 16:51:01 +02:00
Excalidraw Bot
1e54ae0825 New translations en.json (Norwegian Nynorsk) 2024-04-08 16:50:59 +02:00
Excalidraw Bot
6bfc4b7212 New translations en.json (Thai) 2024-04-08 16:50:58 +02:00
Excalidraw Bot
81634d45e4 New translations en.json (Marathi) 2024-04-08 16:50:57 +02:00
Excalidraw Bot
cd1c9391f1 New translations en.json (Bengali) 2024-04-08 16:50:56 +02:00
Excalidraw Bot
726ccccb1c New translations en.json (Tamil) 2024-04-08 16:50:55 +02:00
Excalidraw Bot
74942af896 New translations en.json (Khmer) 2024-04-08 16:50:54 +02:00
Excalidraw Bot
89e52da2fe New translations en.json (Persian) 2024-04-08 16:50:53 +02:00
Excalidraw Bot
fcf153e420 New translations en.json (Indonesian) 2024-04-08 16:50:52 +02:00
Excalidraw Bot
c22f0896b7 New translations en.json (Portuguese, Brazilian) 2024-04-08 16:50:51 +02:00
Excalidraw Bot
b3bf5a215f New translations en.json (Galician) 2024-04-08 16:50:51 +02:00
Excalidraw Bot
5a0066ab52 New translations en.json (Vietnamese) 2024-04-08 16:50:49 +02:00
Excalidraw Bot
b85c365aa9 New translations en.json (Chinese Traditional) 2024-04-08 16:50:49 +02:00
Excalidraw Bot
7b1eaf3f48 New translations en.json (Ukrainian) 2024-04-08 16:50:48 +02:00
Excalidraw Bot
16cb262a26 New translations en.json (Turkish) 2024-04-08 16:50:46 +02:00
Excalidraw Bot
35e2663504 New translations en.json (Slovenian) 2024-04-08 16:50:44 +02:00
Excalidraw Bot
81aaa909af New translations en.json (Russian) 2024-04-08 16:50:43 +02:00
Excalidraw Bot
976384a0a7 New translations en.json (Portuguese) 2024-04-08 16:50:42 +02:00
Excalidraw Bot
e989f1ff6c New translations en.json (Polish) 2024-04-08 16:50:41 +02:00
Excalidraw Bot
4237138392 New translations en.json (Punjabi) 2024-04-08 16:50:40 +02:00
Excalidraw Bot
192b67ee73 New translations en.json (Dutch) 2024-04-08 16:50:39 +02:00
Excalidraw Bot
7e2c567e33 New translations en.json (Lithuanian) 2024-04-08 16:50:38 +02:00
Excalidraw Bot
0659407aa8 New translations en.json (Kurdish) 2024-04-08 16:50:37 +02:00
Excalidraw Bot
c2f5ac17a7 New translations en.json (Korean) 2024-04-08 16:50:36 +02:00
Excalidraw Bot
ab7c9a4106 New translations en.json (Japanese) 2024-04-08 16:50:35 +02:00
Excalidraw Bot
e9e5671356 New translations en.json (Hungarian) 2024-04-08 16:50:34 +02:00
Excalidraw Bot
f447cbcc9f New translations en.json (Hebrew) 2024-04-08 16:50:33 +02:00
Excalidraw Bot
cea81f15a7 New translations en.json (Finnish) 2024-04-08 16:50:32 +02:00
Excalidraw Bot
bae392ce50 New translations en.json (Basque) 2024-04-08 16:50:31 +02:00
Excalidraw Bot
5eea304b1d New translations en.json (Greek) 2024-04-08 16:50:30 +02:00
Excalidraw Bot
dba82deef4 New translations en.json (German) 2024-04-08 16:50:29 +02:00
Excalidraw Bot
14a64cad6e New translations en.json (Danish) 2024-04-08 16:50:28 +02:00
Excalidraw Bot
bf73490b78 New translations en.json (Czech) 2024-04-08 16:50:27 +02:00
Excalidraw Bot
50462b4956 New translations en.json (Catalan) 2024-04-08 16:50:26 +02:00
Excalidraw Bot
64087e6055 New translations en.json (Bulgarian) 2024-04-08 16:50:25 +02:00
Excalidraw Bot
8933a677c0 New translations en.json (Arabic) 2024-04-08 16:50:24 +02:00
Excalidraw Bot
ac487862e9 New translations en.json (Spanish) 2024-04-08 16:50:23 +02:00
Excalidraw Bot
6202f38f70 New translations en.json (French) 2024-04-08 16:50:22 +02:00
Excalidraw Bot
a4779bfe73 New translations en.json (Romanian) 2024-04-08 16:50:21 +02:00
Excalidraw Bot
40874a88ef New translations en.json (Hindi) 2024-04-08 16:50:20 +02:00
Excalidraw Bot
88f6c86c9e New translations en.json (Chinese Simplified) 2024-04-08 16:50:19 +02:00
Excalidraw Bot
55bc4a6365 New translations en.json (Swedish) 2024-04-08 16:50:18 +02:00
Excalidraw Bot
3fb6ab5e45 New translations en.json (Slovak) 2024-04-08 16:50:17 +02:00
Excalidraw Bot
44d7db20e6 New translations en.json (Italian) 2024-04-08 16:50:16 +02:00
Arnost Pleskot
cd50aa719f feat: add system mode to the theme selector (#7853)
Co-authored-by: dwelle <5153846+dwelle@users.noreply.github.com>
2024-04-08 16:46:24 +02:00
David Luzar
92bc08207c fix: remove incorrect check from index.html (#7867) 2024-04-08 16:42:00 +02:00
Excalidraw Bot
8ffed1b059 Auto commit: Calculate translation coverage 2024-04-08 09:51:23 +00:00
Excalidraw Bot
5cae67c1cb New translations en.json (Vietnamese) 2024-04-08 11:51:09 +02:00
Ryan Di
32df5502ae feat: fractional indexing (#7359)
* Introducing fractional indices as part of `element.index`

* Ensuring invalid fractional indices are always synchronized with the array order

* Simplifying reconciliation based on the fractional indices

* Moving reconciliation inside the `@excalidraw/excalidraw` package

---------

Co-authored-by: Marcel Mraz <marcel@excalidraw.com>
Co-authored-by: dwelle <5153846+dwelle@users.noreply.github.com>
2024-04-04 13:51:11 +01:00
Ryan Di
bbdcd30a73 refactor: update collision from ga to vector geometry (#7636)
* new collision api

* isPointOnShape

* removed redundant code

* new collision methods in app

* curve shape takes starting point

* clean up geometry

* curve rotation

* freedraw

* inside curve

* improve ellipse inside check

* ellipse distance func

* curve inside

* include frame name bounds

* replace previous private methods for getting elements at x,y

* arrow bound text hit detection

* keep iframes on top

* remove dependence on old collision methods from app

* remove old collision functions

* move some hit functions outside of app

* code refactor

* type

* text collision from inside

* fix context menu test

* highest z-index collision

* fix 1px away binding test

* strictly less

* remove unused imports

* lint

* 'ignore' resize flipping test

* more lint fix

* skip 'flips while resizing' test

* more test

* fix merge errors

* fix selection in resize test

* added a bit more comment

---------

Co-authored-by: dwelle <5153846+dwelle@users.noreply.github.com>
2024-04-04 16:31:23 +08:00
Excalidraw Bot
4c04ce1c48 Auto commit: Calculate translation coverage 2024-04-03 13:45:31 +00:00
Excalidraw Bot
a464402919 New translations en.json (Hebrew) 2024-04-03 15:45:17 +02:00
Excalidraw Bot
be18f35595 Auto commit: Calculate translation coverage 2024-04-03 12:16:58 +00:00
Excalidraw Bot
b4f9ee520a New translations en.json (Hebrew) 2024-04-03 14:16:29 +02:00
Excalidraw Bot
455153d728 Auto commit: Calculate translation coverage 2024-04-01 06:34:04 +00:00
Excalidraw Bot
1353ef62b8 New translations en.json (Marathi) 2024-04-01 08:33:49 +02:00
Excalidraw Bot
6fad1e745a New translations en.json (Hindi) 2024-04-01 08:33:48 +02:00
Excalidraw Bot
2c988961f7 New translations en.json (Marathi) 2024-04-01 07:08:38 +02:00
Excalidraw Bot
2cd9a7697f New translations en.json (Hindi) 2024-04-01 07:08:37 +02:00
Excalidraw Bot
d398528493 Auto commit: Calculate translation coverage 2024-03-30 11:18:17 +00:00
Excalidraw Bot
59fe6e7b6d New translations en.json (Marathi) 2024-03-30 12:18:05 +01:00
Excalidraw Bot
abaf858f6c Auto commit: Calculate translation coverage 2024-03-29 14:45:52 +00:00
Excalidraw Bot
949c5b7af1 New translations en.json (Marathi) 2024-03-29 15:45:40 +01:00
Excalidraw Bot
701eb7f9fd Auto commit: Calculate translation coverage 2024-03-29 10:31:55 +00:00
Excalidraw Bot
07d92f720b New translations en.json (Catalan) 2024-03-29 11:31:42 +01:00
Excalidraw Bot
d16b808bb9 Auto commit: Calculate translation coverage 2024-03-29 09:27:55 +00:00
Excalidraw Bot
b2e09157da New translations en.json (Chinese Traditional) 2024-03-29 10:27:44 +01:00
Excalidraw Bot
93ee60cd9b New translations en.json (Romanian) 2024-03-29 10:27:43 +01:00
Excalidraw Bot
9eb509e068 New translations en.json (Chinese Simplified) 2024-03-29 10:27:42 +01:00
Excalidraw Bot
89f3dfb399 New translations en.json (Slovak) 2024-03-29 10:27:41 +01:00
Excalidraw Bot
a4c9355b03 Auto commit: Calculate translation coverage 2024-03-29 07:56:59 +00:00
Excalidraw Bot
c79cdab613 New translations en.json (Chinese Traditional) 2024-03-29 08:56:48 +01:00
Excalidraw Bot
ae3735a150 Auto commit: Calculate translation coverage 2024-03-29 04:28:08 +00:00
Excalidraw Bot
38a5c6c01a New translations en.json (Russian) 2024-03-29 05:27:57 +01:00
Excalidraw Bot
68caccfc2a Auto commit: Calculate translation coverage 2024-03-29 01:11:19 +00:00
Excalidraw Bot
9482c7adc6 New translations en.json (Swedish) 2024-03-29 02:11:07 +01:00
Excalidraw Bot
ff23a04e27 Auto commit: Calculate translation coverage 2024-03-29 00:01:13 +00:00
Excalidraw Bot
9ea989ee2a New translations en.json (Swedish) 2024-03-29 01:01:01 +01:00
Excalidraw Bot
261bff5bea Auto commit: Calculate translation coverage 2024-03-28 21:45:56 +00:00
Excalidraw Bot
55740254ed New translations en.json (German) 2024-03-28 22:45:44 +01:00
Excalidraw Bot
acb4da9f5c Auto commit: Calculate translation coverage 2024-03-28 20:46:08 +00:00
Excalidraw Bot
78131cf48b New translations en.json (Occitan) 2024-03-28 21:45:52 +01:00
Excalidraw Bot
415d5d6f6a Auto commit: Calculate translation coverage 2024-03-28 19:44:22 +00:00
Excalidraw Bot
0789a3db47 New translations en.json (Slovenian) 2024-03-28 20:44:05 +01:00
Excalidraw Bot
7218ddea85 Auto commit: Calculate translation coverage 2024-03-28 18:27:06 +00:00
Excalidraw Bot
e94ca414fb New translations en.json (Slovenian) 2024-03-28 19:26:45 +01:00
Excalidraw Bot
2b374bfa3d New translations en.json (German) 2024-03-28 19:26:36 +01:00
David Luzar
3e334a67ed feat: show firefox-compatible command palette shortcut alias (#7825) 2024-03-28 18:12:54 +01:00
Excalidraw Bot
a140db6244 Auto commit: Calculate translation coverage 2024-03-28 17:01:41 +00:00
Excalidraw Bot
07c0753d38 New translations en.json (Karakalpak) 2024-03-28 18:00:31 +01:00
Excalidraw Bot
26f3b861d7 New translations en.json (Kabyle) 2024-03-28 18:00:30 +01:00
Excalidraw Bot
f115a98333 New translations en.json (Occitan) 2024-03-28 18:00:29 +01:00
Excalidraw Bot
f45779c41c New translations en.json (Norwegian Bokmal) 2024-03-28 18:00:28 +01:00
Excalidraw Bot
8446097251 New translations en.json (Uzbek) 2024-03-28 18:00:27 +01:00
Excalidraw Bot
812dfcf633 New translations en.json (Sinhala) 2024-03-28 18:00:26 +01:00
Excalidraw Bot
7b3dcf2f03 New translations en.json (Chinese Traditional, Hong Kong) 2024-03-28 18:00:25 +01:00
Excalidraw Bot
aa27d5f8d1 New translations en.json (Burmese) 2024-03-28 18:00:24 +01:00
Excalidraw Bot
610ee586cb New translations en.json (Azerbaijani) 2024-03-28 18:00:23 +01:00
Excalidraw Bot
7f56e24078 New translations en.json (Latvian) 2024-03-28 18:00:22 +01:00
Excalidraw Bot
07bb8c524e New translations en.json (Kazakh) 2024-03-28 18:00:21 +01:00
Excalidraw Bot
9bed7b2086 New translations en.json (Norwegian Nynorsk) 2024-03-28 18:00:20 +01:00
Excalidraw Bot
5c5e6b851c New translations en.json (Thai) 2024-03-28 18:00:19 +01:00
Excalidraw Bot
ca415bca50 New translations en.json (Marathi) 2024-03-28 18:00:18 +01:00
Excalidraw Bot
7d6293d5a0 New translations en.json (Bengali) 2024-03-28 18:00:17 +01:00
Excalidraw Bot
0d35449faa New translations en.json (Tamil) 2024-03-28 18:00:16 +01:00
Excalidraw Bot
dd33aefac3 New translations en.json (Khmer) 2024-03-28 18:00:15 +01:00
Excalidraw Bot
8e137d1f72 New translations en.json (Persian) 2024-03-28 18:00:14 +01:00
Excalidraw Bot
2888c3bb6e New translations en.json (Indonesian) 2024-03-28 18:00:13 +01:00
Excalidraw Bot
aaef4e3402 New translations en.json (Portuguese, Brazilian) 2024-03-28 18:00:12 +01:00
Excalidraw Bot
8b0a35c832 New translations en.json (Galician) 2024-03-28 18:00:11 +01:00
Excalidraw Bot
ce2da48663 New translations en.json (Vietnamese) 2024-03-28 18:00:10 +01:00
Excalidraw Bot
869b89c136 New translations en.json (Chinese Traditional) 2024-03-28 18:00:09 +01:00
Excalidraw Bot
8bcbecc0ec New translations en.json (Ukrainian) 2024-03-28 18:00:08 +01:00
Excalidraw Bot
c7a0557e98 New translations en.json (Turkish) 2024-03-28 18:00:07 +01:00
Excalidraw Bot
c5e75439e4 New translations en.json (Slovenian) 2024-03-28 18:00:06 +01:00
Excalidraw Bot
8a07b5b907 New translations en.json (Russian) 2024-03-28 18:00:05 +01:00
Excalidraw Bot
584170eec3 New translations en.json (Portuguese) 2024-03-28 18:00:04 +01:00
Excalidraw Bot
6dd2501a19 New translations en.json (Polish) 2024-03-28 18:00:03 +01:00
Excalidraw Bot
3c3c1e9f8c New translations en.json (Punjabi) 2024-03-28 18:00:02 +01:00
Excalidraw Bot
17b01dec90 New translations en.json (Dutch) 2024-03-28 18:00:01 +01:00
Excalidraw Bot
eb4d64dcd8 New translations en.json (Lithuanian) 2024-03-28 17:59:59 +01:00
Excalidraw Bot
dc9f20c19e New translations en.json (Kurdish) 2024-03-28 17:59:59 +01:00
Excalidraw Bot
7c40b5ae3e New translations en.json (Korean) 2024-03-28 17:59:58 +01:00
Excalidraw Bot
bda85ff7ef New translations en.json (Japanese) 2024-03-28 17:59:57 +01:00
Excalidraw Bot
68b1bd80fa New translations en.json (Hungarian) 2024-03-28 17:59:56 +01:00
Excalidraw Bot
5771f5c0b7 New translations en.json (Hebrew) 2024-03-28 17:59:55 +01:00
Excalidraw Bot
fbbd953f42 New translations en.json (Finnish) 2024-03-28 17:59:53 +01:00
Excalidraw Bot
8d7e8e89db New translations en.json (Basque) 2024-03-28 17:59:53 +01:00
Excalidraw Bot
4e52529cbb New translations en.json (Greek) 2024-03-28 17:59:52 +01:00
Excalidraw Bot
a77c7bb41a New translations en.json (German) 2024-03-28 17:59:51 +01:00
Excalidraw Bot
5e2cdeb699 New translations en.json (Danish) 2024-03-28 17:59:50 +01:00
Excalidraw Bot
4d077f7324 New translations en.json (Czech) 2024-03-28 17:59:49 +01:00
Excalidraw Bot
7fda1f04cf New translations en.json (Catalan) 2024-03-28 17:59:48 +01:00
Excalidraw Bot
bce1d4a0e8 New translations en.json (Bulgarian) 2024-03-28 17:59:47 +01:00
Excalidraw Bot
cecd042357 New translations en.json (Arabic) 2024-03-28 17:59:46 +01:00
Excalidraw Bot
e4047f89c9 New translations en.json (Spanish) 2024-03-28 17:59:45 +01:00
Excalidraw Bot
1b457b3efd New translations en.json (French) 2024-03-28 17:59:44 +01:00
Excalidraw Bot
99fe0df4b1 New translations en.json (Romanian) 2024-03-28 17:59:43 +01:00
Excalidraw Bot
9f3209c487 New translations en.json (Hindi) 2024-03-28 17:59:42 +01:00
Excalidraw Bot
4388c33cd4 New translations en.json (Chinese Simplified) 2024-03-28 17:59:41 +01:00
Excalidraw Bot
3e5c45f674 New translations en.json (Swedish) 2024-03-28 17:59:40 +01:00
Excalidraw Bot
85bc583696 New translations en.json (Slovak) 2024-03-28 17:59:40 +01:00
Excalidraw Bot
2d2c35b6db New translations en.json (Italian) 2024-03-28 17:59:39 +01:00
David Luzar
1d71f84515 fix: stop using lookbehind for backwards compat (#7824) 2024-03-28 17:32:38 +01:00
Ryan Di
550a388b2b feat: command palette (#7804)
Co-authored-by: dwelle <5153846+dwelle@users.noreply.github.com>
2024-03-28 16:16:32 +00:00
David Luzar
6b523563d8 fix: ejs support in html files (#7822) 2024-03-28 14:58:47 +01:00
David Luzar
65bc500598 fix: excalidrawAPI.toggleSidebar not switching between tabs correctly (#7821) 2024-03-28 14:52:23 +01:00
Aakansha Doshi
7949aa1f1c feat: upgrade mermaid-to-excalidraw to 0.3.0 (#7819) 2024-03-28 16:44:29 +05:30
Excalidraw Bot
b3bc9b9513 Auto commit: Calculate translation coverage 2024-03-21 10:59:59 +00:00
Excalidraw Bot
ad5c655b32 New translations en.json (Hebrew) 2024-03-21 11:59:41 +01:00
Excalidraw Bot
b91e6b5e4e New translations en.json (Swedish) 2024-03-19 08:12:42 +01:00
Excalidraw Bot
06ca0a66de New translations en.json (Chinese Simplified) 2024-03-18 22:31:28 +01:00
Excalidraw Bot
f170f8dfc2 New translations en.json (Chinese Traditional) 2024-03-18 19:47:46 +01:00
Excalidraw Bot
b6b7518992 New translations en.json (Marathi) 2024-03-18 15:47:50 +01:00
Excalidraw Bot
be7b9ce46b New translations en.json (German) 2024-03-18 15:47:49 +01:00
Excalidraw Bot
743ae9bef1 New translations en.json (Hindi) 2024-03-18 15:47:48 +01:00
Excalidraw Bot
1616535de5 New translations en.json (Catalan) 2024-03-18 14:27:10 +01:00
Excalidraw Bot
18471dbdc8 New translations en.json (Slovenian) 2024-03-18 13:01:13 +01:00
Excalidraw Bot
2c9302b33f New translations en.json (Russian) 2024-03-18 13:01:12 +01:00
Excalidraw Bot
f60ae05858 New translations en.json (Catalan) 2024-03-18 13:01:11 +01:00
Excalidraw Bot
b14aeed40e New translations en.json (Romanian) 2024-03-18 13:01:10 +01:00
Excalidraw Bot
28a2f33bd3 New translations en.json (Karakalpak) 2024-03-18 11:07:38 +01:00
Excalidraw Bot
8183c9a2b9 New translations en.json (Kabyle) 2024-03-18 11:07:37 +01:00
Excalidraw Bot
449f57c0c9 New translations en.json (Occitan) 2024-03-18 11:07:36 +01:00
Excalidraw Bot
6d3f9b1da1 New translations en.json (Norwegian Bokmal) 2024-03-18 11:07:35 +01:00
Excalidraw Bot
a4f9983250 New translations en.json (Uzbek) 2024-03-18 11:07:34 +01:00
Excalidraw Bot
cd6f1e7e25 New translations en.json (Sinhala) 2024-03-18 11:07:33 +01:00
Excalidraw Bot
fc5668fed0 New translations en.json (Chinese Traditional, Hong Kong) 2024-03-18 11:07:32 +01:00
Excalidraw Bot
6cf27e310f New translations en.json (Burmese) 2024-03-18 11:07:31 +01:00
Excalidraw Bot
1291a341f1 New translations en.json (Azerbaijani) 2024-03-18 11:07:30 +01:00
Excalidraw Bot
989b774e9d New translations en.json (Latvian) 2024-03-18 11:07:29 +01:00
Excalidraw Bot
372ef53228 New translations en.json (Kazakh) 2024-03-18 11:07:29 +01:00
Excalidraw Bot
279c446ca8 New translations en.json (Norwegian Nynorsk) 2024-03-18 11:07:28 +01:00
Excalidraw Bot
afa96620bc New translations en.json (Thai) 2024-03-18 11:07:27 +01:00
Excalidraw Bot
acf3847f8d New translations en.json (Marathi) 2024-03-18 11:07:26 +01:00
Excalidraw Bot
8882514053 New translations en.json (Bengali) 2024-03-18 11:07:25 +01:00
Excalidraw Bot
2eabd48630 New translations en.json (Tamil) 2024-03-18 11:07:24 +01:00
Excalidraw Bot
b4f90ab130 New translations en.json (Khmer) 2024-03-18 11:07:23 +01:00
Excalidraw Bot
e3698ae541 New translations en.json (Persian) 2024-03-18 11:07:22 +01:00
Excalidraw Bot
4cccf1b413 New translations en.json (Indonesian) 2024-03-18 11:07:21 +01:00
Excalidraw Bot
e168710885 New translations en.json (Portuguese, Brazilian) 2024-03-18 11:07:20 +01:00
Excalidraw Bot
955892aeec New translations en.json (Galician) 2024-03-18 11:07:19 +01:00
Excalidraw Bot
a574f4d2e9 New translations en.json (Vietnamese) 2024-03-18 11:07:18 +01:00
Excalidraw Bot
022b39c858 New translations en.json (Chinese Traditional) 2024-03-18 11:07:17 +01:00
Excalidraw Bot
7f1bfe6179 New translations en.json (Ukrainian) 2024-03-18 11:07:16 +01:00
Excalidraw Bot
de6b632fa3 New translations en.json (Turkish) 2024-03-18 11:07:15 +01:00
Excalidraw Bot
8a5de5b143 New translations en.json (Slovenian) 2024-03-18 11:07:15 +01:00
Excalidraw Bot
3cae9483b0 New translations en.json (Russian) 2024-03-18 11:07:14 +01:00
Excalidraw Bot
0c65e60ed1 New translations en.json (Portuguese) 2024-03-18 11:07:12 +01:00
Excalidraw Bot
f85ccc1a88 New translations en.json (Polish) 2024-03-18 11:07:12 +01:00
Excalidraw Bot
22d9a24ae6 New translations en.json (Punjabi) 2024-03-18 11:07:11 +01:00
Excalidraw Bot
f181775371 New translations en.json (Dutch) 2024-03-18 11:07:10 +01:00
Excalidraw Bot
a5fbefdc84 New translations en.json (Lithuanian) 2024-03-18 11:07:09 +01:00
Excalidraw Bot
d1b10f6276 New translations en.json (Kurdish) 2024-03-18 11:07:08 +01:00
Excalidraw Bot
a04a4a42ed New translations en.json (Korean) 2024-03-18 11:07:07 +01:00
Excalidraw Bot
a18159226a New translations en.json (Japanese) 2024-03-18 11:07:06 +01:00
Excalidraw Bot
0646e4453c New translations en.json (Hungarian) 2024-03-18 11:07:05 +01:00
Excalidraw Bot
2352af7196 New translations en.json (Hebrew) 2024-03-18 11:07:04 +01:00
Excalidraw Bot
46a6886ac4 New translations en.json (Finnish) 2024-03-18 11:07:03 +01:00
Excalidraw Bot
3ddf1c179a New translations en.json (Basque) 2024-03-18 11:07:02 +01:00
Excalidraw Bot
a0b2a0e4e6 New translations en.json (Greek) 2024-03-18 11:07:01 +01:00
Excalidraw Bot
43c46052f3 New translations en.json (German) 2024-03-18 11:07:00 +01:00
Excalidraw Bot
e8832fcb28 New translations en.json (Danish) 2024-03-18 11:06:59 +01:00
Excalidraw Bot
bd02772edb New translations en.json (Czech) 2024-03-18 11:06:58 +01:00
Excalidraw Bot
d5a38f3799 New translations en.json (Catalan) 2024-03-18 11:06:57 +01:00
Excalidraw Bot
921dca9f5b New translations en.json (Bulgarian) 2024-03-18 11:06:56 +01:00
Excalidraw Bot
8899453891 New translations en.json (Arabic) 2024-03-18 11:06:55 +01:00
Excalidraw Bot
7392af03a3 New translations en.json (Spanish) 2024-03-18 11:06:54 +01:00
Excalidraw Bot
7d1f4deb27 New translations en.json (French) 2024-03-18 11:06:53 +01:00
Excalidraw Bot
66724ac81d New translations en.json (Romanian) 2024-03-18 11:06:52 +01:00
Excalidraw Bot
2368d34ab3 New translations en.json (Hindi) 2024-03-18 11:06:52 +01:00
Excalidraw Bot
ddc2d8d2b7 New translations en.json (Chinese Simplified) 2024-03-18 11:06:51 +01:00
Excalidraw Bot
a7012a4b8e New translations en.json (Swedish) 2024-03-18 11:06:50 +01:00
Excalidraw Bot
88db54e11c New translations en.json (Slovak) 2024-03-18 11:06:49 +01:00
Excalidraw Bot
bc85f580ec New translations en.json (Italian) 2024-03-18 11:06:48 +01:00
David Luzar
15bfa626b4 feat: support to not render remote cursor & username (#7130) 2024-03-18 10:41:06 +01:00
David Luzar
068895db0e feat: expose more collaborator status icons (#7777) 2024-03-18 10:20:07 +01:00
Excalidraw Bot
02fd58ffc8 New translations en.json (Hindi) 2024-03-18 03:49:55 +01:00
dwelle
b7babe554b feat: load old library if migration fails 2024-03-11 09:57:01 +01:00
dwelle
6a385d6663 feat: change LibraryPersistenceAdapter load() source -> priority
to clarify the semantics
2024-03-11 09:40:51 +01:00
Excalidraw Bot
93af0ce89d New translations en.json (Swedish) 2024-03-11 07:35:54 +01:00
Excalidraw Bot
1c025c166a New translations en.json (Polish) 2024-03-09 23:01:20 +01:00
Excalidraw Bot
150e0cef5d New translations en.json (Polish) 2024-03-09 22:05:45 +01:00
Excalidraw Bot
7f40852b11 New translations en.json (Bengali) 2024-03-09 20:53:27 +01:00
Excalidraw Bot
0b6fae0243 New translations en.json (Chinese Traditional) 2024-03-09 20:53:26 +01:00
Excalidraw Bot
37af96a577 New translations en.json (Bengali) 2024-03-09 19:49:38 +01:00
Excalidraw Bot
0e718265fa New translations en.json (Romanian) 2024-03-09 14:22:26 +01:00
Excalidraw Bot
16b103151b New translations en.json (German) 2024-03-09 08:30:33 +01:00
Excalidraw Bot
351db6e2b9 New translations en.json (Russian) 2024-03-09 07:34:41 +01:00
Excalidraw Bot
b2fb87cd40 New translations en.json (Marathi) 2024-03-09 06:18:09 +01:00
Excalidraw Bot
388ec9f4db New translations en.json (Hindi) 2024-03-09 06:18:08 +01:00
Excalidraw Bot
95dd7f0617 New translations en.json (Chinese Simplified) 2024-03-09 06:18:07 +01:00
Excalidraw Bot
2349b9dcfe New translations en.json (Slovenian) 2024-03-09 00:41:58 +01:00
Excalidraw Bot
ddd05ff030 New translations en.json (Karakalpak) 2024-03-08 22:39:03 +01:00
Excalidraw Bot
4bc30fda19 New translations en.json (Kabyle) 2024-03-08 22:39:02 +01:00
Excalidraw Bot
285744877c New translations en.json (Occitan) 2024-03-08 22:39:01 +01:00
Excalidraw Bot
2169ac6fba New translations en.json (Norwegian Bokmal) 2024-03-08 22:39:00 +01:00
Excalidraw Bot
d2b9034f5e New translations en.json (Uzbek) 2024-03-08 22:38:59 +01:00
Excalidraw Bot
f1bbd3c5a0 New translations en.json (Sinhala) 2024-03-08 22:38:58 +01:00
Excalidraw Bot
aec87f706b New translations en.json (Chinese Traditional, Hong Kong) 2024-03-08 22:38:57 +01:00
Excalidraw Bot
7bd06eef1b New translations en.json (Burmese) 2024-03-08 22:38:56 +01:00
Excalidraw Bot
3be12ef66c New translations en.json (Azerbaijani) 2024-03-08 22:38:55 +01:00
Excalidraw Bot
8dae7772b0 New translations en.json (Latvian) 2024-03-08 22:38:54 +01:00
Excalidraw Bot
f69532aebf New translations en.json (Kazakh) 2024-03-08 22:38:53 +01:00
Excalidraw Bot
5f4e421001 New translations en.json (Norwegian Nynorsk) 2024-03-08 22:38:52 +01:00
Excalidraw Bot
b350917852 New translations en.json (Thai) 2024-03-08 22:38:51 +01:00
Excalidraw Bot
d3d1e21107 New translations en.json (Marathi) 2024-03-08 22:38:50 +01:00
Excalidraw Bot
11a7d52578 New translations en.json (Bengali) 2024-03-08 22:38:49 +01:00
Excalidraw Bot
d8a4736c01 New translations en.json (Tamil) 2024-03-08 22:38:49 +01:00
Excalidraw Bot
2a4b70e26c New translations en.json (Khmer) 2024-03-08 22:38:47 +01:00
Excalidraw Bot
353c17dc3b New translations en.json (Persian) 2024-03-08 22:38:46 +01:00
Excalidraw Bot
f51efffd3a New translations en.json (Indonesian) 2024-03-08 22:38:45 +01:00
Excalidraw Bot
2618178a93 New translations en.json (Portuguese, Brazilian) 2024-03-08 22:38:44 +01:00
Excalidraw Bot
c57d36ba38 New translations en.json (Galician) 2024-03-08 22:38:44 +01:00
Excalidraw Bot
6fa91ecb5c New translations en.json (Vietnamese) 2024-03-08 22:38:43 +01:00
Excalidraw Bot
44d61bcb62 New translations en.json (Chinese Traditional) 2024-03-08 22:38:42 +01:00
Excalidraw Bot
dfeddba61b New translations en.json (Ukrainian) 2024-03-08 22:38:41 +01:00
Excalidraw Bot
d691aa87ce New translations en.json (Turkish) 2024-03-08 22:38:40 +01:00
Excalidraw Bot
5a56bbb01d New translations en.json (Slovenian) 2024-03-08 22:38:39 +01:00
Excalidraw Bot
675adb6f0d New translations en.json (Russian) 2024-03-08 22:38:38 +01:00
Excalidraw Bot
4969de2250 New translations en.json (Portuguese) 2024-03-08 22:38:37 +01:00
Excalidraw Bot
8f6d5b3871 New translations en.json (Polish) 2024-03-08 22:38:36 +01:00
Excalidraw Bot
7732cd1d87 New translations en.json (Punjabi) 2024-03-08 22:38:35 +01:00
Excalidraw Bot
a166aa0ac5 New translations en.json (Dutch) 2024-03-08 22:38:34 +01:00
Excalidraw Bot
51fe6a8203 New translations en.json (Lithuanian) 2024-03-08 22:38:33 +01:00
Excalidraw Bot
287c3fce76 New translations en.json (Kurdish) 2024-03-08 22:38:32 +01:00
Excalidraw Bot
b78404bd85 New translations en.json (Korean) 2024-03-08 22:38:31 +01:00
Excalidraw Bot
1e2cc0b6f1 New translations en.json (Japanese) 2024-03-08 22:38:30 +01:00
Excalidraw Bot
be303375c4 New translations en.json (Hungarian) 2024-03-08 22:38:29 +01:00
Excalidraw Bot
8ba188e429 New translations en.json (Hebrew) 2024-03-08 22:38:28 +01:00
Excalidraw Bot
10842ae839 New translations en.json (Finnish) 2024-03-08 22:38:27 +01:00
Excalidraw Bot
592b9862e1 New translations en.json (Basque) 2024-03-08 22:38:27 +01:00
Excalidraw Bot
01b44663e3 New translations en.json (Greek) 2024-03-08 22:38:26 +01:00
Excalidraw Bot
ce59dd6d07 New translations en.json (German) 2024-03-08 22:38:25 +01:00
Excalidraw Bot
199d0eec81 New translations en.json (Danish) 2024-03-08 22:38:24 +01:00
Excalidraw Bot
176558d6d6 New translations en.json (Czech) 2024-03-08 22:38:22 +01:00
Excalidraw Bot
94da21229b New translations en.json (Catalan) 2024-03-08 22:38:21 +01:00
Excalidraw Bot
58298a9758 New translations en.json (Bulgarian) 2024-03-08 22:38:20 +01:00
Excalidraw Bot
bc53ef2017 New translations en.json (Arabic) 2024-03-08 22:38:19 +01:00
Excalidraw Bot
2892c5d77d New translations en.json (Spanish) 2024-03-08 22:38:19 +01:00
Excalidraw Bot
833e83d57d New translations en.json (French) 2024-03-08 22:38:17 +01:00
Excalidraw Bot
47369822d8 New translations en.json (Romanian) 2024-03-08 22:38:16 +01:00
Excalidraw Bot
2da836df9d New translations en.json (Hindi) 2024-03-08 22:38:15 +01:00
Excalidraw Bot
c42d3700f0 New translations en.json (Chinese Simplified) 2024-03-08 22:38:14 +01:00
Excalidraw Bot
146c599e43 New translations en.json (Swedish) 2024-03-08 22:38:13 +01:00
Excalidraw Bot
950651ce0a New translations en.json (Slovak) 2024-03-08 22:38:12 +01:00
Excalidraw Bot
50ef5d664c New translations en.json (Italian) 2024-03-08 22:38:11 +01:00
David Luzar
2382fad4f6 feat: store library to IndexedDB & support storage adapters (#7655) 2024-03-08 22:29:19 +01:00
Excalidraw Bot
1d1c6f35fa New translations en.json (Hindi) 2024-03-07 18:46:48 +01:00
Marcel Mraz
480572f893 fix: correcting Assistant metrics (#7758)
* Changed Assistant metrics to the corrrect ones from OS/2 table

* Adding more information about font metrics

* Adding branded types to avoid future mistakes
2024-03-07 16:54:36 +01:00
David Luzar
68b1fdb20e fix: add missing font metrics for Assistant (#7752) 2024-03-06 10:53:37 +01:00
David Luzar
a38e82f999 feat: close dropdown on escape (#7750) 2024-03-05 23:22:34 +01:00
David Luzar
a07f6e9e3a feat: show ai badge for discovery (#7749) 2024-03-05 23:22:25 +01:00
Marcel Mraz
7e471b55eb feat: text measurements based on font metrics (#7693)
* Introduced vertical offset based on harcoded font metrics 

* Unified usage of alphabetic baseline for both canvas & svg export

* Removed baseline property

* Removed font-size rounding on Safari

* Removed artificial width offset
2024-03-05 19:33:27 +00:00
Excalidraw Bot
fd43439dab New translations en.json (Swedish) 2024-03-04 16:57:04 +01:00
Ryan Di
160440b860 feat: improve collab error notification (#7741)
* identify cause

* toast after dialog for error messages in collab

* remove comment

* shake tooltip instead for repeating collab errors

* clear collab error

* empty commit

* simplify & fix reset race condition

---------

Co-authored-by: dwelle <5153846+dwelle@users.noreply.github.com>
2024-03-04 20:43:44 +08:00
Excalidraw Bot
84ae576ad0 Auto commit: Calculate translation coverage 2024-02-29 16:15:01 +00:00
Excalidraw Bot
bc32a00d6a New translations en.json (Slovak) 2024-02-29 17:14:47 +01:00
Aakansha Doshi
f207bd0a1c build: export types for @excalidraw/utils (#7736)
* build: export types for @excalidraw/utils

* fix

* add types
2024-02-29 15:43:04 +05:30
Aakansha Doshi
99601baffc build: create ESM build for utils package 🥳 (#7500)
* build: create ESM build for utils package

* add deps, exports and import.meta
2024-02-28 19:33:47 +05:30
Aakansha Doshi
af1a3d5b76 fix: export utils from excalidraw package in excalidraw library (#7731)
* fix: export utils from excalidraw package in excalidraw library

* don't export utils utilities

* fix import path

* fix export

* don't export export utilites

* fix export paths

* reexport utils from excalidraw package

* add exports from withinBounds

* fix path
2024-02-28 11:14:57 +05:30
Excalidraw Bot
441b2ff2fd Auto commit: Calculate translation coverage 2024-02-28 04:48:28 +00:00
Excalidraw Bot
941e350245 New translations en.json (Chinese Simplified) 2024-02-28 05:48:15 +01:00
Wabweni Brian
36e56267c9 docs: add missing closing angle bracket in integration.mdx (#7729)
Update integration.mdx: Fix missing closing angle bracket in code sample

 A closing angle bracket was missing in a code sample.

Original code:
<div style={{height:"500px", width:"500px"}}
    <Excalidraw />
</div>

Changes:

<div style={{height:"500px", width:"500px"}}>
    <Excalidraw />
</div>
2024-02-27 07:19:20 +00:00
Aakansha Doshi
b09b5cb5f4 fix: split renderScene so that locales aren't imported unnecessarily (#7718)
* fix: split renderScene so that locales aren't imported unnecessarily

* lint

* split export code

* rename renderScene to helpers.ts

* add helpers

* fix typo

* fixes

* move renderElementToSvg to export

* lint

* rename export to staticSvgScene

* fix
2024-02-27 10:37:44 +05:30
Excalidraw Bot
e32290e9e1 Auto commit: Calculate translation coverage 2024-02-26 16:46:46 +00:00
Excalidraw Bot
231a806257 New translations en.json (Italian) 2024-02-26 17:46:32 +01:00
Excalidraw Bot
782daddfcc Auto commit: Calculate translation coverage 2024-02-26 15:47:06 +00:00
Excalidraw Bot
51ea204cb7 New translations en.json (Italian) 2024-02-26 16:46:49 +01:00
Aashman Verma
dd8529743a docs: type mistake in integration of excalidraw (#7723) 2024-02-26 10:24:27 +01:00
Excalidraw Bot
606979a539 New translations en.json (Hindi) 2024-02-25 19:30:01 +01:00
Aakansha Doshi
f639d44a95 fix: remove dependency of t in blob.ts (#7717)
* remove dependency of t in blob.ts

* fix
2024-02-23 15:05:46 +05:30
Excalidraw Bot
f1a51e5512 New translations en.json (Hindi) 2024-02-22 16:05:51 +01:00
Excalidraw Bot
2275532d10 New translations en.json (Marathi) 2024-02-22 16:05:49 +01:00
Excalidraw Bot
2d03d9b667 New translations en.json (Swedish) 2024-02-22 11:33:28 +01:00
Excalidraw Bot
917d5c81e3 Auto commit: Calculate translation coverage 2024-02-21 21:18:11 +00:00
Excalidraw Bot
d67ffe20ea New translations en.json (Romanian) 2024-02-21 22:17:56 +01:00
Excalidraw Bot
5252cc6f11 Auto commit: Calculate translation coverage 2024-02-21 19:01:07 +00:00
Excalidraw Bot
f006df974d New translations en.json (Chinese Traditional) 2024-02-21 20:00:53 +01:00
Excalidraw Bot
7bd061d996 Auto commit: Calculate translation coverage 2024-02-21 18:05:14 +00:00
Excalidraw Bot
2a3aa69f35 New translations en.json (German) 2024-02-21 19:05:01 +01:00
Excalidraw Bot
5908d8c07e Auto commit: Calculate translation coverage 2024-02-21 16:36:25 +00:00
Excalidraw Bot
e0fce912d5 New translations en.json (Slovenian) 2024-02-21 17:36:11 +01:00
Excalidraw Bot
8a77638f67 Auto commit: Calculate translation coverage 2024-02-21 15:23:40 +00:00
Excalidraw Bot
d3c43fb648 New translations en.json (Karakalpak) 2024-02-21 16:22:40 +01:00
Excalidraw Bot
1974b49b52 New translations en.json (Kabyle) 2024-02-21 16:22:39 +01:00
Excalidraw Bot
e729048c98 New translations en.json (Occitan) 2024-02-21 16:22:38 +01:00
Excalidraw Bot
6164bd47f9 New translations en.json (Norwegian Bokmal) 2024-02-21 16:22:37 +01:00
Excalidraw Bot
791fbfa2e8 New translations en.json (Sinhala) 2024-02-21 16:22:36 +01:00
Excalidraw Bot
fbdbcedf33 New translations en.json (Chinese Traditional, Hong Kong) 2024-02-21 16:22:35 +01:00
Excalidraw Bot
ca7c470793 New translations en.json (Burmese) 2024-02-21 16:22:34 +01:00
Excalidraw Bot
cf787e8b72 New translations en.json (Hindi) 2024-02-21 16:22:33 +01:00
Excalidraw Bot
998789dbe8 New translations en.json (Azerbaijani) 2024-02-21 16:22:32 +01:00
Excalidraw Bot
1b7098b775 New translations en.json (Latvian) 2024-02-21 16:22:31 +01:00
Excalidraw Bot
152dcae5bc New translations en.json (Kazakh) 2024-02-21 16:22:29 +01:00
Excalidraw Bot
42f2e1c5c3 New translations en.json (Norwegian Nynorsk) 2024-02-21 16:22:29 +01:00
Excalidraw Bot
a986a4f0bf New translations en.json (Thai) 2024-02-21 16:22:27 +01:00
Excalidraw Bot
f2fc6ee067 New translations en.json (Marathi) 2024-02-21 16:22:26 +01:00
Excalidraw Bot
043503a739 New translations en.json (Bengali) 2024-02-21 16:22:25 +01:00
Excalidraw Bot
83cd933987 New translations en.json (Tamil) 2024-02-21 16:22:24 +01:00
Excalidraw Bot
9efa749059 New translations en.json (Khmer) 2024-02-21 16:22:23 +01:00
Excalidraw Bot
c8fb8f0b2e New translations en.json (Persian) 2024-02-21 16:22:22 +01:00
Excalidraw Bot
ec719c131f New translations en.json (Indonesian) 2024-02-21 16:22:21 +01:00
Excalidraw Bot
90375a2f12 New translations en.json (Portuguese, Brazilian) 2024-02-21 16:22:20 +01:00
Excalidraw Bot
6051275d0a New translations en.json (Chinese Traditional) 2024-02-21 16:22:19 +01:00
Excalidraw Bot
06f0c2388d New translations en.json (Chinese Simplified) 2024-02-21 16:22:18 +01:00
Excalidraw Bot
7051bac7d8 New translations en.json (Ukrainian) 2024-02-21 16:22:17 +01:00
Excalidraw Bot
44aa5856cd New translations en.json (Swedish) 2024-02-21 16:22:15 +01:00
Excalidraw Bot
374dc52601 New translations en.json (Slovenian) 2024-02-21 16:22:14 +01:00
Excalidraw Bot
46345e9956 New translations en.json (Slovak) 2024-02-21 16:22:13 +01:00
Excalidraw Bot
f3c02d4298 New translations en.json (Russian) 2024-02-21 16:22:13 +01:00
Excalidraw Bot
b4cedca7da New translations en.json (Portuguese) 2024-02-21 16:22:11 +01:00
Excalidraw Bot
deaf828e84 New translations en.json (Polish) 2024-02-21 16:22:10 +01:00
Excalidraw Bot
38a5698bc7 New translations en.json (Punjabi) 2024-02-21 16:22:09 +01:00
Excalidraw Bot
70af8a3fa5 New translations en.json (Dutch) 2024-02-21 16:22:08 +01:00
Excalidraw Bot
37b172c8ca New translations en.json (Lithuanian) 2024-02-21 16:22:07 +01:00
Excalidraw Bot
1eef380425 New translations en.json (Kurdish) 2024-02-21 16:22:06 +01:00
Excalidraw Bot
1dcf411626 New translations en.json (Korean) 2024-02-21 16:22:05 +01:00
Excalidraw Bot
378a97553c New translations en.json (Italian) 2024-02-21 16:22:04 +01:00
Excalidraw Bot
3246b04911 New translations en.json (Hungarian) 2024-02-21 16:22:03 +01:00
Excalidraw Bot
dda48a7d6a New translations en.json (Hebrew) 2024-02-21 16:22:02 +01:00
Excalidraw Bot
29153f0d8d New translations en.json (Finnish) 2024-02-21 16:22:01 +01:00
Excalidraw Bot
70c513f568 New translations en.json (Basque) 2024-02-21 16:22:00 +01:00
Excalidraw Bot
56f75b259c New translations en.json (Greek) 2024-02-21 16:21:58 +01:00
Excalidraw Bot
f94a3a7711 New translations en.json (German) 2024-02-21 16:21:57 +01:00
Excalidraw Bot
5a166ee235 New translations en.json (Danish) 2024-02-21 16:21:56 +01:00
Excalidraw Bot
0c199e42c8 New translations en.json (Czech) 2024-02-21 16:21:55 +01:00
Excalidraw Bot
a377f55d7f New translations en.json (Bulgarian) 2024-02-21 16:21:54 +01:00
Excalidraw Bot
c4759c8ca8 New translations en.json (Arabic) 2024-02-21 16:21:53 +01:00
Excalidraw Bot
9d19230033 New translations en.json (Spanish) 2024-02-21 16:21:52 +01:00
Excalidraw Bot
5aa2ec962b New translations en.json (French) 2024-02-21 16:21:51 +01:00
Excalidraw Bot
b21e7f0a70 New translations en.json (Romanian) 2024-02-21 16:21:50 +01:00
Excalidraw Bot
0056d274d5 New translations en.json (Uzbek) 2024-02-21 16:21:49 +01:00
Excalidraw Bot
cf5d7f3928 New translations en.json (Catalan) 2024-02-21 16:21:48 +01:00
Excalidraw Bot
058eed953e New translations en.json (Vietnamese) 2024-02-21 16:21:47 +01:00
Excalidraw Bot
5feb41624d New translations en.json (Turkish) 2024-02-21 16:21:46 +01:00
Excalidraw Bot
10a74bf607 New translations en.json (Galician) 2024-02-21 16:21:45 +01:00
Excalidraw Bot
0d1bb00270 New translations en.json (Japanese) 2024-02-21 16:21:44 +01:00
Aakansha Doshi
f5ab3e4e12 fix: remove dependency of t from clipboard and image (#7712)
* fix: remove dependency of t from clipboard and image

* pass errorMessage to copyTextToSystemClipboard where needed

* wrap copyTextToSystemClipboard and rethrow translated error in caller

* review fix

* typo
2024-02-21 19:45:33 +05:30
Aakansha Doshi
361a9449bb fix: remove scene hack from export.ts & remove pass elementsMap to getContainingFrame (#7713)
* fix: remove scene hack from export.ts as its not needed anymore

* remove

* pass elementsMap to getContainingFrame

* remove unused `mapElementIds` param

---------

Co-authored-by: dwelle <5153846+dwelle@users.noreply.github.com>
2024-02-21 16:34:20 +05:30
Aakansha Doshi
2e719ff671 fix: decouple pure functions from hyperlink to prevent mermaid bundling (#7710)
* move hyperlink code into its folder

* move pure js functions to hyperlink/helpers and move actionLink to actions

* fix tests

* fix
2024-02-20 20:59:01 +05:30
Excalidraw Bot
506756f332 Auto commit: Calculate translation coverage 2024-02-20 03:48:35 +00:00
Excalidraw Bot
67239c874e New translations en.json (Uzbek) 2024-02-20 04:48:23 +01:00
Aakansha Doshi
79d9dc2f8f fix: make bounds independent of scene (#7679)
* fix: make bounds independent of scene

* pass only elements to getCommonBounds

* lint

* pass elementsMap to getVisibleAndNonSelectedElements
2024-02-19 19:39:14 +05:30
Excalidraw Bot
d6cf042764 Auto commit: Calculate translation coverage 2024-02-19 13:24:59 +00:00
Excalidraw Bot
8e5f3ca841 New translations en.json (Catalan) 2024-02-19 14:24:43 +01:00
Aakansha Doshi
9013c84524 fix: make LinearElementEditor independent of scene (#7670)
* fix: make LinearElementEditor independent of scene

* more fixes

* pass elements and elementsMap to maybeBindBindableElement,getHoveredElementForBinding,bindingBorderTest,getElligibleElementsForBindableElementAndWhere,isLinearElementEligibleForNewBindingByBindable

* replace `ElementsMap` with `NonDeletedSceneElementsMap` & remove unused params

* fix lint

---------

Co-authored-by: dwelle <5153846+dwelle@users.noreply.github.com>
2024-02-19 11:49:01 +05:30
Aakansha Doshi
47f87f4ecb fix: remove scene from getElementAbsoluteCoords and dependent functions and use elementsMap (#7663)
* fix: remove scene from getElementAbsoluteCoords and dependent functions and use elementsMap

* lint

* fix

* use non deleted elements where possible

* use non deleted elements map in actions

* pass elementsMap instead of array to elementOverlapsWithFrame

* lint

* fix

* pass elementsMap to getElementsCorners

* pass elementsMap to getEligibleElementsForBinding

* pass elementsMap in bindOrUnbindSelectedElements and unbindLinearElements

* pass elementsMap in elementsAreInFrameBounds,elementOverlapsWithFrame,isCursorInFrame,getElementsInResizingFrame

* pass elementsMap in getElementsWithinSelection, getElementsCompletelyInFrame, isElementContainingFrame, getElementsInNewFrame

* pass elementsMap to getElementWithTransformHandleType

* pass elementsMap to getVisibleGaps, getMaximumGroups,getReferenceSnapPoints,snapDraggedElements

* lint

* pass elementsMap to bindTextToShapeAfterDuplication,bindLinearElementToElement,getTextBindableContainerAtPosition

* revert changes for bindTextToShapeAfterDuplication
2024-02-16 11:35:01 +05:30
Excalidraw Bot
41d325fdd8 Auto commit: Calculate translation coverage 2024-02-15 15:43:56 +00:00
Excalidraw Bot
6b6761f654 New translations en.json (Vietnamese) 2024-02-15 16:43:43 +01:00
Aakansha Doshi
73bf50e8a8 fix: remove t from getDefaultAppState and allow name to be nullable (#7666)
* fix: remove t and allow name to be nullable

* pass name as required prop

* remove Unnamed

* pass name to excalidrawPlus as well for better type safe

* render once we have excalidrawAPI to avoid defaulting

* rename `getAppName` -> `getName` (temporary)

* stop preventing editing filenames when `props.name` supplied

* keep `name` as optional param for export functions

* keep `appState.name` on `props.name` state separate

* fix lint

* assertive first

* fix lint

* Add TODO

---------

Co-authored-by: dwelle <5153846+dwelle@users.noreply.github.com>
2024-02-15 11:11:18 +05:30
Excalidraw Bot
fc3ae973be Auto commit: Calculate translation coverage 2024-02-13 11:15:09 +00:00
Excalidraw Bot
0c3c4d4f22 New translations en.json (Galician) 2024-02-13 12:14:56 +01:00
Excalidraw Bot
4df91b980a Auto commit: Calculate translation coverage 2024-02-10 10:54:58 +00:00
Excalidraw Bot
3729104547 New translations en.json (Japanese) 2024-02-10 11:54:46 +01:00
Aakansha Doshi
48c3465b19 docs: release patch v0.17.3 (#7673)
* docs: release patch v0.17.3

* update cl
2024-02-09 19:29:50 +05:30
David Luzar
adc4c9f484 fix: prevent panning to trigger history on macos chrome (#7671) 2024-02-08 19:50:50 +01:00
YuBin, Hsu
def1df2c68 fix: keep customData when converting to ExcalidrawElement (#7656)
* feat: keep customData when converting to ExcalidrawElement (#7654)

* docs: add changelog for keeping customData when converting to ExcalidrawElement
2024-02-08 17:23:10 +05:30
Excalidraw Bot
9fd896c1d1 Auto commit: Calculate translation coverage 2024-02-06 19:24:30 +00:00
Excalidraw Bot
e6f4e1f027 New translations en.json (Portuguese) 2024-02-06 20:24:16 +01:00
Excalidraw Bot
35424f62ed New translations en.json (Swedish) 2024-02-06 09:32:24 +01:00
Excalidraw Bot
70943ae461 Auto commit: Calculate translation coverage 2024-02-05 13:44:35 +00:00
Excalidraw Bot
a976aa7123 New translations en.json (French) 2024-02-05 14:44:22 +01:00
Excalidraw Bot
e58111d93d New translations en.json (Russian) 2024-02-04 18:14:26 +01:00
Excalidraw Bot
311ebaa5a4 Auto commit: Calculate translation coverage 2024-02-04 10:18:20 +00:00
Excalidraw Bot
b058b2dff1 New translations en.json (Dutch) 2024-02-04 11:18:10 +01:00
Excalidraw Bot
6c77e76c4c Auto commit: Calculate translation coverage 2024-02-04 08:44:00 +00:00
Excalidraw Bot
691225f51a New translations en.json (Romanian) 2024-02-04 09:43:48 +01:00
Excalidraw Bot
d46c669f64 Auto commit: Calculate translation coverage 2024-02-03 23:48:17 +00:00
Excalidraw Bot
7f46da315f New translations en.json (Chinese Simplified) 2024-02-04 00:48:06 +01:00
Excalidraw Bot
b7e0d18fae Auto commit: Calculate translation coverage 2024-02-03 16:41:58 +00:00
Excalidraw Bot
f9095caa42 New translations en.json (German) 2024-02-03 17:41:47 +01:00
Excalidraw Bot
de5c825d01 Auto commit: Calculate translation coverage 2024-02-03 15:29:53 +00:00
Excalidraw Bot
5fd26d2a45 New translations en.json (Karakalpak) 2024-02-03 16:28:33 +01:00
Excalidraw Bot
06052b1f3e New translations en.json (Kabyle) 2024-02-03 16:28:32 +01:00
Excalidraw Bot
98b3fbbc18 New translations en.json (Norwegian Bokmal) 2024-02-03 16:28:31 +01:00
Excalidraw Bot
fd29c8dd44 New translations en.json (Sinhala) 2024-02-03 16:28:30 +01:00
Excalidraw Bot
f4e90f1888 New translations en.json (Chinese Traditional, Hong Kong) 2024-02-03 16:28:29 +01:00
Excalidraw Bot
d9d8a39d6a New translations en.json (Burmese) 2024-02-03 16:28:28 +01:00
Excalidraw Bot
aa1a99dcf2 New translations en.json (Azerbaijani) 2024-02-03 16:28:27 +01:00
Excalidraw Bot
01f863f268 New translations en.json (Latvian) 2024-02-03 16:28:26 +01:00
Excalidraw Bot
8779e7f36f New translations en.json (Kazakh) 2024-02-03 16:28:25 +01:00
Excalidraw Bot
703cfc02e9 New translations en.json (Norwegian Nynorsk) 2024-02-03 16:28:25 +01:00
Excalidraw Bot
d11c92ffc3 New translations en.json (Thai) 2024-02-03 16:28:24 +01:00
Excalidraw Bot
7f381a0d02 New translations en.json (Marathi) 2024-02-03 16:28:23 +01:00
Excalidraw Bot
b8b1b9d57f New translations en.json (Bengali) 2024-02-03 16:28:22 +01:00
Excalidraw Bot
103c0e5997 New translations en.json (Tamil) 2024-02-03 16:28:21 +01:00
Excalidraw Bot
696e3d6836 New translations en.json (Khmer) 2024-02-03 16:28:20 +01:00
Excalidraw Bot
07a6b9942e New translations en.json (Persian) 2024-02-03 16:28:19 +01:00
Excalidraw Bot
e3d2b854d7 New translations en.json (Indonesian) 2024-02-03 16:28:18 +01:00
Excalidraw Bot
5ee88f6c6b New translations en.json (Portuguese, Brazilian) 2024-02-03 16:28:17 +01:00
Excalidraw Bot
1681598c7d New translations en.json (Vietnamese) 2024-02-03 16:28:16 +01:00
Excalidraw Bot
8f6d92c45c New translations en.json (Chinese Traditional) 2024-02-03 16:28:15 +01:00
Excalidraw Bot
3445c340a1 New translations en.json (Chinese Simplified) 2024-02-03 16:28:14 +01:00
Excalidraw Bot
a82d3c15ff New translations en.json (Turkish) 2024-02-03 16:28:13 +01:00
Excalidraw Bot
8b44b2f2ed New translations en.json (Swedish) 2024-02-03 16:28:12 +01:00
Excalidraw Bot
3f4f9e914b New translations en.json (Slovenian) 2024-02-03 16:28:11 +01:00
Excalidraw Bot
721565f3c3 New translations en.json (Slovak) 2024-02-03 16:28:10 +01:00
Excalidraw Bot
4b8060b093 New translations en.json (Russian) 2024-02-03 16:28:10 +01:00
Excalidraw Bot
b61bbfea4e New translations en.json (Portuguese) 2024-02-03 16:28:09 +01:00
Excalidraw Bot
6c88eb12d7 New translations en.json (Polish) 2024-02-03 16:28:08 +01:00
Excalidraw Bot
5cb46022fb New translations en.json (Punjabi) 2024-02-03 16:28:07 +01:00
Excalidraw Bot
afa0f83349 New translations en.json (Dutch) 2024-02-03 16:28:06 +01:00
Excalidraw Bot
a3ddac93a6 New translations en.json (Lithuanian) 2024-02-03 16:28:05 +01:00
Excalidraw Bot
6dd1406716 New translations en.json (Kurdish) 2024-02-03 16:28:04 +01:00
Excalidraw Bot
59f11650f2 New translations en.json (Korean) 2024-02-03 16:28:03 +01:00
Excalidraw Bot
fb6e93fe8e New translations en.json (Italian) 2024-02-03 16:28:02 +01:00
Excalidraw Bot
b7ddf1ef3a New translations en.json (Hungarian) 2024-02-03 16:28:01 +01:00
Excalidraw Bot
5ffc582f76 New translations en.json (Hebrew) 2024-02-03 16:28:01 +01:00
Excalidraw Bot
d025f728cc New translations en.json (Finnish) 2024-02-03 16:28:00 +01:00
Excalidraw Bot
7172c833cb New translations en.json (Basque) 2024-02-03 16:27:59 +01:00
Excalidraw Bot
e22350f745 New translations en.json (Greek) 2024-02-03 16:27:58 +01:00
Excalidraw Bot
da9319411b New translations en.json (German) 2024-02-03 16:27:57 +01:00
Excalidraw Bot
a3bd43f3b2 New translations en.json (Danish) 2024-02-03 16:27:56 +01:00
Excalidraw Bot
4d0fd858be New translations en.json (Czech) 2024-02-03 16:27:55 +01:00
Excalidraw Bot
f89325507c New translations en.json (Bulgarian) 2024-02-03 16:27:54 +01:00
Excalidraw Bot
3cafe68e2b New translations en.json (Arabic) 2024-02-03 16:27:53 +01:00
Excalidraw Bot
e9ea414849 New translations en.json (Romanian) 2024-02-03 16:27:52 +01:00
Excalidraw Bot
fef5b41bd9 New translations en.json (Galician) 2024-02-03 16:27:51 +01:00
Excalidraw Bot
7a478bd508 New translations en.json (Japanese) 2024-02-03 16:27:50 +01:00
Excalidraw Bot
bba0033900 New translations en.json (Occitan) 2024-02-03 16:27:49 +01:00
Excalidraw Bot
2e773439ce New translations en.json (Hindi) 2024-02-03 16:27:48 +01:00
Excalidraw Bot
3ff668d7ed New translations en.json (French) 2024-02-03 16:27:47 +01:00
Excalidraw Bot
1801d9efcb New translations en.json (Catalan) 2024-02-03 16:27:46 +01:00
Excalidraw Bot
ecd9d7444f New translations en.json (Spanish) 2024-02-03 16:27:45 +01:00
Excalidraw Bot
2dc2b31e36 New translations en.json (Ukrainian) 2024-02-03 16:27:45 +01:00
David Luzar
0513b647ec feat: change collab trigger & add share dialog (#7647) 2024-02-03 14:04:23 +00:00
David Luzar
a289c42830 feat: add loading state to FilledButton (#7650) 2024-02-03 14:53:31 +01:00
David Luzar
d67eaa8710 fix: file save timing out with big file sizes (#7649) 2024-02-03 11:53:35 +01:00
Excalidraw Bot
50a5886455 Auto commit: Calculate translation coverage 2024-02-02 19:30:27 +00:00
Excalidraw Bot
8d4dde8411 New translations en.json (Galician) 2024-02-02 20:30:14 +01:00
Excalidraw Bot
b6c9bd6bfc Auto commit: Calculate translation coverage 2024-02-02 17:29:48 +00:00
Excalidraw Bot
a5977368b1 New translations en.json (Occitan) 2024-02-02 18:29:35 +01:00
Aakansha Doshi
0c3dffb082 fix: make getEmbedLink independent of t function (#7643)
* fix: make getEmbedLink independent of t function

* rename warning to error and make it type safe
2024-02-01 21:12:10 +05:30
Milos Vetesnik
0e0f34edd8 fix: follow mode border for hosts apps (#7642) 2024-02-01 15:03:15 +01:00
David Luzar
4888d9d355 chore: change default port of collab server (#7641) 2024-02-01 14:41:38 +01:00
Aakansha Doshi
1c39bd5781 fix: don't bundle react and jotai when importing from scene (#7640)
* don't bundle react and jotai when importing from scene

* fix
2024-02-01 18:24:17 +05:30
Aakansha Doshi
90ad885446 feat: support onPointerUp prop (#7638)
* feat: support onPointerUp prop

* update changelog

* Update packages/excalidraw/CHANGELOG.md

Co-authored-by: David Luzar <5153846+dwelle@users.noreply.github.com>

---------

Co-authored-by: David Luzar <5153846+dwelle@users.noreply.github.com>
2024-02-01 12:26:55 +00:00
Excalidraw Bot
401281d0eb New translations en.json (Japanese) 2024-02-01 10:44:58 +01:00
Aakansha Doshi
1741c234a6 fix: decouple container cache logic to containerCache. (#7637) 2024-01-31 21:17:41 +05:30
Aakansha Doshi
63b50b3586 fix: don't bundle react-dom when importing from transformHandles (#7634)
* fix: don't bundle react when importing from transfromHandles

* rename to DEFAULT_TRANSFORM_HANDLE_SPACING
2024-01-31 16:50:35 +05:30
Aakansha Doshi
e0fefa8025 fix: don't bundle react-dom when importing from element (#7635) 2024-01-31 16:43:37 +05:30
Excalidraw Bot
f7df761f7c Auto commit: Calculate translation coverage 2024-01-31 07:13:49 +00:00
Excalidraw Bot
e690653a3a New translations en.json (Occitan) 2024-01-31 08:13:38 +01:00
Excalidraw Bot
012094d32f New translations en.json (Hindi) 2024-01-30 03:20:20 +01:00
Milos Vetesnik
d426cc968d refactor: remove portal as it is no longer needed (#7623)
Co-authored-by: dwelle <5153846+dwelle@users.noreply.github.com>
2024-01-29 16:37:09 +01:00
Excalidraw Bot
085099b770 Auto commit: Calculate translation coverage 2024-01-29 14:43:01 +00:00
Excalidraw Bot
c066a5d65a New translations en.json (French) 2024-01-29 15:42:49 +01:00
Aashir Israr
2409c091ff feat: support roundness for images (#7558)
Co-authored-by: dwelle <5153846+dwelle@users.noreply.github.com>
2024-01-29 15:27:07 +01:00
Andran1k
626fe252ab fix: frame name field (#7457)
Co-authored-by: dwelle <5153846+dwelle@users.noreply.github.com>
2024-01-29 10:57:22 +01:00
Excalidraw Bot
0bb4aa58a0 New translations en.json (Ukrainian) 2024-01-27 15:15:12 +01:00
Excalidraw Bot
3baf081831 New translations en.json (Ukrainian) 2024-01-27 14:18:19 +01:00
Excalidraw Bot
cd07cae68c Auto commit: Calculate translation coverage 2024-01-26 23:20:26 +00:00
Excalidraw Bot
f8862ff2b3 New translations en.json (Catalan) 2024-01-27 00:20:14 +01:00
Excalidraw Bot
79dd246722 New translations en.json (Ukrainian) 2024-01-26 18:01:08 +01:00
Excalidraw Bot
6ba4dd5d86 New translations en.json (Ukrainian) 2024-01-26 16:19:23 +01:00
Aakansha Doshi
10bd08ef19 fix: make getBoundTextElement and related helpers pure (#7601)
* fix: make getBoundTextElement pure

* updating args

* fix

* pass boundTextElement to getBoundTextMaxWidth

* fix labelled arrows

* lint

* pass elementsMap to removeElementsFromFrame

* pass elementsMap to getMaximumGroups, alignElements and distributeElements

* lint

* pass allElementsMap to renderElement

* lint

* feat: make more typesafe

* fix: remove unnecessary assertion

* fix: remove unused params

---------

Co-authored-by: dwelle <5153846+dwelle@users.noreply.github.com>
2024-01-26 11:29:07 +05:30
Aakansha Doshi
2789d08154 docs: update the docs for next js integration (#7605)
* docs: update the docs for next js integration

* update

* update

* update docs with tabbed examples

* fix
2024-01-25 20:26:48 +05:30
Excalidraw Bot
da4896077b Auto commit: Calculate translation coverage 2024-01-25 01:58:25 +00:00
Excalidraw Bot
0321ea248a New translations en.json (Spanish) 2024-01-25 02:58:13 +01:00
dependabot[bot]
678bb2b819 build(deps-dev): bump vite from 5.0.6 to 5.0.12 (#7586)
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 5.0.6 to 5.0.12.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/v5.0.12/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v5.0.12/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-01-24 19:29:50 +05:30
dependabot[bot]
966f9aead9 build(deps-dev): bump vite from 5.0.6 to 5.0.12 in /examples/excalidraw/with-script-in-browser (#7603)
build(deps-dev): bump vite

Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 5.0.6 to 5.0.12.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/v5.0.12/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v5.0.12/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-01-24 19:28:11 +05:30
Aakansha Doshi
4f0a2a9593 docs: add next js with app router example (#7552)
* move the existing example to with-script-in-browser

* Add example with next js app router

* disable ssr for excalidraw client comp

* typo

* update output dir

* don't include nextjs example in tsconfig

* remove meta.json

* lint

* remove example.ts

* port

* move the examples outside packages and use the deps as workspaces in examples

* update gitignore

* fix example

* update path of build dir

* fix

* fix scripts

* try local path

* fix

* update commands

* fix

* fix

* fix script

* skip ts

* disable ts

* add vercel.json

* install

* update tsconfig

* fix lint

* remove console.log

* lets see if this works

* revert

* remove ts nocheck

* add types and some utils in nextjs example

* fix types

* updatw example and remove nextjs dynamic syntax so we don't import excal twice

* move both examples to workspaces and create generic example to be used by browser and next js both

* copy the static assets to nextjs

* fix ts config

* render custom menu items

* fix custom footer

* fix types in browser example

* use regular imports for importing excal and import it using dynamic next js in app router instead

* Add example for pages router

* fix css discrepancies

* fix css

* configure output dir

* fix

* fix css

* rename to with-nextjs

* move components to examples/excalidraw/components
2024-01-24 17:07:54 +05:30
halocean96
f3f8217125 docs: toggleSidebar api fix (#7575) 2024-01-23 14:50:51 +00:00
David Luzar
89bd6181f2 fix: revert mapElementIds flag removal (#7594) 2024-01-22 17:23:00 +01:00
Aakansha Doshi
c6fdac131b ci: add the workspace ignore check to install actions as dependency for auto release (#7593) 2024-01-22 17:01:00 +05:30
David Luzar
0415c616b1 refactor: decoupling global Scene state part-1 (#7577) 2024-01-22 00:23:02 +01:00
David Luzar
740a165452 fix: filter out elements not overlapping frame on paste (#7591) 2024-01-21 20:55:57 +01:00
Ryan Di
4997624a3a fix: frame name editing inconvenience (#7437) 2024-01-21 20:55:28 +01:00
Barnabás Molnár
b66daae1f3 fix: Truncate collaborator name in dropdown. (#7576) 2024-01-21 20:36:09 +01:00
David Luzar
1e7df58b5b feat: add pasted elements to frame under cursor (#7590) 2024-01-21 14:01:43 +01:00
David Luzar
46da032626 fix: exporting frame-overlapping elements belonging to other frames (#7584) 2024-01-19 14:41:22 +01:00
みけCAT
3b0593baa7 fix: Prevent the library label from being collapsed (#7579) 2024-01-19 14:41:08 +01:00
Excalidraw Bot
07415a37c9 Auto commit: Calculate translation coverage 2024-01-17 15:48:05 +00:00
Excalidraw Bot
356eb47ca3 New translations en.json (Japanese) 2024-01-17 16:47:46 +01:00
みけCAT
dd530737a2 docs: fix "canvas actions" link in Props page (#7536)
fix "canvas actions" link in Props page
2024-01-17 16:19:42 +05:30
Aakansha Doshi
a4e5e46dd1 fix: move default to last so its compatible with nextjs (#7561) 2024-01-15 14:52:04 +05:30
Excalidraw Bot
9383e1a983 Auto commit: Calculate translation coverage 2024-01-14 21:44:10 +00:00
Excalidraw Bot
43ad9a7da9 New translations en.json (Ukrainian) 2024-01-14 22:43:59 +01:00
Excalidraw Bot
b661158a85 Auto commit: Calculate translation coverage 2024-01-14 20:35:38 +00:00
Excalidraw Bot
4d5f89fb2a New translations en.json (Norwegian Nynorsk) 2024-01-14 21:35:25 +01:00
David Luzar
0fa5f5de4c fix: translating frames containing grouped text containers (#7557) 2024-01-13 21:28:54 +01:00
David Luzar
41cc746885 fix: host font assets from root (#7548) 2024-01-11 21:29:29 +01:00
David Luzar
8ead8559e0 feat: redirect font requests to cdn (#7549) 2024-01-11 21:08:17 +01:00
David Luzar
5245276409 feat: erase groups atomically (#7545) 2024-01-11 17:43:04 +01:00
David Luzar
0c24a7042f feat: remove ExcalidrawEmbeddableElement.validated flag (#7539) 2024-01-11 17:42:51 +01:00
Are
86cfeb714c feat: add eraser tool trail (#7511)
Co-authored-by: dwelle <5153846+dwelle@users.noreply.github.com>
2024-01-11 16:10:15 +00:00
David Luzar
872973f145 fix: do not modify elements while erasing (#7531) 2024-01-11 16:00:07 +01:00
Aakansha Doshi
3ecf72a507 docs: add changelog for ESM build (#7542)
* docs: add changelog for ESM build

* move to breaking change
2024-01-11 16:40:45 +05:30
みけCAT
1aaa400876 docs: fix extra space in UIOptions/tools (#7537)
fix typo in UIOptions/tools
2024-01-11 11:09:33 +00:00
Aakansha Doshi
65047cc2cb fix: decouple react and react-dom imports from utils and make it treeshakeable (#7527)
fix: decouple react and react-dom imports from utils and make it tree-shakeable
2024-01-08 21:01:47 +05:30
Excalidraw Bot
c8d1cd6cc3 New translations en.json (Italian) 2024-01-06 20:07:42 +01:00
Excalidraw Bot
558e9382ae Auto commit: Calculate translation coverage 2024-01-06 10:54:10 +00:00
Excalidraw Bot
1ec0b25c3d New translations en.json (Romanian) 2024-01-06 11:53:58 +01:00
Excalidraw Bot
4d08a6568b Auto commit: Calculate translation coverage 2024-01-06 04:35:47 +00:00
Excalidraw Bot
2ef35fd2f8 New translations en.json (Hindi) 2024-01-06 05:35:33 +01:00
Excalidraw Bot
cc44844029 New translations en.json (Marathi) 2024-01-06 05:35:32 +01:00
Excalidraw Bot
970903992a Auto commit: Calculate translation coverage 2024-01-05 18:37:25 +00:00
Excalidraw Bot
ac160b6a18 New translations en.json (Slovak) 2024-01-05 19:37:11 +01:00
Excalidraw Bot
535a99a12f Auto commit: Calculate translation coverage 2024-01-05 08:09:35 +00:00
Excalidraw Bot
6415432eb5 New translations en.json (Chinese Simplified) 2024-01-05 09:09:23 +01:00
Excalidraw Bot
30e9692158 Auto commit: Calculate translation coverage 2024-01-04 21:12:51 +00:00
Excalidraw Bot
148bce498e New translations en.json (Portuguese) 2024-01-04 22:12:39 +01:00
Excalidraw Bot
9455b0942b Auto commit: Calculate translation coverage 2024-01-04 20:02:43 +00:00
Excalidraw Bot
a279bbb5fd New translations en.json (Portuguese, Brazilian) 2024-01-04 21:02:30 +01:00
Excalidraw Bot
3843e24ba0 New translations en.json (Portuguese) 2024-01-04 21:02:28 +01:00
Excalidraw Bot
91ada50547 Auto commit: Calculate translation coverage 2024-01-04 18:12:59 +00:00
Excalidraw Bot
c969c730a5 New translations en.json (Chinese Traditional) 2024-01-04 19:12:47 +01:00
Excalidraw Bot
560cd5ec32 New translations en.json (Russian) 2024-01-04 19:12:46 +01:00
Excalidraw Bot
186c3755e9 New translations en.json (Portuguese) 2024-01-04 19:12:45 +01:00
Excalidraw Bot
a8113203d4 New translations en.json (German) 2024-01-04 19:12:44 +01:00
David Luzar
8b993d409e feat: render embeds lazily (#7519) 2024-01-04 19:03:04 +01:00
Excalidraw Bot
2e1da33411 Auto commit: Calculate translation coverage 2024-01-04 16:21:40 +00:00
Excalidraw Bot
053dce7b8b New translations en.json (Swedish) 2024-01-04 17:21:27 +01:00
Excalidraw Bot
4941ffdcae New translations en.json (Slovenian) 2024-01-04 17:21:26 +01:00
Excalidraw Bot
845d519fc9 New translations en.json (Portuguese) 2024-01-04 17:21:25 +01:00
Excalidraw Bot
cb59638222 Auto commit: Calculate translation coverage 2024-01-04 14:48:12 +00:00
Excalidraw Bot
1cf00f8f28 New translations en.json (Karakalpak) 2024-01-04 15:46:16 +01:00
Excalidraw Bot
3138e75dfe New translations en.json (Kabyle) 2024-01-04 15:46:15 +01:00
Excalidraw Bot
c0fd470198 New translations en.json (Occitan) 2024-01-04 15:46:14 +01:00
Excalidraw Bot
44dd859a11 New translations en.json (Norwegian Bokmal) 2024-01-04 15:46:13 +01:00
Excalidraw Bot
fb207ad1d4 New translations en.json (Sinhala) 2024-01-04 15:46:11 +01:00
Excalidraw Bot
238324505f New translations en.json (Chinese Traditional, Hong Kong) 2024-01-04 15:46:09 +01:00
Excalidraw Bot
9685ac01a1 New translations en.json (Burmese) 2024-01-04 15:46:08 +01:00
Excalidraw Bot
ebf18e369b New translations en.json (Hindi) 2024-01-04 15:46:07 +01:00
Excalidraw Bot
d1663324be New translations en.json (Azerbaijani) 2024-01-04 15:46:06 +01:00
Excalidraw Bot
37e8eb1211 New translations en.json (Latvian) 2024-01-04 15:46:05 +01:00
Excalidraw Bot
d27063eea4 New translations en.json (Kazakh) 2024-01-04 15:46:04 +01:00
Excalidraw Bot
77a89d12f2 New translations en.json (Norwegian Nynorsk) 2024-01-04 15:46:03 +01:00
Excalidraw Bot
e66d7717ab New translations en.json (Thai) 2024-01-04 15:46:01 +01:00
Excalidraw Bot
828772e4f2 New translations en.json (Marathi) 2024-01-04 15:46:00 +01:00
Excalidraw Bot
087cfdfb9f New translations en.json (Bengali) 2024-01-04 15:45:59 +01:00
Excalidraw Bot
77a7cca80c New translations en.json (Tamil) 2024-01-04 15:45:58 +01:00
Excalidraw Bot
d24c875aeb New translations en.json (Khmer) 2024-01-04 15:45:57 +01:00
Excalidraw Bot
6c974d033b New translations en.json (Indonesian) 2024-01-04 15:45:56 +01:00
Excalidraw Bot
5ee8fd7448 New translations en.json (Portuguese, Brazilian) 2024-01-04 15:45:55 +01:00
Excalidraw Bot
23352dd668 New translations en.json (Galician) 2024-01-04 15:45:54 +01:00
Excalidraw Bot
60524a49be New translations en.json (Vietnamese) 2024-01-04 15:45:53 +01:00
Excalidraw Bot
76665cc7a1 New translations en.json (Chinese Traditional) 2024-01-04 15:45:52 +01:00
Excalidraw Bot
6cd8bbf5e2 New translations en.json (Ukrainian) 2024-01-04 15:45:51 +01:00
Excalidraw Bot
8602bb66ab New translations en.json (Turkish) 2024-01-04 15:45:50 +01:00
Excalidraw Bot
20d40522da New translations en.json (Swedish) 2024-01-04 15:45:48 +01:00
Excalidraw Bot
44d4e069e4 New translations en.json (Slovenian) 2024-01-04 15:45:47 +01:00
Excalidraw Bot
309790a707 New translations en.json (Russian) 2024-01-04 15:45:46 +01:00
Excalidraw Bot
8a17d6287c New translations en.json (Portuguese) 2024-01-04 15:45:45 +01:00
Excalidraw Bot
bea2193b82 New translations en.json (Polish) 2024-01-04 15:45:44 +01:00
Excalidraw Bot
3819b41865 New translations en.json (Punjabi) 2024-01-04 15:45:42 +01:00
Excalidraw Bot
52e7bab8e6 New translations en.json (Dutch) 2024-01-04 15:45:42 +01:00
Excalidraw Bot
7916134430 New translations en.json (Lithuanian) 2024-01-04 15:45:40 +01:00
Excalidraw Bot
e1944b4d45 New translations en.json (Kurdish) 2024-01-04 15:45:39 +01:00
Excalidraw Bot
7fe05e26d6 New translations en.json (Korean) 2024-01-04 15:45:38 +01:00
Excalidraw Bot
a654815139 New translations en.json (Japanese) 2024-01-04 15:45:37 +01:00
Excalidraw Bot
d7c69316f7 New translations en.json (Hungarian) 2024-01-04 15:45:35 +01:00
Excalidraw Bot
a22d237f2a New translations en.json (Hebrew) 2024-01-04 15:45:34 +01:00
Excalidraw Bot
f92acf6481 New translations en.json (Finnish) 2024-01-04 15:45:33 +01:00
Excalidraw Bot
c7adb02973 New translations en.json (Basque) 2024-01-04 15:45:32 +01:00
Excalidraw Bot
ce0ed0bdd3 New translations en.json (Greek) 2024-01-04 15:45:31 +01:00
Excalidraw Bot
3b51f9711c New translations en.json (German) 2024-01-04 15:45:30 +01:00
Excalidraw Bot
ca0f7f417b New translations en.json (Danish) 2024-01-04 15:45:29 +01:00
Excalidraw Bot
9f59e2080d New translations en.json (Czech) 2024-01-04 15:45:28 +01:00
Excalidraw Bot
1e6778ec11 New translations en.json (Catalan) 2024-01-04 15:45:27 +01:00
Excalidraw Bot
a1cdec0995 New translations en.json (Bulgarian) 2024-01-04 15:45:26 +01:00
Excalidraw Bot
6593913c7e New translations en.json (Arabic) 2024-01-04 15:45:25 +01:00
Excalidraw Bot
9fb3f7d223 New translations en.json (Spanish) 2024-01-04 15:45:24 +01:00
Excalidraw Bot
8a43bc35d7 New translations en.json (Romanian) 2024-01-04 15:45:23 +01:00
Excalidraw Bot
2e65fb9441 New translations en.json (French) 2024-01-04 15:45:22 +01:00
Excalidraw Bot
f0326c4a82 New translations en.json (Italian) 2024-01-04 15:45:21 +01:00
Excalidraw Bot
1deb577b6e New translations en.json (Persian) 2024-01-04 15:45:20 +01:00
Excalidraw Bot
60c59a9575 New translations en.json (Slovak) 2024-01-04 15:45:19 +01:00
Excalidraw Bot
fddc299b60 New translations en.json (Chinese Simplified) 2024-01-04 15:45:18 +01:00
David Luzar
1cb350b2aa feat: update X brand logo & tweak labels (#7518) 2024-01-04 14:57:31 +01:00
David Luzar
43ccc875fb feat: support multi-embed pasting & x.com domain (#7516) 2024-01-04 13:27:52 +01:00
Aakansha Doshi
4249b7dec8 chore: add version for excalidraw-app workspace (#7514) 2024-01-04 13:53:19 +05:30
Aakansha Doshi
49f15c736b chore: remove unused files (#7509)
chore remove unused files
2024-01-03 16:25:36 +05:30
Aakansha Doshi
a8064ba3ee build: Welcome ESM and Bye Bye UMD (#7441)
* build: Welcome ESM and Bye Bye UMD

* remove package

* create unbundled esm build

* update script for example

* fix typo

* dummy commit

* update autorelease script to build esm

* revert dummy commit

* move react, react-dom and testing library to dev dependencies

* remove entry.js, publicPath and yarn install:deps script

* fix

* upgrade esbuild to fix glob import error for locales

* remove webpack chunk names as thats not needed anymore

* marking the code sideeffects free

* make the library tree-shakeable and move fonts to fonts directory

* allow side effects for css, scss files

* remove tree-shaking

* comment code for tree shaking

* move to vite for example

* bye bye webpack

* ignore ts

* separate build and output dir

* use esbuild for creating bundle for example

* update output dir

* lint

* create browser dev build with source maps and prod with minification

* add dev and prod builds for bundler

* lint

* update script

* remove await

* load prod build

* create minified build in dist

* prod and dev builds using export field

* remove import.meta

* dummy

* define import.meta prod and dev

* fix

* export types

* add types field

* typo

* lint

* Update scripts/buildPackage.js

* move types inside export

* newline
2024-01-01 20:18:44 +05:30
David Luzar
e6c3c06c2e feat: support pen erasing (#7496) 2024-01-01 13:27:03 +01:00
Excalidraw Bot
892fe1917e Auto commit: Calculate translation coverage 2023-12-30 16:18:06 +00:00
Excalidraw Bot
7979b5e11c New translations en.json (French) 2023-12-30 17:17:53 +01:00
David Luzar
d19b51d4f8 fix: drawing-tablet stylus touch events being prevented (#7494) 2023-12-30 15:00:12 +01:00
David Luzar
c72e853c85 refactor: editor events sub/unsub refactor (#7483) 2023-12-30 11:12:38 +01:00
Excalidraw Bot
d5fba1e199 Auto commit: Calculate translation coverage 2023-12-23 13:08:01 +00:00
Excalidraw Bot
4629c88279 New translations en.json (Italian) 2023-12-23 14:07:47 +01:00
Excalidraw Bot
381809e1bd Auto commit: Calculate translation coverage 2023-12-23 10:34:22 +00:00
Excalidraw Bot
a06c103aa7 New translations en.json (Persian) 2023-12-23 11:34:06 +01:00
Excalidraw Bot
ae43f480d6 Auto commit: Calculate translation coverage 2023-12-22 10:38:58 +00:00
Excalidraw Bot
b7535f0b0e New translations en.json (Slovak) 2023-12-22 11:38:44 +01:00
Excalidraw Bot
9d7dd3afef New translations en.json (Slovak) 2023-12-22 09:45:33 +01:00
Excalidraw Bot
6e70165e8c Auto commit: Calculate translation coverage 2023-12-22 01:52:18 +00:00
Excalidraw Bot
b9759d2c77 New translations en.json (Chinese Simplified) 2023-12-22 02:52:03 +01:00
Excalidraw Bot
1cb3feec51 Auto commit: Calculate translation coverage 2023-12-20 17:36:37 +00:00
Excalidraw Bot
7c0f1f42f6 New translations en.json (Chinese Traditional) 2023-12-20 18:36:23 +01:00
Excalidraw Bot
4b9dae1986 Auto commit: Calculate translation coverage 2023-12-20 11:17:25 +00:00
Excalidraw Bot
8e13821456 New translations en.json (Hindi) 2023-12-20 12:17:11 +01:00
Excalidraw Bot
9ae10b66ab New translations en.json (Marathi) 2023-12-20 12:17:10 +01:00
Excalidraw Bot
f77fcc28d9 Auto commit: Calculate translation coverage 2023-12-20 06:13:39 +00:00
Excalidraw Bot
20a6bdb55c New translations en.json (Korean) 2023-12-20 07:13:22 +01:00
zsviczian
5f40a4cad4 fix: missing cross-env from build:umd in package.json (#7460) 2023-12-19 00:02:03 +01:00
Excalidraw Bot
7f4bcbe853 Auto commit: Calculate translation coverage 2023-12-18 20:50:20 +00:00
Excalidraw Bot
a7e2e053f3 New translations en.json (Russian) 2023-12-18 21:50:07 +01:00
Excalidraw Bot
c870c7adab New translations en.json (German) 2023-12-18 21:50:06 +01:00
Excalidraw Bot
9075584a3a New translations en.json (Spanish) 2023-12-18 21:50:05 +01:00
David Luzar
d91c98b82e fix: incorrect types in ActionNavigate (#7462) 2023-12-18 21:14:30 +01:00
Excalidraw Bot
00f35af572 Auto commit: Calculate translation coverage 2023-12-18 18:13:16 +00:00
Excalidraw Bot
24d5be9e8c New translations en.json (Romanian) 2023-12-18 19:13:02 +01:00
David Luzar
57ea4e61d1 fix: mixing clientId & socketId in UserList (#7461) 2023-12-18 18:21:57 +01:00
Excalidraw Bot
7b671d0d74 Auto commit: Calculate translation coverage 2023-12-18 17:05:33 +00:00
Excalidraw Bot
6ad3077c69 New translations en.json (Swedish) 2023-12-18 18:05:20 +01:00
Excalidraw Bot
4f1d578b2f New translations en.json (Slovenian) 2023-12-18 18:05:18 +01:00
Excalidraw Bot
685eb8cb50 Auto commit: Calculate translation coverage 2023-12-18 16:00:56 +00:00
Excalidraw Bot
998331f937 New translations en.json (Karakalpak) 2023-12-18 16:57:33 +01:00
Excalidraw Bot
fdd3ea29e0 New translations en.json (Kabyle) 2023-12-18 16:57:31 +01:00
Excalidraw Bot
f25781db38 New translations en.json (Occitan) 2023-12-18 16:57:30 +01:00
Excalidraw Bot
8bde613823 New translations en.json (Norwegian Bokmal) 2023-12-18 16:57:29 +01:00
Excalidraw Bot
e9db8195e0 New translations en.json (Sinhala) 2023-12-18 16:57:28 +01:00
Excalidraw Bot
944f823847 New translations en.json (Chinese Traditional, Hong Kong) 2023-12-18 16:57:27 +01:00
Excalidraw Bot
377243b07f New translations en.json (Burmese) 2023-12-18 16:57:26 +01:00
Excalidraw Bot
c86c73dd8f New translations en.json (Hindi) 2023-12-18 16:57:25 +01:00
Excalidraw Bot
4f453600db New translations en.json (Azerbaijani) 2023-12-18 16:57:24 +01:00
Excalidraw Bot
4ff1dbc8b1 New translations en.json (Latvian) 2023-12-18 16:57:23 +01:00
Excalidraw Bot
18463b79b3 New translations en.json (Kazakh) 2023-12-18 16:57:22 +01:00
Excalidraw Bot
9e19d2d166 New translations en.json (Norwegian Nynorsk) 2023-12-18 16:57:21 +01:00
Excalidraw Bot
17e9de9a53 New translations en.json (Thai) 2023-12-18 16:57:19 +01:00
Excalidraw Bot
4a0f4fc4ea New translations en.json (Marathi) 2023-12-18 16:57:18 +01:00
Excalidraw Bot
124d7a388f New translations en.json (Bengali) 2023-12-18 16:57:17 +01:00
Excalidraw Bot
0b34294156 New translations en.json (Tamil) 2023-12-18 16:57:16 +01:00
Excalidraw Bot
d296b12f0e New translations en.json (Khmer) 2023-12-18 16:57:15 +01:00
Excalidraw Bot
2d62da8dfe New translations en.json (Persian) 2023-12-18 16:57:14 +01:00
Excalidraw Bot
6115b9a808 New translations en.json (Indonesian) 2023-12-18 16:57:13 +01:00
Excalidraw Bot
e034410a91 New translations en.json (Portuguese, Brazilian) 2023-12-18 16:57:12 +01:00
Excalidraw Bot
800a609b4f New translations en.json (Galician) 2023-12-18 16:57:10 +01:00
Excalidraw Bot
ce69926f8a New translations en.json (Vietnamese) 2023-12-18 16:57:09 +01:00
Excalidraw Bot
e38a33b7b4 New translations en.json (Chinese Traditional) 2023-12-18 16:57:08 +01:00
Excalidraw Bot
95ab1256ba New translations en.json (Chinese Simplified) 2023-12-18 16:57:07 +01:00
Excalidraw Bot
f7a3dbd9f2 New translations en.json (Ukrainian) 2023-12-18 16:57:06 +01:00
Excalidraw Bot
4552db4fa1 New translations en.json (Turkish) 2023-12-18 16:57:05 +01:00
Excalidraw Bot
a33bb248a4 New translations en.json (Swedish) 2023-12-18 16:57:04 +01:00
Excalidraw Bot
2df55f0be7 New translations en.json (Slovenian) 2023-12-18 16:57:03 +01:00
Excalidraw Bot
a0094fce80 New translations en.json (Slovak) 2023-12-18 16:57:02 +01:00
Excalidraw Bot
72a525063a New translations en.json (Russian) 2023-12-18 16:57:01 +01:00
Excalidraw Bot
0484b8db51 New translations en.json (Portuguese) 2023-12-18 16:56:59 +01:00
Excalidraw Bot
c63781abe3 New translations en.json (Polish) 2023-12-18 16:56:58 +01:00
Excalidraw Bot
b496e68bf9 New translations en.json (Punjabi) 2023-12-18 16:56:57 +01:00
Excalidraw Bot
d0df605151 New translations en.json (Dutch) 2023-12-18 16:56:56 +01:00
Excalidraw Bot
0796621702 New translations en.json (Lithuanian) 2023-12-18 16:56:55 +01:00
Excalidraw Bot
d883fa7cc0 New translations en.json (Kurdish) 2023-12-18 16:56:54 +01:00
Excalidraw Bot
bf68b8b3b2 New translations en.json (Korean) 2023-12-18 16:56:53 +01:00
Excalidraw Bot
8136962237 New translations en.json (Japanese) 2023-12-18 16:56:52 +01:00
Excalidraw Bot
b8a62be016 New translations en.json (Italian) 2023-12-18 16:56:51 +01:00
Excalidraw Bot
f86bc0fab9 New translations en.json (Hungarian) 2023-12-18 16:56:50 +01:00
Excalidraw Bot
422941f260 New translations en.json (Hebrew) 2023-12-18 16:56:49 +01:00
Excalidraw Bot
b839775904 New translations en.json (Finnish) 2023-12-18 16:56:47 +01:00
Excalidraw Bot
69de41c981 New translations en.json (Basque) 2023-12-18 16:56:46 +01:00
Excalidraw Bot
037dfadbc2 New translations en.json (Greek) 2023-12-18 16:56:45 +01:00
Excalidraw Bot
d6a512f05b New translations en.json (German) 2023-12-18 16:56:44 +01:00
Excalidraw Bot
c2f83885cb New translations en.json (Danish) 2023-12-18 16:56:43 +01:00
Excalidraw Bot
4c8f41f312 New translations en.json (Czech) 2023-12-18 16:56:42 +01:00
Excalidraw Bot
93d66a7958 New translations en.json (Catalan) 2023-12-18 16:56:41 +01:00
Excalidraw Bot
8dce1413b9 New translations en.json (Bulgarian) 2023-12-18 16:56:39 +01:00
Excalidraw Bot
e4fdab7c96 New translations en.json (Arabic) 2023-12-18 16:56:38 +01:00
Excalidraw Bot
2a748aa76a New translations en.json (Spanish) 2023-12-18 16:56:37 +01:00
Excalidraw Bot
d8049f3843 New translations en.json (French) 2023-12-18 16:56:36 +01:00
Excalidraw Bot
d9edc2e30d New translations en.json (Romanian) 2023-12-18 16:56:35 +01:00
David Luzar
0808532b49 fix: follow mode collaborator status indicator (#7459) 2023-12-18 16:14:25 +01:00
Lynda Lin
2a0fe2584e fix: empty snapLines arrays would cause re-render (#7454)
Co-authored-by: Lynda Lin <lynda.lin@optoma.com>
Co-authored-by: dwelle <5153846+dwelle@users.noreply.github.com>
2023-12-18 12:42:17 +00:00
Adithyan
7bd6496854 refactor: Fix Typo (#7445) 2023-12-16 18:23:11 +00:00
Jason Praful
537f6e7f68 docs: add steps for local development (#7449)
* docs: add steps for local development #7434

* docs: minor tweaks

---------

Co-authored-by: dwelle <5153846+dwelle@users.noreply.github.com>
2023-12-16 19:18:35 +01:00
David Luzar
6dfa89e846 fix: emitted visible scene bounds not accounting for offsets (#7450) 2023-12-16 17:32:54 +01:00
David Luzar
561e919a2e fix: import Socket as type (#7446) 2023-12-16 11:15:04 +01:00
David Luzar
20e3acf7a6 feat: bump socket.io-client & collab tweaks (#7444) 2023-12-16 00:23:59 +01:00
David Luzar
2c0929e537 fix: follow-mode tweaks (#7443) 2023-12-15 15:16:25 +01:00
Barnabás Molnár
aad8ab0123 feat: follow mode (#6848)
Co-authored-by: dwelle <5153846+dwelle@users.noreply.github.com>
2023-12-15 00:07:11 +01:00
Aakansha Doshi
88a2b286c7 feat: move utils to utils package and make @excalidraw/utils a workspace (#7432)
* feat: move utils to utils package and make @excalidraw/utils a workspace

* remove esm and update types path

* remove esm script

* fix package.json and yarn.lock

* update path

* fix

* fix lint and test
2023-12-13 21:51:27 +05:30
Excalidraw Bot
f8c48e44e0 Auto commit: Calculate translation coverage 2023-12-13 11:32:16 +00:00
Excalidraw Bot
f37bc01fe7 New translations en.json (Polish) 2023-12-13 12:32:03 +01:00
Excalidraw Bot
ae460c569a Auto commit: Calculate translation coverage 2023-12-13 10:07:05 +00:00
Excalidraw Bot
1e535dd779 New translations en.json (Hindi) 2023-12-13 11:06:51 +01:00
Excalidraw Bot
ea8f5a124e New translations en.json (Marathi) 2023-12-13 11:06:49 +01:00
Excalidraw Bot
93ad17baa7 Auto commit: Calculate translation coverage 2023-12-13 06:16:20 +00:00
Excalidraw Bot
b933ddb315 New translations en.json (Marathi) 2023-12-13 07:16:04 +01:00
Excalidraw Bot
e010d12752 New translations en.json (Portuguese, Brazilian) 2023-12-13 07:16:03 +01:00
Excalidraw Bot
3e4c51ebf9 Auto commit: Calculate translation coverage 2023-12-13 05:08:26 +00:00
Excalidraw Bot
58df7cfe70 New translations en.json (Marathi) 2023-12-13 06:08:08 +01:00
Excalidraw Bot
b5ec37b698 Auto commit: Calculate translation coverage 2023-12-12 18:31:08 +00:00
Excalidraw Bot
624f17bd3c New translations en.json (German) 2023-12-12 19:30:51 +01:00
Excalidraw Bot
744525dcaf Auto commit: Calculate translation coverage 2023-12-12 15:18:00 +00:00
Excalidraw Bot
05190598bc New translations en.json (Spanish) 2023-12-12 16:17:43 +01:00
Excalidraw Bot
da6f52a155 Auto commit: Calculate translation coverage 2023-12-12 14:11:43 +00:00
Excalidraw Bot
e5d639270e New translations en.json (Slovenian) 2023-12-12 15:11:28 +01:00
Excalidraw Bot
11da1e5b30 New translations en.json (Spanish) 2023-12-12 15:11:27 +01:00
Excalidraw Bot
7cfc7c7811 Auto commit: Calculate translation coverage 2023-12-12 13:02:31 +00:00
Excalidraw Bot
cf6af5e70d New translations en.json (Chinese Traditional) 2023-12-12 14:02:16 +01:00
Excalidraw Bot
898dfff1a0 Auto commit: Calculate translation coverage 2023-12-12 11:29:53 +00:00
Excalidraw Bot
2660e4edde New translations en.json (Karakalpak) 2023-12-12 12:29:43 +01:00
Excalidraw Bot
8e05ff0c32 New translations en.json (Occitan) 2023-12-12 12:29:41 +01:00
Excalidraw Bot
c4cb94bff8 New translations en.json (Norwegian Bokmal) 2023-12-12 12:29:40 +01:00
Excalidraw Bot
10ee9c4019 New translations en.json (Hindi) 2023-12-12 12:29:37 +01:00
Excalidraw Bot
042bcf0638 New translations en.json (Azerbaijani) 2023-12-12 12:29:36 +01:00
Excalidraw Bot
8c30adaf10 New translations en.json (Norwegian Nynorsk) 2023-12-12 12:29:33 +01:00
Excalidraw Bot
2fcd49791e New translations en.json (Thai) 2023-12-12 12:29:32 +01:00
Excalidraw Bot
ae0c96b66c New translations en.json (Marathi) 2023-12-12 12:29:31 +01:00
Excalidraw Bot
c195bb0739 New translations en.json (Tamil) 2023-12-12 12:29:29 +01:00
Excalidraw Bot
6de5305e72 New translations en.json (Khmer) 2023-12-12 12:29:28 +01:00
Excalidraw Bot
ca1d426fc0 New translations en.json (Persian) 2023-12-12 12:29:27 +01:00
Excalidraw Bot
4fd311364a New translations en.json (Indonesian) 2023-12-12 12:29:26 +01:00
Excalidraw Bot
9d6180e2fd New translations en.json (Portuguese, Brazilian) 2023-12-12 12:29:25 +01:00
Excalidraw Bot
eeeb7e4ed9 New translations en.json (Galician) 2023-12-12 12:29:24 +01:00
Excalidraw Bot
9c248e8ae9 New translations en.json (Vietnamese) 2023-12-12 12:29:23 +01:00
Excalidraw Bot
d579328746 New translations en.json (Chinese Traditional) 2023-12-12 12:29:22 +01:00
Excalidraw Bot
3b3cfc391e New translations en.json (Chinese Simplified) 2023-12-12 12:29:21 +01:00
Excalidraw Bot
222fa328ba New translations en.json (Ukrainian) 2023-12-12 12:29:20 +01:00
Excalidraw Bot
a83498fc61 New translations en.json (Turkish) 2023-12-12 12:29:19 +01:00
Excalidraw Bot
0bd531b612 New translations en.json (Swedish) 2023-12-12 12:29:18 +01:00
Excalidraw Bot
b9b35833d3 New translations en.json (Slovenian) 2023-12-12 12:29:16 +01:00
Excalidraw Bot
eac2a23d72 New translations en.json (Slovak) 2023-12-12 12:29:15 +01:00
Excalidraw Bot
641a766607 New translations en.json (Russian) 2023-12-12 12:29:14 +01:00
Excalidraw Bot
bf38bd6620 New translations en.json (Portuguese) 2023-12-12 12:29:13 +01:00
Excalidraw Bot
775e551c3d New translations en.json (Polish) 2023-12-12 12:29:12 +01:00
Excalidraw Bot
909cc53c3a New translations en.json (Punjabi) 2023-12-12 12:29:11 +01:00
Excalidraw Bot
99e5542f03 New translations en.json (Dutch) 2023-12-12 12:29:10 +01:00
Excalidraw Bot
96b8340210 New translations en.json (Kurdish) 2023-12-12 12:29:08 +01:00
Excalidraw Bot
f92d025434 New translations en.json (Korean) 2023-12-12 12:29:07 +01:00
Excalidraw Bot
bbbed516f2 New translations en.json (Japanese) 2023-12-12 12:29:06 +01:00
Excalidraw Bot
c86a878a75 New translations en.json (Italian) 2023-12-12 12:29:05 +01:00
Excalidraw Bot
6676f24c4f New translations en.json (Hungarian) 2023-12-12 12:29:04 +01:00
Excalidraw Bot
e2e336bd95 New translations en.json (Basque) 2023-12-12 12:29:01 +01:00
Excalidraw Bot
c5ec66e585 New translations en.json (Greek) 2023-12-12 12:29:00 +01:00
Excalidraw Bot
a0c7aae672 New translations en.json (German) 2023-12-12 12:28:59 +01:00
Excalidraw Bot
95c8418dee New translations en.json (Danish) 2023-12-12 12:28:58 +01:00
Excalidraw Bot
21f5934e44 New translations en.json (Czech) 2023-12-12 12:28:57 +01:00
Excalidraw Bot
d6e2936bf8 New translations en.json (Catalan) 2023-12-12 12:28:56 +01:00
Excalidraw Bot
0aa1b62108 New translations en.json (Bulgarian) 2023-12-12 12:28:55 +01:00
Excalidraw Bot
c7c41155f6 New translations en.json (Arabic) 2023-12-12 12:28:54 +01:00
Excalidraw Bot
492a643506 New translations en.json (Spanish) 2023-12-12 12:28:52 +01:00
Excalidraw Bot
1cc8ad6ed9 New translations en.json (French) 2023-12-12 12:28:51 +01:00
Excalidraw Bot
8f57c10d9b New translations en.json (Romanian) 2023-12-12 12:28:50 +01:00
Excalidraw Bot
b635b10b59 chore: Update translations from Crowdin (#7176)
* New translations en.json (Azerbaijani)

* New translations en.json (Hindi)

* New translations en.json (Burmese)

* New translations en.json (Chinese Traditional, Hong Kong)

* New translations en.json (Sinhala)

* New translations en.json (Norwegian Bokmal)

* New translations en.json (Occitan)

* New translations en.json (Kabyle)

* New translations en.json (Karakalpak)

* Auto commit: Calculate translation coverage

* New translations en.json (Chinese Simplified)

* Auto commit: Calculate translation coverage

* New translations en.json (Marathi)

* New translations en.json (Hindi)

* Auto commit: Calculate translation coverage

* New translations en.json (Marathi)

* New translations en.json (Hindi)

* Auto commit: Calculate translation coverage

* New translations en.json (German)

* New translations en.json (Slovenian)

* Auto commit: Calculate translation coverage

* New translations en.json (Korean)

* Auto commit: Calculate translation coverage

* New translations en.json (Chinese Traditional)

* Auto commit: Calculate translation coverage

* New translations en.json (Russian)

* Auto commit: Calculate translation coverage

* New translations en.json (Romanian)

* New translations en.json (Spanish)

* Auto commit: Calculate translation coverage

* New translations en.json (Arabic)

* New translations en.json (Thai)

* New translations en.json (Romanian)

* New translations en.json (French)

* New translations en.json (Spanish)

* New translations en.json (Bulgarian)

* New translations en.json (Catalan)

* New translations en.json (Czech)

* New translations en.json (Danish)

* New translations en.json (German)

* New translations en.json (Greek)

* New translations en.json (Basque)

* New translations en.json (Finnish)

* New translations en.json (Hebrew)

* New translations en.json (Hungarian)

* New translations en.json (Italian)

* New translations en.json (Japanese)

* New translations en.json (Korean)

* New translations en.json (Kurdish)

* New translations en.json (Lithuanian)

* New translations en.json (Dutch)

* New translations en.json (Punjabi)

* New translations en.json (Polish)

* New translations en.json (Portuguese)

* New translations en.json (Russian)

* New translations en.json (Slovak)

* New translations en.json (Slovenian)

* New translations en.json (Swedish)

* New translations en.json (Turkish)

* New translations en.json (Ukrainian)

* New translations en.json (Chinese Simplified)

* New translations en.json (Chinese Traditional)

* New translations en.json (Vietnamese)

* New translations en.json (Galician)

* New translations en.json (Portuguese, Brazilian)

* New translations en.json (Indonesian)

* New translations en.json (Persian)

* New translations en.json (Khmer)

* New translations en.json (Tamil)

* New translations en.json (Bengali)

* New translations en.json (Marathi)

* New translations en.json (Norwegian Nynorsk)

* New translations en.json (Kazakh)

* New translations en.json (Latvian)

* New translations en.json (Azerbaijani)

* New translations en.json (Hindi)

* New translations en.json (Burmese)

* New translations en.json (Chinese Traditional, Hong Kong)

* New translations en.json (Sinhala)

* New translations en.json (Norwegian Bokmal)

* New translations en.json (Occitan)

* New translations en.json (Kabyle)

* New translations en.json (Karakalpak)

* Auto commit: Calculate translation coverage

* New translations en.json (Slovenian)

* Auto commit: Calculate translation coverage

* New translations en.json (Chinese Simplified)

* Auto commit: Calculate translation coverage

* New translations en.json (German)

* Auto commit: Calculate translation coverage

* New translations en.json (Russian)

* Auto commit: Calculate translation coverage

* New translations en.json (Polish)

* New translations en.json (Korean)

* Auto commit: Calculate translation coverage

* New translations en.json (Swedish)

* Auto commit: Calculate translation coverage

* New translations en.json (Swedish)

* Auto commit: Calculate translation coverage

* New translations en.json (French)

* Auto commit: Calculate translation coverage

* New translations en.json (Romanian)

* Auto commit: Calculate translation coverage

* New translations en.json (Chinese Simplified)

* New translations en.json (Catalan)

* Auto commit: Calculate translation coverage

* New translations en.json (Basque)

* Auto commit: Calculate translation coverage

* New translations en.json (Chinese Traditional)

* Auto commit: Calculate translation coverage

* New translations en.json (Spanish)

* Auto commit: Calculate translation coverage

* New translations en.json (Arabic)

* New translations en.json (Thai)

* New translations en.json (Romanian)

* New translations en.json (French)

* New translations en.json (Spanish)

* New translations en.json (Bulgarian)

* New translations en.json (Catalan)

* New translations en.json (Czech)

* New translations en.json (Danish)

* New translations en.json (German)

* New translations en.json (Greek)

* New translations en.json (Basque)

* New translations en.json (Finnish)

* New translations en.json (Hebrew)

* New translations en.json (Hungarian)

* New translations en.json (Italian)

* New translations en.json (Japanese)

* New translations en.json (Korean)

* New translations en.json (Kurdish)

* New translations en.json (Lithuanian)

* New translations en.json (Dutch)

* New translations en.json (Punjabi)

* New translations en.json (Polish)

* New translations en.json (Portuguese)

* New translations en.json (Russian)

* New translations en.json (Slovak)

* New translations en.json (Slovenian)

* New translations en.json (Swedish)

* New translations en.json (Turkish)

* New translations en.json (Ukrainian)

* New translations en.json (Chinese Simplified)

* New translations en.json (Chinese Traditional)

* New translations en.json (Vietnamese)

* New translations en.json (Galician)

* New translations en.json (Portuguese, Brazilian)

* New translations en.json (Indonesian)

* New translations en.json (Persian)

* New translations en.json (Khmer)

* New translations en.json (Tamil)

* New translations en.json (Bengali)

* New translations en.json (Marathi)

* New translations en.json (Norwegian Nynorsk)

* New translations en.json (Kazakh)

* New translations en.json (Latvian)

* New translations en.json (Azerbaijani)

* New translations en.json (Hindi)

* New translations en.json (Burmese)

* New translations en.json (Chinese Traditional, Hong Kong)

* New translations en.json (Sinhala)

* New translations en.json (Norwegian Bokmal)

* New translations en.json (Occitan)

* New translations en.json (Kabyle)

* New translations en.json (Karakalpak)

* Auto commit: Calculate translation coverage

* New translations en.json (Romanian)

* New translations en.json (Spanish)

* Auto commit: Calculate translation coverage

* New translations en.json (Slovenian)

* Auto commit: Calculate translation coverage

* New translations en.json (Chinese Traditional)

* Auto commit: Calculate translation coverage

* New translations en.json (Swedish)

* Auto commit: Calculate translation coverage

* New translations en.json (French)

* Auto commit: Calculate translation coverage

* New translations en.json (German)

* Auto commit: Calculate translation coverage

* New translations en.json (Danish)

* Auto commit: Calculate translation coverage

* New translations en.json (Italian)

* Auto commit: Calculate translation coverage

* New translations en.json (Chinese Simplified)

* Auto commit: Calculate translation coverage

* New translations en.json (Korean)

* Auto commit: Calculate translation coverage

* New translations en.json (Polish)

* New translations en.json (Slovak)

* Auto commit: Calculate translation coverage

* New translations en.json (Karakalpak)

* Auto commit: Calculate translation coverage

* New translations en.json (Romanian)

* New translations en.json (French)

* New translations en.json (Spanish)

* New translations en.json (Arabic)

* New translations en.json (Bulgarian)

* New translations en.json (Catalan)

* New translations en.json (Czech)

* New translations en.json (Danish)

* New translations en.json (German)

* New translations en.json (Greek)

* New translations en.json (Basque)

* New translations en.json (Finnish)

* New translations en.json (Hebrew)

* New translations en.json (Hungarian)

* New translations en.json (Italian)

* New translations en.json (Japanese)

* New translations en.json (Korean)

* New translations en.json (Kurdish)

* New translations en.json (Lithuanian)

* New translations en.json (Dutch)

* New translations en.json (Punjabi)

* New translations en.json (Polish)

* New translations en.json (Portuguese)

* New translations en.json (Russian)

* New translations en.json (Slovak)

* New translations en.json (Slovenian)

* New translations en.json (Swedish)

* New translations en.json (Turkish)

* New translations en.json (Ukrainian)

* New translations en.json (Chinese Simplified)

* New translations en.json (Chinese Traditional)

* New translations en.json (Vietnamese)

* New translations en.json (Galician)

* New translations en.json (Portuguese, Brazilian)

* New translations en.json (Indonesian)

* New translations en.json (Persian)

* New translations en.json (Khmer)

* New translations en.json (Tamil)

* New translations en.json (Bengali)

* New translations en.json (Marathi)

* New translations en.json (Thai)

* New translations en.json (Norwegian Nynorsk)

* New translations en.json (Kazakh)

* New translations en.json (Latvian)

* New translations en.json (Azerbaijani)

* New translations en.json (Hindi)

* New translations en.json (Burmese)

* New translations en.json (Chinese Traditional, Hong Kong)

* New translations en.json (Sinhala)

* New translations en.json (Norwegian Bokmal)

* New translations en.json (Occitan)

* New translations en.json (Kabyle)

* New translations en.json (Karakalpak)

* New translations en.json (Swedish)

* New translations en.json (Romanian)

* remove packages

---------

Co-authored-by: Aakansha Doshi <aakansha1216@gmail.com>
2023-12-12 16:56:22 +05:30
Aakansha Doshi
7ebda02b81 fix: update path of files in docs (#7428)
* fix: update path of files in docs

* remove root yarn install in size limit

* add vercel.json in dev-docs

* update config

* fix lint

* indent

* revert changelog and readme
2023-12-12 14:28:34 +05:30
Aakansha Doshi
d6cd8b78f1 build: decouple package deps and introduce yarn workspaces (#7415)
* feat: decouple package deps and introduce yarn workspaces

* update root directory

* fix

* fix scripts

* fix lint

* update path in scripts

* remove yarn.lock files from packages

* ignore workspace

* dummy

* dummy

* remove comment check

* revert workflow changes

* ignore ws when installing gh actions

* remove log

* update path

* fix

* fix typo
2023-12-12 11:32:51 +05:30
Aakansha Doshi
b7d7ccc929 fix: env variable for text-to-diagram and use frozen lock file when install deps in excalidraw-app (#7409) 2023-12-07 19:32:19 +05:30
Aakansha Doshi
f14ad61bd0 build: move build process and excalidraw-app dependencies in its own package.json (#7021)
* build: move build process and excalidraw-app dependencies in its own package.json

* fix

* fix public path

* move bug-issue-template to excalidraw-app

* make env vars accessible in excalidraw app

* update build script

* install when building

* add ts ignore

* fix build-version script

* update config in vercel.json

* add vercel config for example

* fix vercel config

* update install script in vercel

* update install script in lint.yml

* update install script in test workflows

* push locales to locales folder pwa

* add favicons to manifest

* move react to peer deps in editor

* fix ts

* Enable vite intellisense

* add global.d.ts for excalidraw-app

* remove console.log

* remove react, react-dom and vite from excalidraw-app deps

* increase size limit
2023-12-07 16:39:11 +05:30
Aakansha Doshi
8963baf5ad chore: upgrade to vite 5.x and vitest 1.x (#7407)
* chore: upgrade to vite 5.x and vitest 1.x

* fix coverage

* move to ESM for vite config

* use ESM for vitest
2023-12-07 15:30:08 +05:30
Aakansha Doshi
557add5bf7 feat: Support Mermaid Class diagrams 🥳 (#7381)
* feat: support mermaid class diagrams

* upgrade mermaid-to-excalidraw

* upgrade mermaid-to-excalidraw

* add sequence diagrams in supported chart types

* upgrade mermaid-to-excalidraw

* update i18n
2023-12-06 21:31:54 +05:30
David Luzar
b9cfbc2077 feat: add support for more UML arrowheads (#7391) 2023-12-06 16:00:00 +01:00
dependabot[bot]
a04cc707c3 build(deps-dev): bump vite from 4.4.2 to 4.4.12 (#7393)
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 4.4.2 to 4.4.12.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/v4.4.12/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v4.4.12/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-12-06 15:31:44 +05:30
Vaibhav Shukla
72ea8022bf docs: changelog instruction removed from docs (#7395)
changelog instruction removed from docs
2023-12-06 11:36:39 +05:30
David Luzar
4bdeaf999b feat: TTD dialog UI tweaks (#7384) 2023-12-04 17:50:30 +01:00
Aakansha Doshi
42d8c5a040 chore: update changelog and package.json for v0.17.1 (#7351) 2023-11-28 19:12:39 +05:30
Aakansha Doshi
f299514e44 fix: umd build so it can be used in browser (#7349)
* fix: umd build so it can be used in browser

* fix lint

* increase size limit

* update changelog

* use json.stringify for env preact variable so its accessible as string

* update changelog
2023-11-28 18:11:16 +05:30
David Luzar
dd220bcaea feat: TTD dialog tweaks (#7346)
* tweaks to TTD dialog ~ prepping for settings dialog

* tweaks to ttd parsing & error logging
2023-11-27 16:03:03 +01:00
David Luzar
fe75f29c15 fix: disable caching bounds for arrow labels (#7343) 2023-11-25 23:32:05 +01:00
Barnabás Molnár
14845a343b feat: text-to-diagram (#7325)
Co-authored-by: dwelle <5153846+dwelle@users.noreply.github.com>
2023-11-25 21:11:03 +00:00
David Luzar
dd8a7d41e2 fix: bounds cached prematurely resulting in incorrectly rendered labels (#7339) 2023-11-24 19:55:56 +01:00
David Luzar
fda5c6fdf7 fix: t2c settings dialog spacing for apps that use CSS resets (#7337) 2023-11-24 16:32:00 +01:00
David Luzar
3d1631f375 feat: d2c tweaks (#7336) 2023-11-24 14:02:11 +01:00
David Luzar
c7ee46e7f8 feat: wireframe-to-code (#7334) 2023-11-23 23:07:53 +01:00
DanielJGeiger
d1e4421823 feat: Expose ActionManager.registerAction through ExcalidrawImperativeAPI (#6995)
* feat: Expose `ActionManager` through `ExcalidrawImperativeAPI`

* Only expose `registerAction` instead of `ActionManager`
2023-11-22 15:22:49 -06:00
Barnabás Molnár
7c9cf30909 fix: make zoomToFit fitToViewport account for sidebar (#7298) 2023-11-17 15:56:19 +01:00
David Luzar
1e37dbd60e feat: change frame resizing behavior (#7307) 2023-11-17 14:37:43 +01:00
David Luzar
f8d5c2a1b6 build: allow a range of major node versions (#7306) 2023-11-17 14:23:19 +01:00
Aakansha Doshi
23b24ea5c3 build: use caret for specifying node version to avoid major upgrades automatically (#7297) 2023-11-16 16:18:38 +05:30
Aakansha Doshi
a528769b68 docs: upgrade to @excalidraw/excalidraw@0.17.0 (#7285) 2023-11-14 20:10:19 +05:30
Aakansha Doshi
ddb7585057 docs: Docs for v0.17.0 🚀 (#7248)
* feat: add docs for getCommonBounds

* docs: add docs for frames api support

* docs: update docs for regenerateIds opts in convertToExcalidrawElements

* add docs for ref removal

* add docs for lock support and insertOnCanvasDirectly in setActiveTool

* fix broken links

* update docs for next js support

* update docs for Preact

* add faq

* docs: add `onChange`, `onPointerDown`, `onPointerUp` docs

* docs: update `useDevice` docs

* update docs for disabling image tool

* add docs for withinBounds helpers

* fix lint

* upgrade excal

* add docusaurus2-dotenv for expose env vars

* fix env variable and upgrade excal

* Update dev-docs/docs/@excalidraw/excalidraw/api/excalidraw-element-skeleton.mdx

Co-authored-by: David Luzar <5153846+dwelle@users.noreply.github.com>

* update docs

Co-authored-by: David Luzar <5153846+dwelle@users.noreply.github.com>

* update docs for process.env

---------

Co-authored-by: dwelle <5153846+dwelle@users.noreply.github.com>
2023-11-14 19:54:34 +05:30
Aakansha Doshi
111a48ffb1 docs: release @excalidraw/excalidraw@0.17.0 🎉 (#7284) 2023-11-14 19:53:59 +05:30
Aakansha Doshi
54153629c0 chore: update release scripts (#7282)
* chore: update release scripts

* update docs
2023-11-14 16:37:57 +05:30
David Luzar
9c425224c7 feat: support disabling image tool (#6320)
Co-authored-by: Aakansha Doshi <aakansha1216@gmail.com>
2023-11-14 10:25:41 +01:00
Aakansha Doshi
9d1d45a8ea chore: update changelog (#7279)
* chore: update changelog

* fix

* Update CHANGELOG.md
2023-11-14 13:11:05 +05:30
David Luzar
029c3c48ba fix: image insertion bugs (#7278) 2023-11-13 15:34:59 +01:00
Aakansha Doshi
adfd95be33 build: support preact 🥳 (#7255)
* build: support preact

* add log

* Simplify the config and generate prod and dev builds for preact

* update changelog

* remove logs

* use env variable so its available during build time

* update cl

* fix
2023-11-13 16:18:36 +05:30
zsviczian
ceb255e8ee fix: exportToSvg to honor frameRendering also for name not only for frame itself (#7270)
Co-authored-by: dwelle <5153846+dwelle@users.noreply.github.com>
2023-11-12 22:34:05 +00:00
David Luzar
ae5b9a4ffd fix: not cloning elements on export polluting Scene mapping (#7276) 2023-11-12 23:32:12 +01:00
zsviczian
3d4ff59f40 fix: Can't toggle penMode off due to missing typecheck in togglePenMode (#7273)
Co-authored-by: dwelle <5153846+dwelle@users.noreply.github.com>
2023-11-12 13:24:13 +01:00
David Luzar
7b00089314 chore: bump @excalidraw/random-username (#7272) 2023-11-11 19:23:22 +01:00
zsviczian
af6b81df40 fix: Replace hard coded font family with const value in addFrameLabelsAsTextElements (#7269) 2023-11-11 10:04:02 +01:00
FilBot3
02cc8440c4 feat: allow D&D dice app domain for embeds (#7263)
Co-authored-by: David Luzar <5153846+dwelle@users.noreply.github.com>
2023-11-10 15:29:19 +00:00
David Luzar
6363492cee fix: perf issue when ungrouping elements within frame (#7265)
Co-authored-by: Ryan Di <ryan.weihao.di@gmail.com>
2023-11-10 16:13:08 +01:00
Sahil Nagpure
900b317bf3 feat: remove full screen shortcut (#7222) 2023-11-10 14:44:02 +00:00
Gabriel Lalonde
68179356e6 fix: Fixes the shortcut collision between "toggleHandTool" and "distributeHorizontally" (#7189)
Co-authored-by: dwelle <5153846+dwelle@users.noreply.github.com>
2023-11-10 15:33:02 +01:00
Jan-Peter Dhallé
3ed15e95da Small typo fix frames.mdx (#7216) 2023-11-10 15:23:43 +01:00
zsviczian
798e1fd858 fix: allow pointer events when editing a linear element (#7238) 2023-11-10 15:21:59 +01:00
David Luzar
f66c93633c feat: make adaptive-roughness less aggressive (#7250) 2023-11-10 13:32:34 +01:00
Aakansha Doshi
cee00767df feat: support excalidrawAPI and remove refs support (#7251)
* feat: support excalidrawAPI and remove refs support

* update changelog

* remove ready and readyPromise

* update changelog

* update changelog
2023-11-10 15:33:43 +05:30
David Luzar
864c0b3ea8 feat: render frames on export (#7210) 2023-11-09 17:00:21 +01:00
Aakansha Doshi
a9a6f8eafb docs: update the docs with next js dynamic import support (#7252) 2023-11-09 16:03:35 +05:30
David Luzar
3c96943db3 test: fix mermaid test flake (#7249) 2023-11-07 18:06:15 +01:00
David Luzar
9006caff39 fix: make modal use viewport breakpoints (#7246) 2023-11-07 10:10:12 +01:00
Aakansha Doshi
ce7a847668 feat: export getCommonBounds util (#7247)
* feat: export getCommonBounds util

* add pr link

* fix
2023-11-07 14:19:13 +05:30
David Luzar
b1037b342d feat: make device breakpoints more specific (#7243) 2023-11-06 16:29:00 +01:00
Dante Calderon
18a7b97515 chore: Fix typo in comment in LocalData file (#7235) 2023-11-04 18:15:09 +01:00
Aakansha Doshi
e8def8da8d feat: Support mermaid flowchart and sequence diagrams to excalidraw diagrams 🥳 (#6920)
* feat: integrate mermaidToExcalidraw

* create mermaid to excal dialog

* allow mermaid syntax and export in preview

* fix

* fix webpack config

* fix markdown error by using named export

* center preview

* set elements as selected when inserted onto canvas

* persist mermaid data to storage

* store canvas data in refs

* load mermaid lazily

* tweak design

* compute width, height correctly for arrows

* fix undefined vertex issue

* add mermaid icon in dropdown

* add a note in dialog

* reset preview when error

* show error in preview when error

* show mermaid error messgae react way

* design tweaks

* add example and docs link

* fix

* tweak design to remove scroll bar

* show a spinner unless mermaid loaded

* regenerate ids when needed via programmatic api, this makes sure for mermaid diagrams ids are regenerated

* tweak

* add option to transform viewport to scene coords in transform api

* make opts optional and use 100% zoom when inserting to canvas

* fix arrow bindings in safari and firefox

* fix elements insert position and viewport centering

* fix: Update start/end points by 0.5 so bindings don't overlap with start/end bound element coordinates.

* defer rendering the preview

* tweak text

* fix tests

* remove only

* make design responsive

* fix: show extra tools dropdown in mobile

* fix mobile css

* width auto

* upgrade mermaid-to-excalidraw

* don't pass appState in deps as its not used

* upgrade mermaid-to-excalidraw to fix firefox issue

* use types from mermaid-to-excalidraw

* upgrade mermaid-to-excalidraw

* use stable version of mermaid-to-excalidraw

* upgrade mermaid-to-excalidraw

* fix width of shapes toolbar for smaller screen size and also fix regression of mobile menu

* use i18n

* better api

* enable test coverage in ui

* Add tests

* use common utils to update and get text editor

* updgrade mermaid-to-excalidraw to support sequence diagrams

* fix test

* don't update arrow container height anytime in when redrawing text bounding box

* increase size limit

* increase size limit of vendor to 900kb

* use openDialog for mermaid

* upgrade mermaid-to-excalidraw

* update frame id post generation

* upgrade mermaid-to-excalidraw to add entity codes support

* update size limit

* upgrade mermaid-to-excalidraw package with frame api changes

* upgrade mermaid-to-excalidraw to remove directive and use config

* don't highlight mermaid tool and remove unused api setSelection

* stop using loading state to update text area

* move some styling to scss

* review fixes

* use modifiedTableIcon props and remove stale snap

* css

* dialog css

* fix snap

* use dialog border

* change mermaidToExcalidrawLib to state

* better styling of errors

* make modal bigger

* fix mobile

* update snaps

* fix icon color

* fix dark mode insert button color

* horizontally center spinner

* render canvas conditionally on loaded state

* rd tweaks

* tweak class names

* remove max height

* typo in example

* upgrade mermaid-to-excalidraw

* simplify error state

* fix height & overflow on vertical breakpoint

* fix lint

* show errors in overlay

* set textarea font family

* reduce opacity

* update snap

* upgrade to mermaid  0.1.2

---------

Co-authored-by: dwelle <luzar.david@gmail.com>
2023-11-03 17:41:34 +05:30
David Luzar
a7db41c5ba fix: align input :hover/:focus with spec (#7225) 2023-11-02 16:06:26 +01:00
David Luzar
d8166d9e1d fix: dialog remounting on className updates (#7224) 2023-11-02 16:06:15 +01:00
Farzaneh Sefidabi
81c0259041 docs: add npm downloads rate badge to README.md file (#7127) 2023-11-01 13:27:57 +01:00
Aakansha Doshi
f5c91c3a0f feat: support frames via programmatic API (#7205)
* update frame id post generation

* support frames via programmatic API

* fix types

* add test for frames

* throw error when element doesn't exist

* naming tweaks

* update the api to use children

* consider max of frame dimensions and calculated bounds of elements

* consider bound elements in frame api
2023-11-01 17:14:04 +05:30
David Luzar
9b8de8a12e test: disable flaky test (#7213) 2023-10-31 12:05:08 +01:00
David Luzar
ea677d4581 feat: make clipboard more robust and reintroduce contextmenu actions (#7198) 2023-10-28 19:29:28 +00:00
Aakansha Doshi
ec2de7205f fix: don't update label position when dragging labelled arrows (#6891)
* fix: don't update label position when dragging labelled arrows

* lint

* add test

* don't update coords for label when labelled arrow inside frame

* increase locales bundle size limit
2023-10-27 12:06:11 +05:30
Are
d5e3f436dc feat: add approximate elements in bbox detection (#6727)
Co-authored-by: dwelle <luzar.david@gmail.com>
2023-10-26 23:33:00 +02:00
Aakansha Doshi
dcf4592e79 feat: regenerate ids by default when using transform api and also update bindings by 0.5px to avoid possible overlapping (#7195)
* feat: regenerate ids by default when using transform api and also update bindings by 0.5px to avoid possible overlapping

* type

* increase limit as some past PR(s) increased the bundle size

* review fixes

* update changelog
2023-10-27 00:43:48 +05:30
David Luzar
d1f8eec174 feat: support giphy.com embed domain (#7192) 2023-10-26 00:00:50 +02:00
David Luzar
0f81c30276 fix: frame add/remove/z-index ordering changes (#7194) 2023-10-25 23:16:02 +02:00
zsviczian
f098789d16 fix: element relative position when dragging multiple elements on grid (#7107)
Co-authored-by: dwelle <luzar.david@gmail.com>
2023-10-25 22:48:03 +02:00
David Luzar
f794b0bb90 fix: freedraw non-solid bg hitbox not working (#7193) 2023-10-25 17:21:01 +02:00
David Luzar
104f64f1dc revert: remove bound-arrows from frames (#7190) 2023-10-25 10:39:19 +02:00
Viczián András
71ad3c5356 fix: Actions panel ux improvement (#6850)
Co-authored-by: dwelle <luzar.david@gmail.com>
2023-10-24 18:36:13 +00:00
709 changed files with 52467 additions and 25359 deletions

View File

@@ -6,6 +6,6 @@
!.prettierrc
!package.json
!public/
!src/
!packages/
!tsconfig.json
!yarn.lock

View File

@@ -7,12 +7,11 @@ VITE_APP_LIBRARY_BACKEND=https://us-central1-excalidraw-room-persistence.cloudfu
# collaboration WebSocket server (https://github.com/excalidraw/excalidraw-room)
VITE_APP_WS_SERVER_URL=http://localhost:3002
# set this only if using the collaboration workflow we use on excalidraw.com
VITE_APP_PORTAL_URL=
VITE_APP_PLUS_LP=https://plus.excalidraw.com
VITE_APP_PLUS_APP=https://app.excalidraw.com
VITE_APP_AI_BACKEND=http://localhost:3015
VITE_APP_FIREBASE_CONFIG='{"apiKey":"AIzaSyCMkxA60XIW8KbqMYL7edC4qT5l4qHX2h8","authDomain":"excalidraw-oss-dev.firebaseapp.com","projectId":"excalidraw-oss-dev","storageBucket":"excalidraw-oss-dev.appspot.com","messagingSenderId":"664559512677","appId":"1:664559512677:web:a385181f2928d328a7aa8c"}'
# put these in your .env.local, or make sure you don't commit!

View File

@@ -4,14 +4,13 @@ VITE_APP_BACKEND_V2_POST_URL=https://json.excalidraw.com/api/v2/post/
VITE_APP_LIBRARY_URL=https://libraries.excalidraw.com
VITE_APP_LIBRARY_BACKEND=https://us-central1-excalidraw-room-persistence.cloudfunctions.net/libraries
VITE_APP_PORTAL_URL=https://portal.excalidraw.com
VITE_APP_PLUS_LP=https://plus.excalidraw.com
VITE_APP_PLUS_APP=https://app.excalidraw.com
# Fill to set socket server URL used for collaboration.
# Meant for forks only: excalidraw.com uses custom VITE_APP_PORTAL_URL flow
VITE_APP_WS_SERVER_URL=
VITE_APP_AI_BACKEND=https://oss-ai.excalidraw.com
# socket server URL used for collaboration
VITE_APP_WS_SERVER_URL=https://oss-collab.excalidraw.com
VITE_APP_FIREBASE_CONFIG='{"apiKey":"AIzaSyAd15pYlMci_xIp9ko6wkEsDzAAA0Dn0RU","authDomain":"excalidraw-room-persistence.firebaseapp.com","databaseURL":"https://excalidraw-room-persistence.firebaseio.com","projectId":"excalidraw-room-persistence","storageBucket":"excalidraw-room-persistence.appspot.com","messagingSenderId":"654800341332","appId":"1:654800341332:web:4a692de832b55bd57ce0c1"}'

View File

@@ -5,4 +5,4 @@ package-lock.json
firebase/
dist/
public/workbox
src/packages/excalidraw/types
packages/excalidraw/types

View File

@@ -23,5 +23,5 @@ jobs:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
- name: Auto release
run: |
yarn add @actions/core
yarn add @actions/core -W
yarn autorelease

View File

@@ -44,7 +44,7 @@ jobs:
- name: Auto release preview
id: "autorelease"
run: |
yarn add @actions/core
yarn add @actions/core -W
yarn autorelease preview ${{ github.event.issue.number }}
- name: Post comment post release
if: always()

View File

@@ -16,7 +16,7 @@ jobs:
- name: Install and lint
run: |
yarn --frozen-lockfile
yarn install
yarn test:other
yarn test:code
yarn test:typecheck

View File

@@ -22,11 +22,11 @@ jobs:
- name: Create report file
run: |
yarn locales-coverage
FILE_CHANGED=$(git diff src/locales/percentages.json)
FILE_CHANGED=$(git diff packages/excalidraw/locales/percentages.json)
if [ ! -z "${FILE_CHANGED}" ]; then
git config --global user.name 'Excalidraw Bot'
git config --global user.email 'bot@excalidraw.com'
git add src/locales/percentages.json
git add packages/excalidraw/locales/percentages.json
git commit -am "Auto commit: Calculate translation coverage"
git push
fi

View File

@@ -15,16 +15,14 @@ jobs:
uses: actions/setup-node@v3
with:
node-version: 18.x
- name: Install
run: yarn --frozen-lockfile
- name: Install in src/packages/excalidraw
run: yarn --frozen-lockfile
working-directory: src/packages/excalidraw
- name: Install in packages/excalidraw
run: yarn
working-directory: packages/excalidraw
env:
CI: true
- uses: andresz1/size-limit-action@v1
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
build_script: build:umd
build_script: build:esm
skip_step: install
directory: src/packages/excalidraw
directory: packages/excalidraw

View File

@@ -16,7 +16,7 @@ jobs:
with:
node-version: "18.x"
- name: "Install Deps"
run: yarn --frozen-lockfile
run: yarn install
- name: "Test Coverage"
run: yarn test:coverage
- name: "Report Coverage"

View File

@@ -13,5 +13,5 @@ jobs:
node-version: 18.x
- name: Install and test
run: |
yarn --frozen-lockfile
yarn install
yarn test:app

7
.gitignore vendored
View File

@@ -21,10 +21,9 @@ npm-debug.log*
package-lock.json
yarn-debug.log*
yarn-error.log*
src/packages/excalidraw/types
src/packages/excalidraw/example/public/bundle.js
src/packages/excalidraw/example/public/excalidraw-assets-dev
src/packages/excalidraw/example/public/excalidraw.development.js
packages/excalidraw/types
coverage
dev-dist
html
examples/**/bundle.*
meta*.json

View File

@@ -25,6 +25,9 @@
<a href="https://github.com/excalidraw/excalidraw/blob/master/LICENSE">
<img alt="Excalidraw is released under the MIT license." src="https://img.shields.io/badge/license-MIT-blue.svg" />
</a>
<a href="https://www.npmjs.com/package/@excalidraw/excalidraw">
<img alt="npm downloads/month" src="https://img.shields.io/npm/dm/@excalidraw/excalidraw" />
</a>
<a href="https://docs.excalidraw.com/docs/introduction/contributing">
<img alt="PRs welcome!" src="https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat" />
</a>
@@ -82,7 +85,7 @@ We'll be adding these features as drop-in plugins for the npm package in the fut
## Quick start
Install the [Excalidraw npm package](https://www.npmjs.com/package/@excalidraw/excalidraw):
**Note:** following instructions are for installing the Excalidraw [npm package](https://www.npmjs.com/package/@excalidraw/excalidraw) when integrating Excalidraw into your own app. To run the repository locally for development, please refer to our [Development Guide](https://docs.excalidraw.com/docs/introduction/development).
```
npm install react react-dom @excalidraw/excalidraw
@@ -94,7 +97,7 @@ or via yarn
yarn add react react-dom @excalidraw/excalidraw
```
Don't forget to check out our [Documentation](https://docs.excalidraw.com)!
Check out our [documentation](https://docs.excalidraw.com/docs/@excalidraw/excalidraw/installation) for more details!
## Contributing

View File

@@ -1,3 +1,3 @@
files:
- source: /src/locales/en.json
translation: /src/locales/%locale%.json
- source: /packages/excalidraw/locales/en.json
translation: /packages/excalidraw/locales/%locale%.json

View File

@@ -34,7 +34,7 @@ Open the `Menu` in the below playground and you will see the `custom footer` ren
```jsx live noInline
const MobileFooter = ({}) => {
const device = useDevice();
if (device.isMobile) {
if (device.editor.isMobile) {
return (
<Footer>
<button

View File

@@ -133,7 +133,7 @@ function App() {
}
```
Here is a [complete list](https://github.com/excalidraw/excalidraw/blob/master/src/components/mainMenu/DefaultItems.tsx) of the default items.
Here is a [complete list](https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/components/mainMenu/DefaultItems.tsx) of the default items.
### MainMenu.Group

View File

@@ -80,7 +80,7 @@ A given tab trigger button that switches to a given sidebar tab. It must be rend
| `className` | `string` | No | |
| `style` | `React.CSSProperties` | No | |
You can use the [`ref.toggleSidebar({ name: "custom" })`](/docs/@excalidraw/excalidraw/api/props/ref#toggleSidebar) api to control the sidebar, but we export a trigger button to make UI use cases easier.
You can use the [`ref.toggleSidebar({ name: "custom" })`](/docs/@excalidraw/excalidraw/api/props/excalidraw-api#toggleSidebar) api to control the sidebar, but we export a trigger button to make UI use cases easier.
## Example

View File

@@ -37,7 +37,7 @@ Defaults to `THEME.LIGHT` unless passed in `initialData.appState.theme`
### MIME_TYPES
[`MIME_TYPES`](https://github.com/excalidraw/excalidraw/blob/master/src/constants.ts#L101) contains all the mime types supported by `Excalidraw`.
[`MIME_TYPES`](https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/constants.ts#L101) contains all the mime types supported by `Excalidraw`.
**How to use **

View File

@@ -2,21 +2,25 @@
We support a simplified API to make it easier to generate Excalidraw elements programmatically. This API is in beta and subject to change before stable. You can check the [PR](https://github.com/excalidraw/excalidraw/pull/6546) for more details.
For this purpose we introduced a new type [`ExcalidrawElementSkeleton`](https://github.com/excalidraw/excalidraw/blob/master/src/data/transform.ts#L133). This is the simplified version of [`ExcalidrawElement`](https://github.com/excalidraw/excalidraw/blob/master/src/element/types.ts#L134) type with the minimum possible attributes so that creating elements programmatically is much easier (especially for cases like binding arrows or creating text containers).
For this purpose we introduced a new type [`ExcalidrawElementSkeleton`](https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/data/transform.ts#L133). This is the simplified version of [`ExcalidrawElement`](https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/element/types.ts#L134) type with the minimum possible attributes so that creating elements programmatically is much easier (especially for cases like binding arrows or creating text containers).
The [`ExcalidrawElementSkeleton`](https://github.com/excalidraw/excalidraw/blob/master/src/data/transform.ts#L133) can be converted to fully qualified Excalidraw elements by using [`convertToExcalidrawElements`](/docs/@excalidraw/excalidraw/api/excalidraw-element-skeleton#converttoexcalidrawelements).
The [`ExcalidrawElementSkeleton`](https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/data/transform.ts#L133) can be converted to fully qualified Excalidraw elements by using [`convertToExcalidrawElements`](/docs/@excalidraw/excalidraw/api/excalidraw-element-skeleton#converttoexcalidrawelements).
## convertToExcalidrawElements
**_Signature_**
<pre>
convertToExcalidrawElements(elements:{" "}
<a href="https://github.com/excalidraw/excalidraw/blob/master/src/data/transform.ts#L133">
ExcalidrawElementSkeleton
</a>
)
</pre>
```ts
convertToExcalidrawElements(
elements: ExcalidrawElementSkeleton,
opts?: { regenerateIds: boolean }
): ExcalidrawElement[]
```
| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `elements` | [ExcalidrawElementSkeleton](https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/data/transform.ts#L137) | | The Excalidraw element Skeleton which needs to be converted to Excalidraw elements. |
| `opts` | `{ regenerateIds: boolean }` | ` {regenerateIds: true}` | By default `id` will be regenerated for all the elements irrespective of whether you pass the `id` so if you don't want the ids to regenerated, you can set this attribute to `false`. |
**_How to use_**
@@ -24,13 +28,13 @@ The [`ExcalidrawElementSkeleton`](https://github.com/excalidraw/excalidraw/blob/
import { convertToExcalidrawElements } from "@excalidraw/excalidraw";
```
This function converts the Excalidraw Element Skeleton to excalidraw elements which could be then rendered on the canvas. Hence calling this function is necessary before passing it to APIs like [`initialData`](https://docs.excalidraw.com/docs/@excalidraw/excalidraw/api/props/initialdata), [`updateScene`](https://docs.excalidraw.com/docs/@excalidraw/excalidraw/api/props/ref#updatescene) if you are using the Skeleton API
This function converts the Excalidraw Element Skeleton to excalidraw elements which could be then rendered on the canvas. Hence calling this function is necessary before passing it to APIs like [`initialData`](https://docs.excalidraw.com/docs/@excalidraw/excalidraw/api/props/initialdata), [`updateScene`](https://docs.excalidraw.com/docs/@excalidraw/excalidraw/api/props/excalidraw-api#updatescene) if you are using the Skeleton API
## Supported Features
### Rectangle, Ellipse, and Diamond
To create these shapes you need to pass its `type` and `x` and `y` coordinates for position. The rest of the attributes are optional_.
To create these shapes you need to pass its `type` and `x` and `y` coordinates for position. The rest of the attributes are optional\_.
For the Skeleton API to work, `convertToExcalidrawElements` needs to be called before passing it to Excalidraw Component via initialData, updateScene or any such API.
@@ -67,7 +71,7 @@ function App() {
}
```
You can pass additional [`properties`](https://github.com/excalidraw/excalidraw/blob/master/src/element/types.ts#L27) as well to decorate the shapes.
You can pass additional [`properties`](https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/element/types.ts#L27) as well to decorate the shapes.
:::info
@@ -188,7 +192,7 @@ convertToExcalidrawElements([
### Text Containers
In addition to `type`, `x` and `y` properties, [`label`](https://github.com/excalidraw/excalidraw/blob/master/src/data/transform.ts#L124C7-L130C59) property is required for text containers. The `text` property in `label` is required, rest of the attributes are optional.
In addition to `type`, `x` and `y` properties, [`label`](https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/data/transform.ts#L124C7-L130C59) property is required for text containers. The `text` property in `label` is required, rest of the attributes are optional.
If you don't provide the dimensions of container, we calculate it based of the label dimensions.
@@ -322,7 +326,7 @@ convertToExcalidrawElements([
### Arrow bindings
To bind arrow to a shape you need to specify its [`start`](https://github.com/excalidraw/excalidraw/blob/master/src/data/transform.ts#L86) and [`end`](https://github.com/excalidraw/excalidraw/blob/master/src/data/transform.ts#L54) properties. You need to pass either `type` or `id` property in `start` and `end` properties, rest of the attributes are optional
To bind arrow to a shape you need to specify its [`start`](https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/data/transform.ts#L86) and [`end`](https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/data/transform.ts#L54) properties. You need to pass either `type` or `id` property in `start` and `end` properties, rest of the attributes are optional
```js
convertToExcalidrawElements([
@@ -427,3 +431,45 @@ convertToExcalidrawElements([
```
![image](https://github.com/excalidraw/excalidraw/assets/11256141/a8b047c8-2eed-4aea-82a2-e1e6bbddb8d4)
### Frames
To create a frame, you need to pass `type`, `children` (list of Excalidraw element ids). The rest of the attributes are optional.
```ts
{
type: "frame";
children: readonly ExcalidrawElement["id"][];
name?: string;
} & Partial<ExcalidrawFrameElement>);
```
```ts
convertToExcalidrawElements([
{
"type": "rectangle",
"x": 10,
"y": 10,
"strokeWidth": 2,
"id": "1"
},
{
"type": "diamond",
"x": 120,
"y": 20,
"backgroundColor": "#fff3bf",
"strokeWidth": 2,
"label": {
"text": "HELLO EXCALIDRAW",
"strokeColor": "#099268",
"fontSize": 30
},
"id": "2"
},
{
"type": "frame",
"children": ["1", "2"],
"name": "My frame"
}]
}
```

View File

@@ -1,27 +1,26 @@
# ref
# excalidrawAPI
<pre>
<a href="https://reactjs.org/docs/refs-and-the-dom.html#creating-refs">
createRef
</a>{" "}
&#124;{" "}
<a href="https://reactjs.org/docs/hooks-reference.html#useref">useRef</a>{" "}
&#124;{" "}
<a href="https://reactjs.org/docs/refs-and-the-dom.html#callback-refs">
callbackRef
</a>{" "}
&#124; <br />
&#123; current: &#123; readyPromise: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/utils.ts#L460">
resolvablePromise
</a> } }
(api:{" "}
<a href="https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/types.ts#L616">
ExcalidrawAPI
</a>
) => void;
</pre>
You can pass a `ref` when you want to access some excalidraw APIs. We expose the below APIs:
Once the callback is triggered, you will need to store the api in state to access it later.
```jsx showLineNumbers
export default function App() {
const [excalidrawAPI, setExcalidrawAPI] = useState(null);
return <Excalidraw excalidrawAPI={{(api)=> setExcalidrawAPI(api)}} />;
}
```
You can use this prop when you want to access some [Excalidraw APIs](https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/types.ts#L616). We expose the below APIs :point_down:
| API | Signature | Usage |
| --- | --- | --- |
| ready | `boolean` | This is set to true once Excalidraw is rendered |
| [readyPromise](#readypromise) | `function` | This promise will be resolved with the api once excalidraw has rendered. This will be helpful when you want do some action on the host app once this promise resolves. For this to work you will have to pass ref as shown [here](#readypromise) |
| [updateScene](#updatescene) | `function` | updates the scene with the sceneData |
| [updateLibrary](#updatelibrary) | `function` | updates the scene with the sceneData |
| [addFiles](#addfiles) | `function` | add files data to the appState |
@@ -38,61 +37,22 @@ You can pass a `ref` when you want to access some excalidraw APIs. We expose the
| [setActiveTool](#setactivetool) | `function` | This API can be used to set the active tool |
| [setCursor](#setcursor) | `function` | This API can be used to set customise the mouse cursor on the canvas |
| [resetCursor](#resetcursor) | `function` | This API can be used to reset to default mouse cursor on the canvas |
| [toggleMenu](#togglemenu) | `function` | Toggles specific menus on/off |
| [toggleSidebar](#toggleSidebar) | `function` | Toggles specific sidebar on/off |
| [onChange](#onChange) | `function` | Subscribes to change events |
| [onPointerDown](#onPointerDown) | `function` | Subscribes to `pointerdown` events |
| [onPointerUp](#onPointerUp) | `function` | Subscribes to `pointerup` events |
## readyPromise
:::info The `Ref` support has been removed in v0.17.0 so if you are using refs, please update the integration to use the `excalidrawAPI`.
<pre>
const excalidrawRef = &#123; current:&#123; readyPromise:
<a href="https://github.com/excalidraw/excalidraw/blob/master/src/utils.ts#L460">
&nbsp;resolvablePromise
</a>
&nbsp;&#125; &#125;
</pre>
Additionally `ready` and `readyPromise` from the API have been discontinued. These APIs were found to be superfluous, and as part of the effort to streamline the APIs and maintain simplicity, they were removed in version v0.17.0.
Since plain object is passed as a `ref`, the `readyPromise` is resolved as soon as the component is mounted. Most of the time you will not need this unless you have a specific use case where you can't pass the `ref` in the react way and want to do some action on the host when this promise resolves.
```jsx showLineNumbers
const resolvablePromise = () => {
let resolve;
let reject;
const promise = new Promise((_resolve, _reject) => {
resolve = _resolve;
reject = _reject;
});
promise.resolve = resolve;
promise.reject = reject;
return promise;
};
const App = () => {
const excalidrawRef = useMemo(
() => ({
current: {
readyPromise: resolvablePromise(),
},
}),
[],
);
useEffect(() => {
excalidrawRef.current.readyPromise.then((api) => {
console.log("loaded", api);
});
}, [excalidrawRef]);
return (
<div style={{ height: "500px" }}>
<Excalidraw ref={excalidrawRef} />
</div>
);
};
```
:::
## updateScene
<pre>
(scene:{" "}
<a href="https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L339">
<a href="https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/types.ts#L339">
sceneData
</a>
) => void
@@ -102,9 +62,9 @@ You can use this function to update the scene with the sceneData. It accepts the
| Name | Type | Description |
| --- | --- | --- |
| `elements` | [`ImportedDataState["elements"]`](https://github.com/excalidraw/excalidraw/blob/master/src/data/types.ts#L38) | The `elements` to be updated in the scene |
| `appState` | [`ImportedDataState["appState"]`](https://github.com/excalidraw/excalidraw/blob/master/src/data/types.ts#L39) | The `appState` to be updated in the scene. |
| `collaborators` | <code>Map<string, <a href="https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L37">Collaborator></a></code> | The list of collaborators to be updated in the scene. |
| `elements` | [`ImportedDataState["elements"]`](https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/data/types.ts#L38) | The `elements` to be updated in the scene |
| `appState` | [`ImportedDataState["appState"]`](https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/data/types.ts#L39) | The `appState` to be updated in the scene. |
| `collaborators` | <code>Map<string, <a href="https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/types.ts#L37">Collaborator></a></code> | The list of collaborators to be updated in the scene. |
| `commitToHistory` | `boolean` | Implies if the `history (undo/redo)` should be recorded. Defaults to `false`. |
```jsx live
@@ -165,13 +125,13 @@ function App() {
<pre>
(opts: &#123; <br /> libraryItems:{" "}
<a href="https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L249">
<a href="https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/types.ts#L249">
LibraryItemsSource
</a>
;<br /> merge?: boolean; <br /> prompt?: boolean;
<br /> openLibraryMenu?: boolean;
<br /> defaultStatus?: "unpublished" | "published"; <br /> &#125;) => Promise&lt;
<a href="https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L246">
<a href="https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/types.ts#L246">
LibraryItems
</a>
&gt;
@@ -181,7 +141,7 @@ You can use this function to update the library. It accepts the below attributes
| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `libraryItems` | [LibraryItemsSource](https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L249) | \_ | The `libraryItems` to be replaced/merged with current library |
| `libraryItems` | [LibraryItemsSource](https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/types.ts#L249) | \_ | The `libraryItems` to be replaced/merged with current library |
| `merge` | boolean | `false` | Whether to merge with existing library items. |
| `prompt` | boolean | `false` | Whether to prompt user for confirmation. |
| `openLibraryMenu` | boolean | `false` | Keep the library menu open after library is updated. |
@@ -229,7 +189,7 @@ function App() {
</button>
<Excalidraw
ref={(api) => setExcalidrawAPI(api)}
// initial data retrieved from https://github.com/excalidraw/excalidraw/blob/master/dev-docs/src/initialData.js
// initial data retrieved from https://github.com/excalidraw/excalidraw/blob/master/dev-docs/packages/excalidraw/initialData.js
initialData={{
libraryItems: initialData.libraryItems,
appState: { openSidebar: "library" },
@@ -244,7 +204,7 @@ function App() {
<pre>
(files:{" "}
<a href="https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L59">
<a href="https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/types.ts#L59">
BinaryFileData
</a>
) => void
@@ -264,7 +224,7 @@ Resets the scene. If `resetLoadingState` is passed as true then it will also for
<pre>
() =>{" "}
<a href="https://github.com/excalidraw/excalidraw/blob/master/src/element/types.ts#L115">
<a href="https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/element/types.ts#L115">
ExcalidrawElement[]
</a>
</pre>
@@ -275,7 +235,7 @@ Returns all the elements including the deleted in the scene.
<pre>
() => NonDeleted&#60;
<a href="https://github.com/excalidraw/excalidraw/blob/master/src/element/types.ts#L115">
<a href="https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/element/types.ts#L115">
ExcalidrawElement
</a>
[]&#62;
@@ -287,7 +247,7 @@ Returns all the elements excluding the deleted in the scene
<pre>
() =>{" "}
<a href="https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L95">
<a href="https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/types.ts#L95">
AppState
</a>
</pre>
@@ -328,7 +288,7 @@ Scroll the nearest element out of the elements supplied to the center of the vie
| Attribute | type | default | Description |
| --- | --- | --- | --- |
| target | [ExcalidrawElement](https://github.com/excalidraw/excalidraw/blob/master/src/element/types.ts#L115) &#124; [ExcalidrawElement[]](https://github.com/excalidraw/excalidraw/blob/master/src/element/types.ts#L115) | All scene elements | The element(s) to scroll to. |
| target | [ExcalidrawElement](https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/element/types.ts#L115) &#124; [ExcalidrawElement[]](https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/element/types.ts#L115) | All scene elements | The element(s) to scroll to. |
| opts.fitToContent | boolean | false | Whether to fit the elements to viewport by automatically changing zoom as needed. Note that the zoom range is between 10%-100%. |
| opts.fitToViewport | boolean | false | Similar to fitToContent but the zoom range is not limited. If elements are smaller than the viewport, zoom will go above 100%. |
| opts.viewportZoomFactor | number | 0.7 | when fitToViewport=true, how much screen should the content cover, between 0.1 (10%) and 1 (100%) |
@@ -376,7 +336,7 @@ The unique id of the excalidraw component. This can be used to identify the exca
<pre>
() =>{" "}
<a href="https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L82">
<a href="https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/types.ts#L82">
files
</a>
</pre>
@@ -387,14 +347,25 @@ This API can be used to get the files present in the scene. It may contain files
This API has the below signature. It sets the `tool` passed in param as the active tool.
<pre>
(tool: <br /> &#123; type:{" "}
<a href="https://github.com/excalidraw/excalidraw/blob/master/src/shapes.tsx#L15">
SHAPES
</a>
[number]["value"]&#124; "eraser" &#125; &#124;
<br /> &#123; type: "custom"; customType: string &#125;) => void
</pre>
```ts
(
tool: (
| (
| { type: Exclude<ToolType, "image"> }
| {
type: Extract<ToolType, "image">;
insertOnCanvasDirectly?: boolean;
}
)
| { type: "custom"; customType: string }
) & { locked?: boolean },
) => {};
```
| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `type` | [ToolType](https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/types.ts#L91) | `selection` | The tool type which should be set as active tool. When setting `image` as active tool, the insertion onto canvas when using image tool is disabled by default, so you can enable it by setting `insertOnCanvasDirectly` to `true` |
| `locked` | `boolean` | `false` | Indicates whether the the active tool should be locked. It behaves the same way when using the `lock` tool in the editor interface |
## setCursor
@@ -421,3 +392,51 @@ This API is especially useful when you render a custom [`<Sidebar/>`](/docs/@exc
```
This API can be used to reset to default mouse cursor.
## onChange
```tsx
(
callback: (
elements: readonly ExcalidrawElement[],
appState: AppState,
files: BinaryFiles,
) => void
) => () => void
```
Subscribes to change events, similar to [`props.onChange`](/docs/@excalidraw/excalidraw/api/props#onchange).
Returns an unsubscribe function.
## onPointerDown
```tsx
(
callback: (
activeTool: AppState["activeTool"],
pointerDownState: PointerDownState,
event: React.PointerEvent<HTMLElement>,
) => void,
) => () => void
```
Subscribes to canvas `pointerdown` events.
Returns an unsubscribe function.
## onPointerUp
```tsx
(
callback: (
activeTool: AppState["activeTool"],
pointerDownState: PointerDownState,
event: PointerEvent,
) => void,
) => () => void
```
Subscribes to canvas `pointerup` events.
Returns an unsubscribe function.

View File

@@ -1,18 +1,18 @@
# initialData
<pre>
&#123; elements?: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/element/types.ts#L114">ExcalidrawElement[]</a>, appState?: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L95">AppState</a> &#125;
&#123; elements?: <a href="https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/element/types.ts#L114">ExcalidrawElement[]</a>, appState?: <a href="https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/types.ts#L95">AppState</a> &#125;
</pre>
This helps to load Excalidraw with `initialData`. It must be an object or a [promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/Promise) which resolves to an object containing the below optional fields.
| Name | Type | Description |
| --- | --- | --- |
| `elements` | [ExcalidrawElement[]](https://github.com/excalidraw/excalidraw/blob/master/src/element/types.ts#L114) | The `elements` with which `Excalidraw` should be mounted. |
| `appState` | [AppState](https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L95) | The `AppState` with which `Excalidraw` should be mounted. |
| `elements` | [ExcalidrawElement[]](https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/element/types.ts#L114) | The `elements` with which `Excalidraw` should be mounted. |
| `appState` | [AppState](https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/types.ts#L95) | The `AppState` with which `Excalidraw` should be mounted. |
| `scrollToContent` | `boolean` | This attribute indicates whether to `scroll` to the nearest element to center once `Excalidraw` is mounted. By default, it will not scroll the nearest element to the center. Make sure you pass `initialData.appState.scrollX` and `initialData.appState.scrollY` when `scrollToContent` is false so that scroll positions are retained |
| `libraryItems` | [LibraryItems](https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L247) &#124; Promise&lt;[LibraryItems](https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L200)&gt; | This library items with which `Excalidraw` should be mounted. |
| `files` | [BinaryFiles](https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L82) | The `files` added to the scene. |
| `libraryItems` | [LibraryItems](https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/types.ts#L247) &#124; Promise&lt;[LibraryItems](https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/types.ts#L200)&gt; | This library items with which `Excalidraw` should be mounted. |
| `files` | [BinaryFiles](https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/types.ts#L82) | The `files` added to the scene. |
You might want to use this when you want to load excalidraw with some initial elements and app state.

View File

@@ -1,11 +1,11 @@
# Props
All `props` are *optional*.
All `props` are _optional_.
| Name | Type | Default | Description |
| --- | --- | --- | --- |
| [`initialData`](/docs/@excalidraw/excalidraw/api/props/initialdata) | `object` &#124; `null` &#124; <code>Promise<object &#124; null></code> | `null` | The initial data with which app loads. |
| [`ref`](/docs/@excalidraw/excalidraw/api/props/ref) | `object` | _ | `Ref` to be passed to Excalidraw |
| [`initialData`](/docs/@excalidraw/excalidraw/api/props/initialdata) | `object` &#124; `null` &#124; <code>Promise<object &#124; null></code> | `null` | The initial data with which app loads. |
| [`excalidrawAPI`](/docs/@excalidraw/excalidraw/api/props/excalidraw-api) | `function` | _ | Callback triggered with the excalidraw api once rendered |
| [`isCollaborating`](#iscollaborating) | `boolean` | _ | This indicates if the app is in `collaboration` mode |
| [`onChange`](#onchange) | `function` | _ | This callback is triggered whenever the component updates due to any change. This callback will receive the excalidraw `elements` and the current `app state`. |
| [`onPointerUpdate`](#onpointerupdate) | `function` | _ | Callback triggered when mouse pointer is updated. |
@@ -23,7 +23,7 @@ All `props` are *optional*.
| [`libraryReturnUrl`](#libraryreturnurl) | `string` | _ | What URL should [libraries.excalidraw.com](https://libraries.excalidraw.com) be installed to |
| [`theme`](#theme) | `"light"` &#124; `"dark"` | `"light"` | The theme of the Excalidraw component |
| [`name`](#name) | `string` | | Name of the drawing |
| [`UIOptions`](/docs/@excalidraw/excalidraw/api/props/ui-options) | `object` | [DEFAULT UI OPTIONS](https://github.com/excalidraw/excalidraw/blob/master/src/constants.ts#L151) | To customise UI options. Currently we support customising [`canvas actions`](#canvasactions) |
| [`UIOptions`](/docs/@excalidraw/excalidraw/api/props/ui-options) | `object` | [DEFAULT UI OPTIONS](https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/constants.ts#L151) | To customise UI options. Currently we support customising [`canvas actions`](/docs/@excalidraw/excalidraw/api/props/ui-options#canvasactions) |
| [`detectScroll`](#detectscroll) | `boolean` | `true` | Indicates whether to update the offsets when nearest ancestor is scrolled. |
| [`handleKeyboardGlobally`](#handlekeyboardglobally) | `boolean` | `false` | Indicates whether to bind the keyboard events to document. |
| [`autoFocus`](#autofocus) | `boolean` | `false` | indicates whether to focus the Excalidraw component on page load |
@@ -33,11 +33,11 @@ All `props` are *optional*.
### Storing custom data on Excalidraw elements
Beyond attributes that Excalidraw elements already support, you can store `custom` data on each `element` in a `customData` object. The type of the attribute is [`Record<string, any>`](https://github.com/excalidraw/excalidraw/blob/master/src/element/types.ts#L66) and is optional.
Beyond attributes that Excalidraw elements already support, you can store `custom` data on each `element` in a `customData` object. The type of the attribute is [`Record<string, any>`](https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/element/types.ts#L66) and is optional.
You can use this to add any extra information you need to keep track of.
You can add `customData` to elements when passing them as [`initialData`](/docs/@excalidraw/excalidraw/api/props/initialdata), or using [`updateScene`](/docs/@excalidraw/excalidraw/api/props/ref#updatescene) / [`updateLibrary`](/docs/@excalidraw/excalidraw/api/props/ref#updatelibrary) afterwards.
You can add `customData` to elements when passing them as [`initialData`](/docs/@excalidraw/excalidraw/api/props/initialdata), or using [`updateScene`](/docs/@excalidraw/excalidraw/api/props/excalidraw-api#updatescene) / [`updateLibrary`](/docs/@excalidraw/excalidraw/api/props/excalidraw-api#updatelibrary) afterwards.
```js showLineNumbers
{
@@ -59,11 +59,11 @@ Every time component updates, this callback if passed will get triggered and has
(excalidrawElements, appState, files) => void;
```
1. `excalidrawElements`: Array of [excalidrawElements](https://github.com/excalidraw/excalidraw/blob/master/src/element/types.ts#L114) in the scene.
1. `excalidrawElements`: Array of [excalidrawElements](https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/element/types.ts#L114) in the scene.
2. `appState`: [AppState](https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L95) of the scene.
2. `appState`: [AppState](https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/types.ts#L95) of the scene.
3. `files`: The [BinaryFiles](https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L64) which are added to the scene.
3. `files`: The [BinaryFiles](https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/types.ts#L64) which are added to the scene.
Here you can try saving the data to your backend or local storage for example.
@@ -79,22 +79,30 @@ This callback is triggered when mouse pointer is updated.
2.`button`: The position of the button. This will be one of `["down", "up"]`
3.`pointersMap`: [`pointers`](https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L131) map of the scene
3.`pointersMap`: [`pointers`](https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/types.ts#L131) map of the scene
```js
(exportedElements, appState, canvas) => void
```
1. `exportedElements`: An array of [non deleted elements](https://github.com/excalidraw/excalidraw/blob/master/src/element/types.ts#L87) which needs to be exported.
2. `appState`: [AppState](https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L95) of the scene.
1. `exportedElements`: An array of [non deleted elements](https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/element/types.ts#L87) which needs to be exported.
2. `appState`: [AppState](https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/types.ts#L95) of the scene.
3. `canvas`: The `HTMLCanvasElement` of the scene.
### onPointerDown
This prop if passed will be triggered on pointer down events and has the below signature.
<pre>
(activeTool: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L115"> AppState["activeTool"]</a>, pointerDownState: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L424">PointerDownState</a>) => void
(activeTool:{" "}
<a href="https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/types.ts#L115">
{" "}
AppState["activeTool"]
</a>
, pointerDownState: <a href="https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/types.ts#L424">
PointerDownState
</a>) => void
</pre>
### onScrollChange
@@ -110,7 +118,11 @@ This prop if passed will be triggered when canvas is scrolled and has the below
This callback is triggered if passed when something is pasted into the scene. You can use this callback in case you want to do something additional when the paste event occurs.
<pre>
(data: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/clipboard.ts#L18">ClipboardData</a>, event: ClipboardEvent &#124; null) => boolean
(data:{" "}
<a href="https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/clipboard.ts#L18">
ClipboardData
</a>
, event: ClipboardEvent &#124; null) => boolean
</pre>
This callback must return a `boolean` value or a [promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/Promise) which resolves to a boolean value.
@@ -123,7 +135,7 @@ This callback if supplied will get triggered when the library is updated and has
<pre>
(items:{" "}
<a href="https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L200">
<a href="https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/types.ts#L200">
LibraryItems
</a>
) => void | Promise&lt;any&gt;
@@ -136,8 +148,11 @@ It is invoked with empty items when user clears the library. You can use this ca
This prop if passed will be triggered when clicked on `link`. To handle the redirect yourself (such as when using your own router for internal links), you must call `event.preventDefault()`.
<pre>
(element: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/element/types.ts#L114">ExcalidrawElement</a>,
event: CustomEvent&lt;&#123; nativeEvent: MouseEvent }&gt;) => void
(element:{" "}
<a href="https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/element/types.ts#L114">
ExcalidrawElement
</a>
, event: CustomEvent&lt;&#123; nativeEvent: MouseEvent }&gt;) => void
</pre>
Example:
@@ -167,7 +182,7 @@ const onLinkOpen: ExcalidrawProps["onLinkOpen"] = useCallback(
### langCode
Determines the `language` of the UI. It should be one of the [available language codes](https://github.com/excalidraw/excalidraw/blob/master/src/i18n.ts#L14). Defaults to `en` (English). We also export default language and supported languages which you can import as shown below.
Determines the `language` of the UI. It should be one of the [available language codes](https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/i18n.ts#L14). Defaults to `en` (English). We also export default language and supported languages which you can import as shown below.
```js
import { defaultLang, languages } from "@excalidraw/excalidraw";
@@ -176,34 +191,34 @@ import { defaultLang, languages } from "@excalidraw/excalidraw";
| name | type |
| --- | --- |
| `defaultLang` | `string` |
| `languages` | [`Language[]`](https://github.com/excalidraw/excalidraw/blob/master/src/i18n.ts#L15) |
| `languages` | [`Language[]`](https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/i18n.ts#L15) |
### viewModeEnabled
This prop indicates whether the app is in `view mode`. When supplied, the value takes precedence over *intialData.appState.viewModeEnabled*, the `view mode` will be fully controlled by the host app, and users won't be able to toggle it from within the app.
This prop indicates whether the app is in `view mode`. When supplied, the value takes precedence over _intialData.appState.viewModeEnabled_, the `view mode` will be fully controlled by the host app, and users won't be able to toggle it from within the app.
### zenModeEnabled
This prop indicates whether the app is in `zen mode`. When supplied, the value takes precedence over *intialData.appState.zenModeEnabled*, the `zen mode` will be fully controlled by the host app, and users won't be able to toggle it from within the app.
This prop indicates whether the app is in `zen mode`. When supplied, the value takes precedence over _intialData.appState.zenModeEnabled_, the `zen mode` will be fully controlled by the host app, and users won't be able to toggle it from within the app.
### gridModeEnabled
This prop indicates whether the shows the grid. When supplied, the value takes precedence over *intialData.appState.gridModeEnabled*, the grid will be fully controlled by the host app, and users won't be able to toggle it from within the app.
This prop indicates whether the shows the grid. When supplied, the value takes precedence over _intialData.appState.gridModeEnabled_, the grid will be fully controlled by the host app, and users won't be able to toggle it from within the app.
### libraryReturnUrl
If supplied, this URL will be used when user tries to install a library from [libraries.excalidraw.com](https://libraries.excalidraw.com).
Defaults to *window.location.origin + window.location.pathname*. To install the libraries in the same tab from which it was opened, you need to set `window.name` (to any alphanumeric string) — if it's not set it will open in a new tab.
Defaults to _window.location.origin + window.location.pathname_. To install the libraries in the same tab from which it was opened, you need to set `window.name` (to any alphanumeric string) — if it's not set it will open in a new tab.
### theme
This prop controls Excalidraw's theme. When supplied, the value takes precedence over *intialData.appState.theme*, the theme will be fully controlled by the host app, and users won't be able to toggle it from within the app unless *UIOptions.canvasActions.toggleTheme* is set to `true`, in which case the `theme` prop will control Excalidraw's default theme with ability to allow theme switching (you must take care of updating the `theme` prop when you detect a change to `appState.theme` from the [onChange](#onchange) callback).
This prop controls Excalidraw's theme. When supplied, the value takes precedence over _intialData.appState.theme_, the theme will be fully controlled by the host app, and users won't be able to toggle it from within the app unless _UIOptions.canvasActions.toggleTheme_ is set to `true`, in which case the `theme` prop will control Excalidraw's default theme with ability to allow theme switching (you must take care of updating the `theme` prop when you detect a change to `appState.theme` from the [onChange](#onchange) callback).
You can use [`THEME`](/docs/@excalidraw/excalidraw/api/utils#theme) to specify the theme.
### name
This prop sets the `name` of the drawing which will be used when exporting the drawing. When supplied, the value takes precedence over *intialData.appState.name*, the `name` will be fully controlled by host app and the users won't be able to edit from within Excalidraw.
This prop sets the `name` of the drawing which will be used when exporting the drawing. When supplied, the value takes precedence over _intialData.appState.name_, the `name` will be fully controlled by host app and the users won't be able to edit from within Excalidraw.
### detectScroll
@@ -236,4 +251,4 @@ validateEmbeddable?: boolean | string[] | RegExp | RegExp[] | ((link: string) =>
This is an optional property. By default we support a handful of well-known sites. You may allow additional sites or disallow the default ones by supplying a custom validator. If you pass `true`, all URLs will be allowed. You can also supply a list of hostnames, RegExp (or list of RegExp objects), or a function. If the function returns `undefined`, the built-in validator will be used.
Supplying a list of hostnames (with or without `www.`) is the preferred way to allow a specific list of domains.
Supplying a list of hostnames (with or without `www.`) is the preferred way to allow a specific list of domains.

View File

@@ -4,7 +4,7 @@
<pre>
(isMobile: boolean, appState:
<a href="https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L95">
<a href="https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/types.ts#L95">
AppState
</a>) => JSX | null
</pre>
@@ -66,7 +66,7 @@ function App() {
<pre>
(element: NonDeleted&lt;ExcalidrawEmbeddableElement&gt;, appState:{" "}
<a href="https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L95">
<a href="https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/types.ts#L95">
AppState
</a>
) => JSX.Element | null

View File

@@ -1,10 +1,10 @@
# UIOptions
This prop can be used to customise UI of Excalidraw. Currently we support customising [`canvasActions`](#canvasactions), [`dockedSidebarBreakpoint`](#dockedsidebarbreakpoint) and [`welcomeScreen`](#welcmescreen).
This prop can be used to customise UI of Excalidraw. Currently we support customising [`canvasActions`](#canvasactions), [`dockedSidebarBreakpoint`](#dockedsidebarbreakpoint) [`welcomeScreen`](#welcmescreen) and [`tools`](#tools).
<pre>
&#123;
<br /> canvasActions?: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L372">
<br /> canvasActions?: <a href="https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/types.ts#L372">
CanvasActions
</a>, <br /> dockedSidebarBreakpoint?: number, <br /> welcomeScreen?: boolean <br />
@@ -55,7 +55,7 @@ If `UIOptions.canvasActions.export` is `false` the export button will not be ren
## dockedSidebarBreakpoint
This prop indicates at what point should we break to a docked, permanent sidebar. If not passed it defaults to [`MQ_RIGHT_SIDEBAR_MAX_WIDTH_PORTRAIT`](https://github.com/excalidraw/excalidraw/blob/master/src/constants.ts#L161).
This prop indicates at what point should we break to a docked, permanent sidebar. If not passed it defaults to [`MQ_RIGHT_SIDEBAR_MAX_WIDTH_PORTRAIT`](https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/constants.ts#L161).
If the _width_ of the _excalidraw_ container exceeds _dockedSidebarBreakpoint_, the sidebar will be `dockable` and the button to `dock` the sidebar will be shown
If user choses to `dock` the sidebar, it will push the right part of the UI towards the left, making space for the sidebar as shown below.
@@ -70,3 +70,12 @@ function App() {
);
}
```
## tools
This `prop` controls the visibility of the tools in the editor.
Currently you can control the visibility of `image` tool via this prop.
| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| image | boolean | true | Decides whether `image` tool should be visible.

View File

@@ -20,16 +20,16 @@ exportToCanvas(&#123;<br/>&nbsp;
getDimensions,<br/>&nbsp;
files,<br/>&nbsp;
exportPadding?: number;<br/>
&#125;: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/packages/utils.ts#L21">ExportOpts</a>
&#125;: <a href="https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/packages/utils.ts#L21">ExportOpts</a>
</pre>
| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `elements` | [Excalidraw Element []](https://github.com/excalidraw/excalidraw/blob/master/src/element/types.ts#L114) | | The elements to be exported to canvas. |
| `appState` | [AppState](https://github.com/excalidraw/excalidraw/blob/master/src/packages/utils.ts#L23) | [Default App State](https://github.com/excalidraw/excalidraw/blob/master/src/appState.ts#L17) | The app state of the scene. |
| `elements` | [Excalidraw Element []](https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/element/types.ts#L114) | | The elements to be exported to canvas. |
| `appState` | [AppState](https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/packages/utils.ts#L23) | [Default App State](https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/appState.ts#L17) | The app state of the scene. |
| [`getDimensions`](#getdimensions) | `function` | _ | A function which returns the `width`, `height`, and optionally `scale` (defaults to `1`), with which canvas is to be exported. |
| `maxWidthOrHeight` | `number` | _ | The maximum `width` or `height` of the exported image. If provided, `getDimensions` is ignored. |
| `files` | [BinaryFiles](https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L59) | _ | The files added to the scene. |
| `files` | [BinaryFiles](https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/types.ts#L59) | _ | The files added to the scene. |
| `exportPadding` | `number` | `10` | The `padding` to be added on canvas. |
@@ -105,7 +105,7 @@ function App() {
<pre>
exportToBlob(<br/>&nbsp;
opts: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/packages/utils.ts#L14">ExportOpts</a> & &#123;<br/>&nbsp;
opts: <a href="https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/packages/utils.ts#L14">ExportOpts</a> & &#123;<br/>&nbsp;
mimeType?: string,<br/>&nbsp;
quality?: number,<br/>&nbsp;
exportPadding?: number;<br/>
@@ -134,16 +134,16 @@ Returns a promise which resolves with a [blob](https://developer.mozilla.org/en-
<pre>
exportToSvg(&#123;<br/>&nbsp;
elements:&nbsp;
<a href="https://github.com/excalidraw/excalidraw/blob/master/src/element/types.ts#L114">
<a href="https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/element/types.ts#L114">
ExcalidrawElement[]
</a>,<br/>&nbsp;
appState:
<a href="https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L95"> AppState
<a href="https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/types.ts#L95"> AppState
</a>,<br/>&nbsp;
exportPadding: number,<br/>&nbsp;
metadata: string,<br/>&nbsp;
files:&nbsp;
<a href="https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L59">
<a href="https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/types.ts#L59">
BinaryFiles
</a>,<br/>
&#125;);
@@ -151,10 +151,10 @@ exportToSvg(&#123;<br/>&nbsp;
| Name | Type | Default | Description |
| --- | --- | --- | --- |
| elements | [Excalidraw Element []](https://github.com/excalidraw/excalidraw/blob/master/src/element/types.ts#L114) | | The elements to exported as `svg `|
| appState | [AppState](https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L95) | [defaultAppState](https://github.com/excalidraw/excalidraw/blob/master/src/appState.ts#L11) | The `appState` of the scene |
| elements | [Excalidraw Element []](https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/element/types.ts#L114) | | The elements to exported as `svg `|
| appState | [AppState](https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/types.ts#L95) | [defaultAppState](https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/appState.ts#L11) | The `appState` of the scene |
| exportPadding | number | 10 | The `padding` to be added on canvas |
| files | [BinaryFiles](https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L64) | undefined | The `files` added to the scene. |
| files | [BinaryFiles](https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/types.ts#L64) | undefined | The `files` added to the scene. |
This function returns a promise which resolves to `svg` of the exported drawing.
@@ -164,7 +164,7 @@ This function returns a promise which resolves to `svg` of the exported drawing.
<pre>
exportToClipboard(<br/>&nbsp;
opts: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/packages/utils.ts#L21">ExportOpts</a> & &#123;<br/>&nbsp;
opts: <a href="https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/packages/utils.ts#L21">ExportOpts</a> & &#123;<br/>&nbsp;
mimeType?: string,<br/>&nbsp;
quality?: number;<br/>&nbsp;
type: 'png' | 'svg' |'json'<br/>

View File

@@ -8,7 +8,7 @@ id: "restore"
**_Signature_**
<pre>
restoreAppState(appState: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/data/types.ts#L34">ImportedDataState["appState"]</a>,<br/>&nbsp; localAppState: Partial&lt;<a href="https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L95">AppState</a>> | null): <a href="https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L95">AppState</a>
restoreAppState(appState: <a href="https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/data/types.ts#L34">ImportedDataState["appState"]</a>,<br/>&nbsp; localAppState: Partial&lt;<a href="https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/types.ts#L95">AppState</a>> | null): <a href="https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/types.ts#L95">AppState</a>
</pre>
**_How to use_**
@@ -17,7 +17,7 @@ restoreAppState(appState: <a href="https://github.com/excalidraw/excalidraw/blob
import { restoreAppState } from "@excalidraw/excalidraw";
```
This function will make sure all the `keys` have appropriate `values` in [appState](https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L95) and if any key is missing, it will be set to its `default` value.
This function will make sure all the `keys` have appropriate `values` in [appState](https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/types.ts#L95) and if any key is missing, it will be set to its `default` value.
When `localAppState` is supplied, it's used in place of values that are missing (`undefined`) in `appState` instead of the defaults.
Use this as a way to not override user's defaults if you persist them.
@@ -29,16 +29,16 @@ You can pass `null` / `undefined` if not applicable.
<pre>
restoreElements(
elements: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/element/types.ts#L114">ImportedDataState["elements"]</a>,<br/>&nbsp;
localElements: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/element/types.ts#L114">ExcalidrawElement[]</a> | null | undefined): <a href="https://github.com/excalidraw/excalidraw/blob/master/src/element/types.ts#L114">ExcalidrawElement[]</a>,<br/>&nbsp;
elements: <a href="https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/element/types.ts#L114">ImportedDataState["elements"]</a>,<br/>&nbsp;
localElements: <a href="https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/element/types.ts#L114">ExcalidrawElement[]</a> | null | undefined): <a href="https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/element/types.ts#L114">ExcalidrawElement[]</a>,<br/>&nbsp;
opts: &#123; refreshDimensions?: boolean, repairBindings?: boolean }<br/>
)
</pre>
| Prop | Type | Description |
| ---- | ---- | ---- |
| `elements` | <a href="https://github.com/excalidraw/excalidraw/blob/master/src/element/types.ts#L114">ImportedDataState["elements"]</a> | The `elements` to be restored |
| [`localElements`](#localelements) | <a href="https://github.com/excalidraw/excalidraw/blob/master/src/element/types.ts#L114">ExcalidrawElement[]</a> &#124; null &#124; undefined | When `localElements` are supplied, they are used to ensure that existing restored elements reuse `version` (and increment it), and regenerate `versionNonce`. |
| `elements` | <a href="https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/element/types.ts#L114">ImportedDataState["elements"]</a> | The `elements` to be restored |
| [`localElements`](#localelements) | <a href="https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/element/types.ts#L114">ExcalidrawElement[]</a> &#124; null &#124; undefined | When `localElements` are supplied, they are used to ensure that existing restored elements reuse `version` (and increment it), and regenerate `versionNonce`. |
| [`opts`](#opts) | `Object` | The extra optional parameter to configure restored elements
#### localElements
@@ -70,15 +70,15 @@ Parameter `refreshDimensions` indicates whether we should also `recalculate` tex
<pre>
restore(
data: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/data/types.ts#L34">ImportedDataState</a>,<br/>&nbsp;
localAppState: Partial&lt;<a href="https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L95">AppState</a>> | null | undefined,<br/>&nbsp;
localElements: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/element/types.ts#L114">ExcalidrawElement[]</a> | null | undefined<br/>): <a href="https://github.com/excalidraw/excalidraw/blob/master/src/data/types.ts#L4">DataState</a><br/>
data: <a href="https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/data/types.ts#L34">ImportedDataState</a>,<br/>&nbsp;
localAppState: Partial&lt;<a href="https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/types.ts#L95">AppState</a>> | null | undefined,<br/>&nbsp;
localElements: <a href="https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/element/types.ts#L114">ExcalidrawElement[]</a> | null | undefined<br/>): <a href="https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/data/types.ts#L4">DataState</a><br/>
opts: &#123; refreshDimensions?: boolean, repairBindings?: boolean }<br/>
)
</pre>
See [`restoreAppState()`](https://github.com/excalidraw/excalidraw/blob/master/src/packages/excalidraw/README.md#restoreAppState) about `localAppState`, and [`restoreElements()`](https://github.com/excalidraw/excalidraw/blob/master/src/packages/excalidraw/README.md#restoreElements) about `localElements`.
See [`restoreAppState()`](https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/packages/excalidraw/README.md#restoreAppState) about `localAppState`, and [`restoreElements()`](https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/packages/excalidraw/README.md#restoreElements) about `localElements`.
**_How to use_**
@@ -93,7 +93,7 @@ This function makes sure elements and state is set to appropriate values and set
**_Signature_**
<pre>
restoreLibraryItems(libraryItems: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/data/types.ts#L34">ImportedDataState["libraryItems"]</a>,<br/>&nbsp;
restoreLibraryItems(libraryItems: <a href="https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/data/types.ts#L34">ImportedDataState["libraryItems"]</a>,<br/>&nbsp;
defaultStatus: "published" | "unpublished")
</pre>

View File

@@ -8,7 +8,7 @@ These are pure Javascript functions exported from the @excalidraw/excalidraw [`@
### serializeAsJSON
Takes the scene elements and state and returns a JSON string. `Deleted` elements as well as most properties from `AppState` are removed from the resulting JSON. (see [`serializeAsJSON()`](https://github.com/excalidraw/excalidraw/blob/master/src/data/json.ts#L42) source for details).
Takes the scene elements and state and returns a JSON string. `Deleted` elements as well as most properties from `AppState` are removed from the resulting JSON. (see [`serializeAsJSON()`](https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/data/json.ts#L42) source for details).
If you want to overwrite the `source` field in the `JSON` string, you can set `window.EXCALIDRAW_EXPORT_SOURCE` to the desired value.
@@ -16,8 +16,8 @@ If you want to overwrite the `source` field in the `JSON` string, you can set `w
<pre>
serializeAsJSON(&#123;<br/>&nbsp;
elements: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/element/types.ts#L114">ExcalidrawElement[]</a>,<br/>&nbsp;
appState: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L95">AppState</a>,<br/>
elements: <a href="https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/element/types.ts#L114">ExcalidrawElement[]</a>,<br/>&nbsp;
appState: <a href="https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/types.ts#L95">AppState</a>,<br/>
}): string
</pre>
@@ -37,7 +37,7 @@ If you want to overwrite the source field in the JSON string, you can set `windo
<pre>
serializeLibraryAsJSON(
libraryItems: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L200">LibraryItems[]</a>)
libraryItems: <a href="https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/types.ts#L200">LibraryItems[]</a>)
</pre>
**How to use**
@@ -53,7 +53,7 @@ Returns `true` if element is invisibly small (e.g. width & height are zero).
**_Signature_**
<pre>
isInvisiblySmallElement(element: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/element/types.ts#L114">ExcalidrawElement</a>): boolean
isInvisiblySmallElement(element: <a href="https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/element/types.ts#L114">ExcalidrawElement</a>): boolean
</pre>
**How to use**
@@ -80,10 +80,10 @@ excalidrawAPI.updateScene(scene);
<pre>
loadFromBlob(<br/>&nbsp;
blob: <a href="https://developer.mozilla.org/en-US/docs/Web/API/Blob">Blob</a>,<br/>&nbsp;
localAppState: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L95">AppState</a> | null,<br/>&nbsp;
localElements: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/element/types.ts#L114">ExcalidrawElement[]</a> | null,<br/>&nbsp;
localAppState: <a href="https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/types.ts#L95">AppState</a> | null,<br/>&nbsp;
localElements: <a href="https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/element/types.ts#L114">ExcalidrawElement[]</a> | null,<br/>&nbsp;
fileHandle?: FileSystemHandle | null <br/>
) => Promise&lt;<a href="https://github.com/excalidraw/excalidraw/blob/master/src/data/restore.ts#L61">RestoredDataState</a>>
) => Promise&lt;<a href="https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/data/restore.ts#L61">RestoredDataState</a>>
</pre>
### loadLibraryFromBlob
@@ -129,11 +129,11 @@ if (contents.type === MIME_TYPES.excalidraw) {
<pre>
loadSceneOrLibraryFromBlob(<br/>&nbsp;
blob: <a href="https://developer.mozilla.org/en-US/docs/Web/API/Blob">Blob</a>,
localAppState: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L95">AppState</a> | null,<br/>&nbsp;
localElements: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/element/types.ts#L114">ExcalidrawElement[]</a> | null,<br/>&nbsp;
blob: <a href="https://developer.mozilla.org/en-US/docs/Web/API/Blob">Blob</a>,<br/>&nbsp;
localAppState: <a href="https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/types.ts#L95">AppState</a> | null,<br/>&nbsp;
localElements: <a href="https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/element/types.ts#L114">ExcalidrawElement[]</a> | null,<br/>&nbsp;
fileHandle?: FileSystemHandle | null<br/>
) => Promise&lt;&#123; type: string, data: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/data/restore.ts#L53">RestoredDataState</a> | <a href="https://github.com/excalidraw/excalidraw/blob/master/src/data/types.ts#L33">ImportedLibraryState</a>}>
) => Promise&lt;&#123; type: string, data: <a href="https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/data/restore.ts#L53">RestoredDataState</a> | <a href="https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/data/types.ts#L33">ImportedLibraryState</a>}>
</pre>
### getFreeDrawSvgPath
@@ -149,7 +149,7 @@ import { getFreeDrawSvgPath } from "@excalidraw/excalidraw";
**Signature**
<pre>
getFreeDrawSvgPath(element: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/element/types.ts#L182">ExcalidrawFreeDrawElement</a>)
getFreeDrawSvgPath(element: <a href="https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/element/types.ts#L182">ExcalidrawFreeDrawElement</a>)
</pre>
### isLinearElement
@@ -164,9 +164,9 @@ import { isLinearElement } from "@excalidraw/excalidraw";
**Signature**
```tsx
isLinearElement(elementType?: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/element/types.ts#L80">ExcalidrawElement</a>): boolean
```
<pre>
isLinearElement(elementType?: <a href="https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/element/types.ts#L80">ExcalidrawElement</a>): boolean
</pre>
### getNonDeletedElements
@@ -181,7 +181,7 @@ import { getNonDeletedElements } from "@excalidraw/excalidraw";
**Signature**
<pre>
getNonDeletedElements(elements:<a href="https://github.com/excalidraw/excalidraw/blob/master/src/element/types.ts#L114"> readonly ExcalidrawElement[]</a>): as readonly <a href="https://github.com/excalidraw/excalidraw/blob/master/src/element/types.ts#L125">NonDeletedExcalidrawElement[]</a>
getNonDeletedElements(elements:<a href="https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/element/types.ts#L114"> readonly ExcalidrawElement[]</a>): as readonly <a href="https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/element/types.ts#L125">NonDeletedExcalidrawElement[]</a>
</pre>
### mergeLibraryItems
@@ -195,8 +195,10 @@ import { mergeLibraryItems } from "@excalidraw/excalidraw";
**_Signature_**
<pre>
mergeLibraryItems(localItems: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L250">LibraryItems</a>,<br/>&nbsp;
otherItems: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L200">LibraryItems</a>) => <a href="https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L250">LibraryItems</a>
mergeLibraryItems(<br/>&nbsp;
localItems: <a href="https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/types.ts#L250">LibraryItems</a>,<br/>&nbsp;
otherItems: <a href="https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/types.ts#L200">LibraryItems</a><br/>
): <a href="https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/types.ts#L250">LibraryItems</a>
</pre>
### parseLibraryTokensFromUrl
@@ -237,8 +239,8 @@ export const App = () => {
<pre>
useHandleLibrary(opts: &#123;<br/>&nbsp;
excalidrawAPI: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L494">ExcalidrawAPI</a>,<br/>&nbsp;
getInitialLibraryItems?: () => <a href="https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L253">LibraryItemsSource</a><br/>
excalidrawAPI: <a href="https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/types.ts#L494">ExcalidrawAPI</a>,<br/>&nbsp;
getInitialLibraryItems?: () => <a href="https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/types.ts#L253">LibraryItemsSource</a><br/>
});
</pre>
@@ -251,7 +253,7 @@ This function returns the current `scene` version.
**_Signature_**
<pre>
getSceneVersion(elements: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/element/types.ts#L114">ExcalidrawElement[]</a>)
getSceneVersion(elements: <a href="https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/element/types.ts#L114">ExcalidrawElement[]</a>)
</pre>
**How to use**
@@ -272,7 +274,7 @@ import { sceneCoordsToViewportCoords } from "@excalidraw/excalidraw";
<pre>
sceneCoordsToViewportCoords(&#123; sceneX: number, sceneY: number },<br/>&nbsp;
appState: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L95">AppState</a><br/>): &#123; x: number, y: number }
appState: <a href="https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/types.ts#L95">AppState</a><br/>): &#123; x: number, y: number }
</pre>
### viewportCoordsToSceneCoords
@@ -287,7 +289,7 @@ import { viewportCoordsToSceneCoords } from "@excalidraw/excalidraw";
<pre>
viewportCoordsToSceneCoords(&#123; clientX: number, clientY: number },<br/>&nbsp;
appState: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L95">AppState</a><br/>): &#123;x: number, y: number}
appState: <a href="https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/types.ts#L95">AppState</a><br/>): &#123;x: number, y: number}
</pre>
### useDevice
@@ -299,7 +301,7 @@ Open the `main menu` in the below example to view the footer.
```jsx live noInline
const MobileFooter = ({}) => {
const device = useDevice();
if (device.isMobile) {
if (device.editor.isMobile) {
return (
<Footer>
<button
@@ -331,14 +333,15 @@ const App = () => (
render(<App />);
```
The `device` has the following `attributes`
The `device` has the following `attributes`, some grouped into `viewport` and `editor` objects, per context.
| Name | Type | Description |
| --- | --- | --- |
| `isSmScreen` | `boolean` | Set to `true` when the device small screen is small (Width < `640px` ) |
| `isMobile` | `boolean` | Set to `true` when the device is `mobile` |
| `isTouchScreen` | `boolean` | Set to `true` for `touch` devices |
| `canDeviceFitSidebar` | `boolean` | Implies whether there is enough space to fit the `sidebar` |
| `viewport.isMobile` | `boolean` | Set to `true` when viewport is in `mobile` breakpoint |
| `viewport.isLandscape` | `boolean` | Set to `true` when the viewport is in `landscape` mode |
| `editor.canFitSidebar` | `boolean` | Set to `true` if there's enough space to fit the `sidebar` |
| `editor.isMobile` | `boolean` | Set to `true` when editor container is in `mobile` breakpoint |
| `isTouchScreen` | `boolean` | Set to `true` for `touch` when touch event detected |
### i18n
@@ -347,8 +350,8 @@ To help with localization, we export the following.
| name | type |
| --- | --- |
| `defaultLang` | `string` |
| `languages` | [`Language[]`](https://github.com/excalidraw/excalidraw/blob/master/src/i18n.ts#L15) |
| `useI18n` | [`() => { langCode, t }`](https://github.com/excalidraw/excalidraw/blob/master/src/i18n.ts#L15) |
| `languages` | [`Language[]`](https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/i18n.ts#L15) |
| `useI18n` | [`() => { langCode, t }`](https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/i18n.ts#L15) |
```js
import { defaultLang, languages, useI18n } from "@excalidraw/excalidraw";
@@ -383,3 +386,94 @@ function App() {
);
}
```
### getCommonBounds
This util can be used to get the common bounds of the passed elements.
**_Signature_**
```ts
getCommonBounds(
elements: readonly ExcalidrawElement[]
): readonly [
minX: number,
minY: number,
maxX: number,
maxY: number,
]
```
**_How to use_**
```js
import { getCommonBounds } from "@excalidraw/excalidraw";
```
### elementsOverlappingBBox
To filter `elements` that are inside, overlap, or contain the `bounds` rectangle.
The bounds check is approximate and does not precisely follow the element's shape. You can also supply `errorMargin` which effectively makes the `bounds` larger by that amount.
This API has 3 `type`s of operation: `overlap`, `contain`, and `inside`:
- `overlap` - filters elements that are overlapping or inside bounds.
- `contain` - filters elements that are inside bounds or bounds inside elements.
- `inside` - filters elements that are inside bounds.
**_Signature_**
<pre>
elementsOverlappingBBox(<br/>&nbsp;
elements: readonly NonDeletedExcalidrawElement[];<br/>&nbsp;
bounds: <a href="https://github.com/excalidraw/excalidraw/blob/9c425224c789d083bf16e0597ce4a429b9ee008e/src/element/bounds.ts#L37-L42">Bounds</a> | ExcalidrawElement;<br/>&nbsp;
errorMargin?: number;<br/>&nbsp;
type: "overlap" | "contain" | "inside";<br/>
): NonDeletedExcalidrawElement[];
</pre>
**_How to use_**
```js
import { elementsOverlappingBBox } from "@excalidraw/excalidraw";
```
### isElementInsideBBox
Lower-level API than `elementsOverlappingBBox` to check if a single `element` is inside `bounds`. If `eitherDirection=true`, returns `true` if `element` is fully inside `bounds` rectangle, or vice versa. When `false`, it returns `true` only for the former case.
**_Signature_**
<pre>
isElementInsideBBox(<br/>&nbsp;
element: NonDeletedExcalidrawElement,<br/>&nbsp;
bounds: <a href="https://github.com/excalidraw/excalidraw/blob/9c425224c789d083bf16e0597ce4a429b9ee008e/src/element/bounds.ts#L37-L42">Bounds</a>,<br/>&nbsp;
eitherDirection = false,<br/>
): boolean
</pre>
**_How to use_**
```js
import { isElementInsideBBox } from "@excalidraw/excalidraw";
```
### elementPartiallyOverlapsWithOrContainsBBox
Checks if `element` is overlapping the `bounds` rectangle, or is fully inside.
**_Signature_**
<pre>
elementPartiallyOverlapsWithOrContainsBBox(<br/>&nbsp;
element: NonDeletedExcalidrawElement,<br/>&nbsp;
bounds: <a href="https://github.com/excalidraw/excalidraw/blob/9c425224c789d083bf16e0597ce4a429b9ee008e/src/element/bounds.ts#L37-L42">Bounds</a>,<br/>
): boolean
</pre>
**_How to use_**
```js
import { elementPartiallyOverlapsWithOrContainsBBox } from "@excalidraw/excalidraw";
```

View File

@@ -21,7 +21,7 @@ Most notably, you can customize the primary colors, by overriding these variable
- `--color-primary-light`
- `--color-primary-contrast-offset` — a slightly darker (in light mode), or lighter (in dark mode) `--color-primary` color to fix contrast issues (see [Chubb illusion](https://en.wikipedia.org/wiki/Chubb_illusion)). It will fall back to `--color-primary` if not present.
For a complete list of variables, check [theme.scss](https://github.com/excalidraw/excalidraw/blob/master/src/css/theme.scss), though most of them will not make sense to override.
For a complete list of variables, check [theme.scss](https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/css/theme.scss), though most of them will not make sense to override.
```css showLineNumbers
.custom-styles .excalidraw {

View File

@@ -13,7 +13,7 @@ To start the example app using the `@excalidraw/excalidraw` package, follow the
1. Install the dependencies
```bash
cd src/packages/excalidraw && yarn
cd packages/excalidraw && yarn
```
2. Start the example app
@@ -43,7 +43,7 @@ Once the version is released `@excalibot` will post a comment with the release v
To release the next stable version follow the below steps:
```bash
yarn prerelease version
yarn prerelease:excalidraw
```
You need to pass the `version` for which you want to create the release. This will make the changes needed before making the release like updating `package.json`, `changelog` and more.
@@ -51,7 +51,7 @@ You need to pass the `version` for which you want to create the release. This wi
The next step is to run the `release` script:
```bash
yarn release
yarn release:excalidraw
```
This will publish the package.

View File

@@ -31,6 +31,17 @@ We strongly recommend turning it off. You can follow the steps below on how to d
If disabling this setting doesn't fix the display of text elements, please consider opening an [issue](https://github.com/excalidraw/excalidraw/issues/new) on our GitHub, or message us on [Discord](https://discord.gg/UexuTaE).
### ReferenceError: process is not defined
When using `vite` or any build tools, you will have to make sure the `process` is accessible as we are accessing `process.env.IS_PREACT` to decide whether to use `preact` build.
Since Vite removes env variables by default, you can update the vite config to ensure its available :point_down:
```
define: {
"process.env.IS_PREACT": JSON.stringify("true"),
},
```
## Need help?

View File

@@ -30,25 +30,131 @@ function App() {
}
```
### Rendering Excalidraw only on client
### Next.js
Since _Excalidraw_ doesn't support server side rendering, you should render the component once the host is `mounted`.
Since Excalidraw doesn't support `server side rendering` so it should be rendered only on `client`. The way to achieve this in next.js is using `next.js dynamic import`.
The following workflow shows one way how to render Excalidraw on Next.js. We'll add more detailed and alternative Next.js examples, soon.
If you want to only import `Excalidraw` component you can do :point_down:
```jsx showLineNumbers
import { useState, useEffect } from "react";
import dynamic from "next/dynamic";
const Excalidraw = dynamic(
async () => (await import("@excalidraw/excalidraw")).Excalidraw,
{
ssr: false,
},
);
export default function App() {
const [Excalidraw, setExcalidraw] = useState(null);
useEffect(() => {
import("@excalidraw/excalidraw").then((comp) => setExcalidraw(comp.Excalidraw));
}, []);
return <>{Excalidraw && <Excalidraw />}</>;
return <Excalidraw />;
}
```
However the above component only works for named component exports. If you want to import some util / constant or something else apart from Excalidraw, then this approach will not work. Instead you can write a wrapper over Excalidraw and import the wrapper dynamically.
If you are using `pages router` then importing the wrapper dynamically would work, where as if you are using `app router` then you will have to also add `useClient` directive on top of the file in addition to dynamically importing the wrapper as shown :point_down:
<Tabs>
<TabItem value="Excalidraw Wrapper" label="Excalidraw Wrapper" >
```jsx showLineNumbers
"use client";
import { Excalidraw, convertToExcalidrawElements } from "@excalidraw/excalidraw";
import "@excalidraw/excalidraw/index.css";
const ExcalidrawWrapper: React.FC = () => {
console.info(convertToExcalidrawElements([{
type: "rectangle",
id: "rect-1",
width: 186.47265625,
height: 141.9765625,
},]));
return (
<div style={{height:"500px", width:"500px"}}>
<Excalidraw />
</div>
);
};
export default ExcalidrawWrapper;
```
</TabItem>
<TabItem value="pages" label="Pages router">
```jsx showLineNumbers
import dynamic from "next/dynamic";
// Since client components get prerenderd on server as well hence importing
// the excalidraw stuff dynamically with ssr false
const ExcalidrawWrapper = dynamic(
async () => (await import("../excalidrawWrapper")).default,
{
ssr: false,
},
);
export default function Page() {
return (
<ExcalidrawWrapper />
);
}
```
</TabItem>
<TabItem value="app" label="App router">
```jsx showLineNumbers
import dynamic from "next/dynamic";
// Since client components get prerenderd on server as well hence importing
// the excalidraw stuff dynamically with ssr false
const ExcalidrawWrapper = dynamic(
async () => (await import("../excalidrawWrapper")).default,
{
ssr: false,
},
);
export default function Page() {
return (
<ExcalidrawWrapper />
);
}
```
</TabItem>
</Tabs>
Here is a [source code](https://github.com/excalidraw/excalidraw/tree/master/examples/excalidraw/with-nextjs) for the example with app and pages router. You you can try it out [here](https://excalidraw-package-example-with-nextjs-gh6smrdnq-excalidraw.vercel.app/).
The `types` are available at `@excalidraw/excalidraw/types`, you can view [example for typescript](https://codesandbox.io/s/excalidraw-types-9h2dm)
### Preact
Since we support `umd` build ships with `react/jsx-runtime` and `react-dom/client` inlined with the package. This conflicts with `Preact` and hence the build doesn't work directly with `Preact`.
However we have shipped a separate build for `Preact` so if you are using `Preact` you need to set `process.env.IS_PREACT` to `true` to use the `Preact` build.
Once the above `env` variable is set, you will be able to use the package in `Preact` as well.
:::info
When using `vite` or any build tools, you will have to make sure the `process` is accessible as we are accessing `process.env.IS_PREACT` to decide whether to use `preact` build.
Since Vite removes env variables by default, you can update the vite config to ensure its available :point_down:
```
define: {
"process.env.IS_PREACT": JSON.stringify("true"),
},
```
:::
## Browser
To use it in a browser directly:
@@ -99,7 +205,7 @@ import TabItem from "@theme/TabItem";
<h1>Excalidraw Embed Example</h1>
<div id="app"></div>
</div>
<script type="text/javascript" src="src/index.js"></script>
<script type="text/javascript" src="packages/excalidraw/index.js"></script>
</body>
</html>
```

View File

@@ -38,9 +38,9 @@ Add the diagram type in switch case in [`parseMermaid`](https://github.com/excal
## Writing the Excalidraw Skeleton Convertor
With the completion of previous step, we have all the data, now we need to transform it so to [ExcalidrawElementSkeleton](https://github.com/excalidraw/excalidraw/blob/master/src/data/transform.ts#L133) format.
With the completion of previous step, we have all the data, now we need to transform it so to [ExcalidrawElementSkeleton](https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/data/transform.ts#L133) format.
Similar to [`FlowChartToExcalidrawSkeletonConverter`](https://github.com/excalidraw/mermaid-to-excalidraw/blob/master/src/converter/types/flowchart.ts#L24), you have to write the `{{diagramType}}ToExcalidrawSkeletonConverter` which parses the data received in previous step and returns the [ExcalidrawElementSkeleton](https://github.com/excalidraw/excalidraw/blob/master/src/data/transform.ts#L133).
Similar to [`FlowChartToExcalidrawSkeletonConverter`](https://github.com/excalidraw/mermaid-to-excalidraw/blob/master/src/converter/types/flowchart.ts#L24), you have to write the `{{diagramType}}ToExcalidrawSkeletonConverter` which parses the data received in previous step and returns the [ExcalidrawElementSkeleton](https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/data/transform.ts#L133).
Thats it, you have added the new diagram type 🥳, now lets test it out!

View File

@@ -6,7 +6,7 @@ In this section we will be diving into how the [flowchart parser](https://github
![image](https://github.com/excalidraw/excalidraw/assets/11256141/2a097bbb-64bf-49d6-bf7f-21172bdb538d)
We use `diagram.parser.yy` attribute to parse the data. If you want to know more about how the `diagram.parse.yy` attribute looks like, you can check it [here](https://github.com/mermaid-js/mermaid/blob/00d06c7282a701849793680c1e97da1cfdfcce62/packages/mermaid/src/diagrams/flowchart/flowDb.js#L768), however for scope of flowchart we are using **3** APIs from this parser to compute `vertices`, `edges` and `clusters` as we need these data to transform to [ExcalidrawElementSkeleton](https://github.com/excalidraw/excalidraw/blob/master/src/data/transform.ts#L133C13-L133C38).
We use `diagram.parser.yy` attribute to parse the data. If you want to know more about how the `diagram.parse.yy` attribute looks like, you can check it [here](https://github.com/mermaid-js/mermaid/blob/00d06c7282a701849793680c1e97da1cfdfcce62/packages/mermaid/src/diagrams/flowchart/flowDb.js#L768), however for scope of flowchart we are using **3** APIs from this parser to compute `vertices`, `edges` and `clusters` as we need these data to transform to [ExcalidrawElementSkeleton](https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/data/transform.ts#L133C13-L133C38).
For computing `vertices` and `edge`s lets consider the below svg generated by mermaid
@@ -42,7 +42,7 @@ Considering the same example this is the response from the API
}
}
```
The dimensions and position is missing in this response and we need that to transform to [ExcalidrawElementSkeleton](https://github.com/excalidraw/excalidraw/blob/master/src/data/transform.ts#L133C13-L133C38), for this we have our own parser [`parseVertex`](https://github.com/excalidraw/mermaid-to-excalidraw/blob/master/src/parseMermaid.ts#L178) which takes the above response and uses the `svg` together to compute position, dimensions and cleans up the response.
The dimensions and position is missing in this response and we need that to transform to [ExcalidrawElementSkeleton](https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/data/transform.ts#L133C13-L133C38), for this we have our own parser [`parseVertex`](https://github.com/excalidraw/mermaid-to-excalidraw/blob/master/src/parseMermaid.ts#L178) which takes the above response and uses the `svg` together to compute position, dimensions and cleans up the response.
The final output from `parseVertex` looks like :point_down:

View File

@@ -55,11 +55,11 @@ If you want to understand how flowchart parser works, you can navigate to [Flowc
## Converting to ExcalidrawElementSkeleton
Now we have all the data, we just need to transform it to [ExcalidrawElementSkeleton](https://github.com/excalidraw/excalidraw/blob/master/src/data/transform.ts#L133C13-L133C38) API so it can be rendered in Excalidraw.
Now we have all the data, we just need to transform it to [ExcalidrawElementSkeleton](https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/data/transform.ts#L133C13-L133C38) API so it can be rendered in Excalidraw.
For this we have `converters` which takes the parsed mermaid data and gives back the Excalidraw Skeleton.
For Unsupported types, we have already mentioned above that we convert it to `dataURL` and return the ExcalidrawImageSkeleton.
For supported types, currently only flowchart, we have [flowchartConverter](https://github.com/excalidraw/mermaid-to-excalidraw/blob/master/src/converter/types/flowchart.ts#L24) which parses the data and converts to [ExcalidrawElementSkeleton](https://github.com/excalidraw/excalidraw/blob/master/src/data/transform.ts#L133C13-L133C38).
For supported types, currently only flowchart, we have [flowchartConverter](https://github.com/excalidraw/mermaid-to-excalidraw/blob/master/src/converter/types/flowchart.ts#L24) which parses the data and converts to [ExcalidrawElementSkeleton](https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/data/transform.ts#L133C13-L133C38).
![image](https://github.com/excalidraw/excalidraw/assets/11256141/00226e9d-043d-4a08-989a-3ad9d2a574f1)

View File

@@ -19,14 +19,4 @@ Frames should be ordered where frame children come first, followed by the frame
]
```
If not oredered correctly, the editor will still function, but the elements may not be rendered and clipped correctly. Further, the renderer relies on this ordering for performance optimizations.
# Arrows
An arrow can be a child of a frame only if it has no binding (either start or end) to any other element, regardless of whether the bound element is inside the frame or not.
This ensures that when an arrow is bound to an element outside the frame, it's rendered and behaves correctly.
Therefore, when an arrow (that's a child of a frame) gets bound to an element, it's automatically removed from the frame.
Bound-arrow is duplicated alongside a frame only if the arrow start is bound to an element within that frame.
If not ordered correctly, the editor will still function, but the elements may not be rendered and clipped correctly. Further, the renderer relies on this ordering for performance optimizations.

View File

@@ -52,15 +52,6 @@ Make sure the title starts with a semantic prefix:
- **chore**: Other changes that don't modify src or test files
- **revert**: Reverts a previous commit
### Changelog
Add a brief description of your pull request to the changelog located here: [changelog](https://github.com/excalidraw/excalidraw/blob/master/CHANGELOG.md)
Notes:
- Make sure to prepend to the section corresponding with the semantic prefix you selected in the title
- Link to your pull request - this will require updating the CHANGELOG _after_ creating the pull request
### Testing
Once you submit your pull request it will automatically be tested. Be sure to check the results of the test and fix any issues that arise.

View File

@@ -1,6 +1,11 @@
// @ts-check
// Note: type annotations allow type checking and IDEs autocompletion
// Set the env variable to false so the excalidraw npm package doesn't throw
// process undefined as docusaurus doesn't expose env variables by default
process.env.IS_PREACT = "false";
/** @type {import('@docusaurus/types').Config} */
const config = {
title: "Excalidraw developer docs",
@@ -36,10 +41,7 @@ const config = {
showLastUpdateTime: true,
},
theme: {
customCss: [
require.resolve("./src/css/custom.scss"),
require.resolve("../src/packages/excalidraw/example/App.scss"),
],
customCss: [require.resolve("./src/css/custom.scss")],
},
}),
],
@@ -139,7 +141,15 @@ const config = {
},
}),
themes: ["@docusaurus/theme-live-codeblock"],
plugins: ["docusaurus-plugin-sass"],
plugins: [
"docusaurus-plugin-sass",
[
"docusaurus2-dotenv",
{
systemvars: true,
},
],
],
};
module.exports = config;

View File

@@ -18,7 +18,7 @@
"@docusaurus/core": "2.2.0",
"@docusaurus/preset-classic": "2.2.0",
"@docusaurus/theme-live-codeblock": "2.2.0",
"@excalidraw/excalidraw": "0.15.2-eb020d0",
"@excalidraw/excalidraw": "0.17.0",
"@mdx-js/react": "^1.6.22",
"clsx": "^1.2.1",
"docusaurus-plugin-sass": "0.2.3",
@@ -30,6 +30,7 @@
"devDependencies": {
"@docusaurus/module-type-aliases": "2.0.0-rc.1",
"@tsconfig/docusaurus": "^1.0.5",
"docusaurus2-dotenv": "1.4.0",
"typescript": "^4.7.4"
},
"browserslist": {

View File

@@ -53,7 +53,7 @@ const sidebars = {
},
items: [
"@excalidraw/excalidraw/api/props/initialdata",
"@excalidraw/excalidraw/api/props/ref",
"@excalidraw/excalidraw/api/props/excalidraw-api",
"@excalidraw/excalidraw/api/props/render-props",
"@excalidraw/excalidraw/api/props/ui-options",
],

4
dev-docs/vercel.json Normal file
View File

@@ -0,0 +1,4 @@
{
"outputDirectory": "build",
"installCommand": "yarn install"
}

View File

@@ -1718,10 +1718,10 @@
url-loader "^4.1.1"
webpack "^5.73.0"
"@excalidraw/excalidraw@0.15.2-eb020d0":
version "0.15.2-eb020d0"
resolved "https://registry.yarnpkg.com/@excalidraw/excalidraw/-/excalidraw-0.15.2-eb020d0.tgz#25bd61e6f23da7c084fb16a3e0fe0dd9ad8e6533"
integrity sha512-TKGLzpOVqFQcwK1GFKTDXgg1s2U6tc5KE3qXuv87osbzOtftQn3x4+VH61vwdj11l00nEN80SMdXUC43T9uJqQ==
"@excalidraw/excalidraw@0.17.0":
version "0.17.0"
resolved "https://registry.yarnpkg.com/@excalidraw/excalidraw/-/excalidraw-0.17.0.tgz#3c64aa8e36406ac171b008cfecbdce5bb0755725"
integrity sha512-NzP22v5xMqxYW27ZtTHhiGFe7kE8NeBk45aoeM/mDSkXiOXPDH+PcvwzHRN/Ei+Vj/0sTPHxejn8bZyRWKGjXg==
"@hapi/hoek@^9.0.0":
version "9.3.0"
@@ -3567,6 +3567,13 @@ docusaurus-plugin-sass@0.2.3:
dependencies:
sass-loader "^10.1.1"
docusaurus2-dotenv@1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/docusaurus2-dotenv/-/docusaurus2-dotenv-1.4.0.tgz#9ab900e29de9081f9f1f28f7224ff63760385641"
integrity sha512-iWqem5fnBAyeBBtX75Fxp71uUAnwFaXzOmade8zAhN4vL3RG9m27sLSRwjJGVVgIkEo3esjGyCcTGTiCjfi+sg==
dependencies:
dotenv-webpack "1.7.0"
dom-converter@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/dom-converter/-/dom-converter-0.2.0.tgz#6721a9daee2e293682955b6afe416771627bb768"
@@ -3652,6 +3659,25 @@ dot-prop@^5.2.0:
dependencies:
is-obj "^2.0.0"
dotenv-defaults@^1.0.2:
version "1.1.1"
resolved "https://registry.yarnpkg.com/dotenv-defaults/-/dotenv-defaults-1.1.1.tgz#032c024f4b5906d9990eb06d722dc74cc60ec1bd"
integrity sha512-6fPRo9o/3MxKvmRZBD3oNFdxODdhJtIy1zcJeUSCs6HCy4tarUpd+G67UTU9tF6OWXeSPqsm4fPAB+2eY9Rt9Q==
dependencies:
dotenv "^6.2.0"
dotenv-webpack@1.7.0:
version "1.7.0"
resolved "https://registry.yarnpkg.com/dotenv-webpack/-/dotenv-webpack-1.7.0.tgz#4384d8c57ee6f405c296278c14a9f9167856d3a1"
integrity sha512-wwNtOBW/6gLQSkb8p43y0Wts970A3xtNiG/mpwj9MLUhtPCQG6i+/DSXXoNN7fbPCU/vQ7JjwGmgOeGZSSZnsw==
dependencies:
dotenv-defaults "^1.0.2"
dotenv@^6.2.0:
version "6.2.0"
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-6.2.0.tgz#941c0410535d942c8becf28d3f357dbd9d476064"
integrity sha512-HygQCKUBSFl8wKQZBSemMywRWcEDNidvNbjGVyZu3nbZ8qq9ubiPoGLMdRDpfSrpkkm9BXYFkpKxxFX38o/76w==
duplexer3@^0.1.4:
version "0.1.5"
resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.5.tgz#0b5e4d7bad5de8901ea4440624c8e1d20099217e"

View File

@@ -15,14 +15,23 @@
border-radius: 50%;
}
}
.app-title {
margin-block-start: 0.83em;
margin-block-end: 0.83em;
}
}
.button-wrapper button {
z-index: 1;
height: 40px;
max-width: 200px;
margin: 10px;
padding: 5px;
.button-wrapper {
input[type="checkbox"] {
margin: 5px;
}
button {
z-index: 1;
height: 40px;
max-width: 200px;
margin: 10px;
padding: 5px;
}
}
.excalidraw .App-menu_top .buttonList {

View File

@@ -1,23 +1,31 @@
import { useEffect, useState, useRef, useCallback } from "react";
import React, {
useEffect,
useState,
useRef,
useCallback,
Children,
cloneElement,
} from "react";
import ExampleSidebar from "./sidebar/ExampleSidebar";
import type * as TExcalidraw from "../index";
import type * as TExcalidraw from "@excalidraw/excalidraw";
import "./App.scss";
import initialData from "./initialData";
import { nanoid } from "nanoid";
import {
resolvablePromise,
ResolvablePromise,
distance2d,
fileOpen,
withBatchedUpdates,
withBatchedUpdatesThrottled,
} from "../../../utils";
import { EVENT, ROUNDNESS } from "../../../constants";
import { distance2d } from "../../../math";
import { fileOpen } from "../../../data/filesystem";
import { loadSceneOrLibraryFromBlob } from "../../utils";
import {
} from "../utils";
import CustomFooter from "./CustomFooter";
import MobileFooter from "./MobileFooter";
import initialData from "../initialData";
import type {
AppState,
BinaryFileData,
ExcalidrawImperativeAPI,
@@ -25,18 +33,14 @@ import {
Gesture,
LibraryItems,
PointerDownState as ExcalidrawPointerDownState,
} from "../../../types";
import { NonDeletedExcalidrawElement, Theme } from "../../../element/types";
import { ImportedLibraryData } from "../../../data/types";
import CustomFooter from "./CustomFooter";
import MobileFooter from "./MobileFooter";
import { KEYS } from "../../../keys";
} from "@excalidraw/excalidraw/dist/excalidraw/types";
import type {
NonDeletedExcalidrawElement,
Theme,
} from "@excalidraw/excalidraw/dist/excalidraw/element/types";
import type { ImportedLibraryData } from "@excalidraw/excalidraw/dist/excalidraw/data/types";
declare global {
interface Window {
ExcalidrawLib: typeof TExcalidraw;
}
}
import "./App.scss";
type Comment = {
x: number;
@@ -57,27 +61,6 @@ type PointerDownState = {
};
};
// This is so that we use the bundled excalidraw.development.js file instead
// of the actual source code
const {
exportToCanvas,
exportToSvg,
exportToBlob,
exportToClipboard,
Excalidraw,
useHandleLibrary,
MIME_TYPES,
sceneCoordsToViewportCoords,
viewportCoordsToSceneCoords,
restoreElements,
Sidebar,
Footer,
WelcomeScreen,
MainMenu,
LiveCollaborationTrigger,
convertToExcalidrawElements,
} = window.ExcalidrawLib;
const COMMENT_ICON_DIMENSION = 32;
const COMMENT_INPUT_HEIGHT = 50;
const COMMENT_INPUT_WIDTH = 150;
@@ -86,9 +69,38 @@ export interface AppProps {
appTitle: string;
useCustom: (api: ExcalidrawImperativeAPI | null, customArgs?: any[]) => void;
customArgs?: any[];
children: React.ReactNode;
excalidrawLib: typeof TExcalidraw;
}
export default function App({ appTitle, useCustom, customArgs }: AppProps) {
export default function App({
appTitle,
useCustom,
customArgs,
children,
excalidrawLib,
}: AppProps) {
const {
exportToCanvas,
exportToSvg,
exportToBlob,
exportToClipboard,
useHandleLibrary,
MIME_TYPES,
sceneCoordsToViewportCoords,
viewportCoordsToSceneCoords,
restoreElements,
Sidebar,
Footer,
WelcomeScreen,
MainMenu,
LiveCollaborationTrigger,
convertToExcalidrawElements,
TTDDialog,
TTDDialogTrigger,
ROUNDNESS,
loadSceneOrLibraryFromBlob,
} = excalidrawLib;
const appRef = useRef<any>(null);
const [viewModeEnabled, setViewModeEnabled] = useState(false);
const [zenModeEnabled, setZenModeEnabled] = useState(false);
@@ -98,6 +110,7 @@ export default function App({ appTitle, useCustom, customArgs }: AppProps) {
const [exportWithDarkMode, setExportWithDarkMode] = useState(false);
const [exportEmbedScene, setExportEmbedScene] = useState(false);
const [theme, setTheme] = useState<Theme>("light");
const [disableImageTool, setDisableImageTool] = useState(false);
const [isCollaborating, setIsCollaborating] = useState(false);
const [commentIcons, setCommentIcons] = useState<{ [id: string]: Comment }>(
{},
@@ -149,8 +162,105 @@ export default function App({ appTitle, useCustom, customArgs }: AppProps) {
};
};
fetchData();
}, [excalidrawAPI]);
}, [excalidrawAPI, convertToExcalidrawElements, MIME_TYPES]);
const renderExcalidraw = (children: React.ReactNode) => {
const Excalidraw: any = Children.toArray(children).find(
(child) =>
React.isValidElement(child) &&
typeof child.type !== "string" &&
//@ts-ignore
child.type.displayName === "Excalidraw",
);
if (!Excalidraw) {
return;
}
const newElement = cloneElement(
Excalidraw,
{
excalidrawAPI: (api: ExcalidrawImperativeAPI) => setExcalidrawAPI(api),
initialData: initialStatePromiseRef.current.promise,
onChange: (
elements: NonDeletedExcalidrawElement[],
state: AppState,
) => {
console.info("Elements :", elements, "State : ", state);
},
onPointerUpdate: (payload: {
pointer: { x: number; y: number };
button: "down" | "up";
pointersMap: Gesture["pointers"];
}) => setPointerData(payload),
viewModeEnabled,
zenModeEnabled,
gridModeEnabled,
theme,
name: "Custom name of drawing",
UIOptions: {
canvasActions: {
loadScene: false,
},
tools: { image: !disableImageTool },
},
renderTopRightUI,
onLinkOpen,
onPointerDown,
onScrollChange: rerenderCommentIcons,
validateEmbeddable: true,
},
<>
{excalidrawAPI && (
<Footer>
<CustomFooter
excalidrawAPI={excalidrawAPI}
excalidrawLib={excalidrawLib}
/>
</Footer>
)}
<WelcomeScreen />
<Sidebar name="custom">
<Sidebar.Tabs>
<Sidebar.Header />
<Sidebar.Tab tab="one">Tab one!</Sidebar.Tab>
<Sidebar.Tab tab="two">Tab two!</Sidebar.Tab>
<Sidebar.TabTriggers>
<Sidebar.TabTrigger tab="one">One</Sidebar.TabTrigger>
<Sidebar.TabTrigger tab="two">Two</Sidebar.TabTrigger>
</Sidebar.TabTriggers>
</Sidebar.Tabs>
</Sidebar>
<Sidebar.Trigger
name="custom"
tab="one"
style={{
position: "absolute",
left: "50%",
transform: "translateX(-50%)",
bottom: "20px",
zIndex: 9999999999999999,
}}
>
Toggle Custom Sidebar
</Sidebar.Trigger>
{renderMenu()}
{excalidrawAPI && (
<TTDDialogTrigger icon={<span>😀</span>}>
Text to diagram
</TTDDialogTrigger>
)}
<TTDDialog
onTextSubmit={async (_) => {
console.info("submit");
// sleep for 2s
await new Promise((resolve) => setTimeout(resolve, 2000));
throw new Error("error, go away now");
// return "dummy";
}}
/>
</>,
);
return newElement;
};
const renderTopRightUI = (isMobile: boolean) => {
return (
<>
@@ -334,8 +444,8 @@ export default function App({ appTitle, useCustom, customArgs }: AppProps) {
pointerDownState: PointerDownState,
) => {
return withBatchedUpdates((event) => {
window.removeEventListener(EVENT.POINTER_MOVE, pointerDownState.onMove);
window.removeEventListener(EVENT.POINTER_UP, pointerDownState.onUp);
window.removeEventListener("pointermove", pointerDownState.onMove);
window.removeEventListener("pointerup", pointerDownState.onUp);
excalidrawAPI?.setActiveTool({ type: "selection" });
const distance = distance2d(
pointerDownState.x,
@@ -399,8 +509,8 @@ export default function App({ appTitle, useCustom, customArgs }: AppProps) {
onPointerMoveFromPointerDownHandler(pointerDownState);
const onPointerUp =
onPointerUpFromPointerDownHandler(pointerDownState);
window.addEventListener(EVENT.POINTER_MOVE, onPointerMove);
window.addEventListener(EVENT.POINTER_UP, onPointerUp);
window.addEventListener("pointermove", onPointerMove);
window.addEventListener("pointerup", onPointerUp);
pointerDownState.onMove = onPointerMove;
pointerDownState.onUp = onPointerUp;
@@ -492,7 +602,7 @@ export default function App({ appTitle, useCustom, customArgs }: AppProps) {
}}
onBlur={saveComment}
onKeyDown={(event) => {
if (!event.shiftKey && event.key === KEYS.ENTER) {
if (!event.shiftKey && event.key === "Enter") {
event.preventDefault();
saveComment();
}
@@ -525,7 +635,12 @@ export default function App({ appTitle, useCustom, customArgs }: AppProps) {
</MainMenu.ItemCustom>
<MainMenu.DefaultItems.Help />
{excalidrawAPI && <MobileFooter excalidrawAPI={excalidrawAPI} />}
{excalidrawAPI && (
<MobileFooter
excalidrawLib={excalidrawLib}
excalidrawAPI={excalidrawAPI}
/>
)}
</MainMenu>
);
};
@@ -606,6 +721,16 @@ export default function App({ appTitle, useCustom, customArgs }: AppProps) {
/>
Switch to Dark Theme
</label>
<label>
<input
type="checkbox"
checked={disableImageTool === true}
onChange={() => {
setDisableImageTool(!disableImageTool);
}}
/>
Disable Image Tool
</label>
<label>
<input
type="checkbox"
@@ -664,66 +789,7 @@ export default function App({ appTitle, useCustom, customArgs }: AppProps) {
</div>
</div>
<div className="excalidraw-wrapper">
<Excalidraw
ref={(api: ExcalidrawImperativeAPI) => setExcalidrawAPI(api)}
initialData={initialStatePromiseRef.current.promise}
onChange={(elements, state) => {
console.info("Elements :", elements, "State : ", state);
}}
onPointerUpdate={(payload: {
pointer: { x: number; y: number };
button: "down" | "up";
pointersMap: Gesture["pointers"];
}) => setPointerData(payload)}
viewModeEnabled={viewModeEnabled}
zenModeEnabled={zenModeEnabled}
gridModeEnabled={gridModeEnabled}
theme={theme}
name="Custom name of drawing"
UIOptions={{
canvasActions: {
loadScene: false,
},
}}
renderTopRightUI={renderTopRightUI}
onLinkOpen={onLinkOpen}
onPointerDown={onPointerDown}
onScrollChange={rerenderCommentIcons}
// allow all urls
validateEmbeddable={true}
>
{excalidrawAPI && (
<Footer>
<CustomFooter excalidrawAPI={excalidrawAPI} />
</Footer>
)}
<WelcomeScreen />
<Sidebar name="custom">
<Sidebar.Tabs>
<Sidebar.Header />
<Sidebar.Tab tab="one">Tab one!</Sidebar.Tab>
<Sidebar.Tab tab="two">Tab two!</Sidebar.Tab>
<Sidebar.TabTriggers>
<Sidebar.TabTrigger tab="one">One</Sidebar.TabTrigger>
<Sidebar.TabTrigger tab="two">Two</Sidebar.TabTrigger>
</Sidebar.TabTriggers>
</Sidebar.Tabs>
</Sidebar>
<Sidebar.Trigger
name="custom"
tab="one"
style={{
position: "absolute",
left: "50%",
transform: "translateX(-50%)",
bottom: "20px",
zIndex: 9999999999999999,
}}
>
Toggle Custom Sidebar
</Sidebar.Trigger>
{renderMenu()}
</Excalidraw>
{renderExcalidraw(children)}
{Object.keys(commentIcons || []).length > 0 && renderCommentIcons()}
{comment && renderComment()}
</div>

View File

@@ -1,6 +1,5 @@
import { ExcalidrawImperativeAPI } from "../../../types";
import { MIME_TYPES } from "../entry";
import { Button } from "../../../components/Button";
import type * as TExcalidraw from "@excalidraw/excalidraw";
import type { ExcalidrawImperativeAPI } from "@excalidraw/excalidraw/dist/excalidraw/types";
const COMMENT_SVG = (
<svg
@@ -18,24 +17,28 @@ const COMMENT_SVG = (
<path d="M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8v.5z"></path>
</svg>
);
const CustomFooter = ({
excalidrawAPI,
excalidrawLib,
}: {
excalidrawAPI: ExcalidrawImperativeAPI;
excalidrawLib: typeof TExcalidraw;
}) => {
const { Button, MIME_TYPES } = excalidrawLib;
return (
<>
<Button
onSelect={() => alert("General Kenobi!")}
className="you are a bold one"
style={{ marginLeft: "1rem" }}
style={{ marginLeft: "1rem", width: "auto" }}
title="Hello there!"
>
{COMMENT_SVG}
Hit me
</Button>
<button
<Button
className="custom-element"
onClick={() => {
onSelect={() => {
excalidrawAPI?.setActiveTool({
type: "custom",
customType: "comment",
@@ -58,15 +61,10 @@ const CustomFooter = ({
)}`;
excalidrawAPI?.setCursor(`url(${url}), auto`);
}}
title="Comments!"
>
{COMMENT_SVG}
</button>
<button
className="custom-footer"
onClick={() => alert("This is dummy footer")}
>
custom footer
</button>
</Button>
</>
);
};

View File

@@ -0,0 +1,27 @@
import { ExcalidrawImperativeAPI } from "@excalidraw/excalidraw/dist/excalidraw/types";
import CustomFooter from "./CustomFooter";
import type * as TExcalidraw from "@excalidraw/excalidraw";
const MobileFooter = ({
excalidrawAPI,
excalidrawLib,
}: {
excalidrawAPI: ExcalidrawImperativeAPI;
excalidrawLib: typeof TExcalidraw;
}) => {
const { useDevice, Footer } = excalidrawLib;
const device = useDevice();
if (device.editor.isMobile) {
return (
<Footer>
<CustomFooter
excalidrawAPI={excalidrawAPI}
excalidrawLib={excalidrawLib}
/>
</Footer>
);
}
return null;
};
export default MobileFooter;

View File

@@ -1,5 +1,6 @@
import React, { useState } from "react";
import { useState } from "react";
import "./ExampleSidebar.scss";
export default function Sidebar({ children }: { children: React.ReactNode }) {
const [open, setOpen] = useState(false);

View File

@@ -1,5 +1,5 @@
import { ExcalidrawElementSkeleton } from "../../../data/transform";
import { FileId } from "../../../element/types";
import type { ExcalidrawElementSkeleton } from "@excalidraw/excalidraw/data/transform";
import type { FileId } from "@excalidraw/excalidraw/element/types";
const elements: ExcalidrawElementSkeleton[] = [
{
@@ -7,6 +7,7 @@ const elements: ExcalidrawElementSkeleton[] = [
x: 10,
y: 10,
strokeWidth: 2,
id: "1",
},
{
type: "diamond",
@@ -19,6 +20,7 @@ const elements: ExcalidrawElementSkeleton[] = [
strokeColor: "#099268",
fontSize: 30,
},
id: "2",
},
{
type: "arrow",
@@ -36,6 +38,11 @@ const elements: ExcalidrawElementSkeleton[] = [
height: 230,
fileId: "rocket" as FileId,
},
{
type: "frame",
children: ["1", "2"],
name: "My frame",
},
];
export default {
elements,

View File

@@ -0,0 +1,13 @@
{
"name": "examples",
"version": "1.0.0",
"private": true,
"dependencies": {
"react": "18.2.0",
"react-dom": "18.2.0",
"@excalidraw/excalidraw": "*"
},
"devDependencies": {
"typescript": "^5"
}
}

View File

@@ -0,0 +1,3 @@
{
"extends": "../../tsconfig"
}

View File

@@ -0,0 +1,146 @@
import { unstable_batchedUpdates } from "react-dom";
import { fileOpen as _fileOpen } from "browser-fs-access";
import type { MIME_TYPES } from "@excalidraw/excalidraw";
import { AbortError } from "../../packages/excalidraw/errors";
type FILE_EXTENSION = Exclude<keyof typeof MIME_TYPES, "binary">;
const INPUT_CHANGE_INTERVAL_MS = 500;
export type ResolvablePromise<T> = Promise<T> & {
resolve: [T] extends [undefined] ? (value?: T) => void : (value: T) => void;
reject: (error: Error) => void;
};
export const resolvablePromise = <T>() => {
let resolve!: any;
let reject!: any;
const promise = new Promise((_resolve, _reject) => {
resolve = _resolve;
reject = _reject;
});
(promise as any).resolve = resolve;
(promise as any).reject = reject;
return promise as ResolvablePromise<T>;
};
export const distance2d = (x1: number, y1: number, x2: number, y2: number) => {
const xd = x2 - x1;
const yd = y2 - y1;
return Math.hypot(xd, yd);
};
export const fileOpen = <M extends boolean | undefined = false>(opts: {
extensions?: FILE_EXTENSION[];
description: string;
multiple?: M;
}): Promise<M extends false | undefined ? File : File[]> => {
// an unsafe TS hack, alas not much we can do AFAIK
type RetType = M extends false | undefined ? File : File[];
const mimeTypes = opts.extensions?.reduce((mimeTypes, type) => {
mimeTypes.push(MIME_TYPES[type]);
return mimeTypes;
}, [] as string[]);
const extensions = opts.extensions?.reduce((acc, ext) => {
if (ext === "jpg") {
return acc.concat(".jpg", ".jpeg");
}
return acc.concat(`.${ext}`);
}, [] as string[]);
return _fileOpen({
description: opts.description,
extensions,
mimeTypes,
multiple: opts.multiple ?? false,
legacySetup: (resolve, reject, input) => {
const scheduleRejection = debounce(reject, INPUT_CHANGE_INTERVAL_MS);
const focusHandler = () => {
checkForFile();
document.addEventListener("keyup", scheduleRejection);
document.addEventListener("pointerup", scheduleRejection);
scheduleRejection();
};
const checkForFile = () => {
// this hack might not work when expecting multiple files
if (input.files?.length) {
const ret = opts.multiple ? [...input.files] : input.files[0];
resolve(ret as RetType);
}
};
requestAnimationFrame(() => {
window.addEventListener("focus", focusHandler);
});
const interval = window.setInterval(() => {
checkForFile();
}, INPUT_CHANGE_INTERVAL_MS);
return (rejectPromise) => {
clearInterval(interval);
scheduleRejection.cancel();
window.removeEventListener("focus", focusHandler);
document.removeEventListener("keyup", scheduleRejection);
document.removeEventListener("pointerup", scheduleRejection);
if (rejectPromise) {
// so that something is shown in console if we need to debug this
console.warn("Opening the file was canceled (legacy-fs).");
rejectPromise(new AbortError());
}
};
},
}) as Promise<RetType>;
};
export const debounce = <T extends any[]>(
fn: (...args: T) => void,
timeout: number,
) => {
let handle = 0;
let lastArgs: T | null = null;
const ret = (...args: T) => {
lastArgs = args;
clearTimeout(handle);
handle = window.setTimeout(() => {
lastArgs = null;
fn(...args);
}, timeout);
};
ret.flush = () => {
clearTimeout(handle);
if (lastArgs) {
const _lastArgs = lastArgs;
lastArgs = null;
fn(..._lastArgs);
}
};
ret.cancel = () => {
lastArgs = null;
clearTimeout(handle);
};
return ret;
};
export const withBatchedUpdates = <
TFunction extends ((event: any) => void) | (() => void),
>(
func: Parameters<TFunction>["length"] extends 0 | 1 ? TFunction : never,
) =>
((event) => {
unstable_batchedUpdates(func as TFunction, event);
}) as TFunction;
/**
* barches React state updates and throttles the calls to a single call per
* animation frame
*/
export const withBatchedUpdatesThrottled = <
TFunction extends ((event: any) => void) | (() => void),
>(
func: Parameters<TFunction>["length"] extends 0 | 1 ? TFunction : never,
) => {
// @ts-ignore
return throttleRAF<Parameters<TFunction>>(((event) => {
unstable_batchedUpdates(func, event);
}) as TFunction);
};

View File

@@ -0,0 +1,36 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/.pnp
.pnp.js
.yarn/install-state.gz
# testing
/coverage
# next.js
/.next/
/out/
# production
/build
# misc
.DS_Store
*.pem
# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# local env files
.env*.local
# vercel
.vercel
# typescript
*.tsbuildinfo
next-env.d.ts

View File

@@ -0,0 +1,36 @@
This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
## Getting Started
First, run the development server:
```bash
npm run dev
# or
yarn dev
# or
pnpm dev
# or
bun dev
```
Open [http://localhost:3000](http://localhost:3005) with your browser to see the result.
You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.
This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font.
## Learn More
To learn more about Next.js, take a look at the following resources:
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
## Deploy on Vercel
The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.

View File

@@ -0,0 +1,12 @@
/** @type {import('next').NextConfig} */
const nextConfig = {
distDir: "build",
typescript: {
// The ts config doesn't work with `jsx: preserve" and if updated to `react-jsx` it gets ovewritten by next js throwing ts errors hence I am ignoring build errors until this is fixed.
ignoreBuildErrors: true,
},
// This is needed as in pages router the code for importing types throws error as its outside next js app
transpilePackages: ["../"],
};
module.exports = nextConfig;

View File

@@ -0,0 +1,25 @@
{
"name": "with-nextjs",
"version": "0.1.0",
"private": true,
"scripts": {
"build:workspace": "yarn workspace @excalidraw/excalidraw run build:esm",
"dev": "yarn build:workspace && next dev -p 3005",
"build": "yarn build:workspace && next build",
"start": "next start -p 3006",
"lint": "next lint"
},
"dependencies": {
"@excalidraw/excalidraw": "*",
"next": "14.1",
"react": "^18",
"react-dom": "^18"
},
"devDependencies": {
"@types/node": "^20",
"@types/react": "^18",
"@types/react-dom": "^18",
"path2d-polyfill": "2.0.1",
"typescript": "^5"
}
}

View File

Before

Width:  |  Height:  |  Size: 197 KiB

After

Width:  |  Height:  |  Size: 197 KiB

View File

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 30 KiB

View File

Before

Width:  |  Height:  |  Size: 6.1 KiB

After

Width:  |  Height:  |  Size: 6.1 KiB

View File

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

View File

@@ -0,0 +1,11 @@
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en">
<body>{children}</body>
</html>
);
}

View File

@@ -0,0 +1,23 @@
import dynamic from "next/dynamic";
import "../common.scss";
// Since client components get prerenderd on server as well hence importing the excalidraw stuff dynamically
// with ssr false
const ExcalidrawWithClientOnly = dynamic(
async () => (await import("../excalidrawWrapper")).default,
{
ssr: false,
},
);
export default function Page() {
return (
<>
<a href="/excalidraw-in-pages">Switch to Pages router</a>
<h1 className="page-title">App Router</h1>
{/* @ts-expect-error - https://github.com/vercel/next.js/issues/42292 */}
<ExcalidrawWithClientOnly />
</>
);
}

View File

@@ -0,0 +1,15 @@
* {
box-sizing: border-box;
font-family: sans-serif;
}
a {
color: #1c7ed6;
font-size: 20px;
text-decoration: none;
font-weight: 550;
}
.page-title {
text-align: center;
}

View File

@@ -0,0 +1,22 @@
"use client";
import * as excalidrawLib from "@excalidraw/excalidraw";
import { Excalidraw } from "@excalidraw/excalidraw";
import App from "../../components/App";
import "@excalidraw/excalidraw/index.css";
const ExcalidrawWrapper: React.FC = () => {
return (
<>
<App
appTitle={"Excalidraw with Nextjs Example"}
useCustom={(api: any, args?: any[]) => {}}
excalidrawLib={excalidrawLib}
>
<Excalidraw />
</App>
</>
);
};
export default ExcalidrawWrapper;

View File

@@ -0,0 +1,22 @@
import dynamic from "next/dynamic";
import "../common.scss";
// Since client components get prerenderd on server as well hence importing the excalidraw stuff dynamically
// with ssr false
const Excalidraw = dynamic(
async () => (await import("../excalidrawWrapper")).default,
{
ssr: false,
},
);
export default function Page() {
return (
<>
<a href="/">Switch to App router</a>
<h1 className="page-title">Pages Router</h1>
{/* @ts-expect-error - https://github.com/vercel/next.js/issues/42292 */}
<Excalidraw />
</>
);
}

View File

@@ -0,0 +1,28 @@
{
"compilerOptions": {
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"incremental": true,
"plugins": [
{
"name": "next"
}
],
"paths": {
"@/*": ["./src/*"]
},
"forceConsistentCasingInFileNames": true
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts", "build/types/**/*.ts"],
"exclude": ["node_modules"]
}

View File

@@ -0,0 +1,3 @@
{
"outputDirectory": "build"
}

View File

@@ -0,0 +1,252 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
"@excalidraw/excalidraw@workspace:^":
version "0.17.2"
resolved "https://registry.yarnpkg.com/@excalidraw/excalidraw/-/excalidraw-0.17.2.tgz#9a636a1e6bb3c88c5883347d3a7e75e9cce8ab96"
integrity sha512-7pqUWD8+mPjDhF4XxG3gw4rvE2JGaLW3Vss5UZfTbITPxAtFaGEc1K081bncitnaYhUwN9ENJE0i87QB3poDwQ==
"@next/env@14.0.4":
version "14.0.4"
resolved "https://registry.yarnpkg.com/@next/env/-/env-14.0.4.tgz#d5cda0c4a862d70ae760e58c0cd96a8899a2e49a"
integrity sha512-irQnbMLbUNQpP1wcE5NstJtbuA/69kRfzBrpAD7Gsn8zm/CY6YQYc3HQBz8QPxwISG26tIm5afvvVbu508oBeQ==
"@next/swc-darwin-arm64@14.0.4":
version "14.0.4"
resolved "https://registry.yarnpkg.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.0.4.tgz#27b1854c2cd04eb1d5e75081a1a792ad91526618"
integrity sha512-mF05E/5uPthWzyYDyptcwHptucf/jj09i2SXBPwNzbgBNc+XnwzrL0U6BmPjQeOL+FiB+iG1gwBeq7mlDjSRPg==
"@next/swc-darwin-x64@14.0.4":
version "14.0.4"
resolved "https://registry.yarnpkg.com/@next/swc-darwin-x64/-/swc-darwin-x64-14.0.4.tgz#9940c449e757d0ee50bb9e792d2600cc08a3eb3b"
integrity sha512-IZQ3C7Bx0k2rYtrZZxKKiusMTM9WWcK5ajyhOZkYYTCc8xytmwSzR1skU7qLgVT/EY9xtXDG0WhY6fyujnI3rw==
"@next/swc-linux-arm64-gnu@14.0.4":
version "14.0.4"
resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.0.4.tgz#0eafd27c8587f68ace7b4fa80695711a8434de21"
integrity sha512-VwwZKrBQo/MGb1VOrxJ6LrKvbpo7UbROuyMRvQKTFKhNaXjUmKTu7wxVkIuCARAfiI8JpaWAnKR+D6tzpCcM4w==
"@next/swc-linux-arm64-musl@14.0.4":
version "14.0.4"
resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.0.4.tgz#2b0072adb213f36dada5394ea67d6e82069ae7dd"
integrity sha512-8QftwPEW37XxXoAwsn+nXlodKWHfpMaSvt81W43Wh8dv0gkheD+30ezWMcFGHLI71KiWmHK5PSQbTQGUiidvLQ==
"@next/swc-linux-x64-gnu@14.0.4":
version "14.0.4"
resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.0.4.tgz#68c67d20ebc8e3f6ced6ff23a4ba2a679dbcec32"
integrity sha512-/s/Pme3VKfZAfISlYVq2hzFS8AcAIOTnoKupc/j4WlvF6GQ0VouS2Q2KEgPuO1eMBwakWPB1aYFIA4VNVh667A==
"@next/swc-linux-x64-musl@14.0.4":
version "14.0.4"
resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.0.4.tgz#67cd81b42fb2caf313f7992fcf6d978af55a1247"
integrity sha512-m8z/6Fyal4L9Bnlxde5g2Mfa1Z7dasMQyhEhskDATpqr+Y0mjOBZcXQ7G5U+vgL22cI4T7MfvgtrM2jdopqWaw==
"@next/swc-win32-arm64-msvc@14.0.4":
version "14.0.4"
resolved "https://registry.yarnpkg.com/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.0.4.tgz#be06585906b195d755ceda28f33c633e1443f1a3"
integrity sha512-7Wv4PRiWIAWbm5XrGz3D8HUkCVDMMz9igffZG4NB1p4u1KoItwx9qjATHz88kwCEal/HXmbShucaslXCQXUM5w==
"@next/swc-win32-ia32-msvc@14.0.4":
version "14.0.4"
resolved "https://registry.yarnpkg.com/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.0.4.tgz#e76cabefa9f2d891599c3d85928475bd8d3f6600"
integrity sha512-zLeNEAPULsl0phfGb4kdzF/cAVIfaC7hY+kt0/d+y9mzcZHsMS3hAS829WbJ31DkSlVKQeHEjZHIdhN+Pg7Gyg==
"@next/swc-win32-x64-msvc@14.0.4":
version "14.0.4"
resolved "https://registry.yarnpkg.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.0.4.tgz#e74892f1a9ccf41d3bf5979ad6d3d77c07b9cba1"
integrity sha512-yEh2+R8qDlDCjxVpzOTEpBLQTEFAcP2A8fUFLaWNap9GitYKkKv1//y2S6XY6zsR4rCOPRpU7plYDR+az2n30A==
"@swc/helpers@0.5.2":
version "0.5.2"
resolved "https://registry.yarnpkg.com/@swc/helpers/-/helpers-0.5.2.tgz#85ea0c76450b61ad7d10a37050289eded783c27d"
integrity sha512-E4KcWTpoLHqwPHLxidpOqQbcrZVgi0rsmmZXUle1jXmJfuIf/UWpczUJ7MZZ5tlxytgJXyp0w4PGkkeLiuIdZw==
dependencies:
tslib "^2.4.0"
"@types/node@^20":
version "20.11.0"
resolved "https://registry.yarnpkg.com/@types/node/-/node-20.11.0.tgz#8e0b99e70c0c1ade1a86c4a282f7b7ef87c9552f"
integrity sha512-o9bjXmDNcF7GbM4CNQpmi+TutCgap/K3w1JyKgxAjqx41zp9qlIAVFi0IhCNsJcXolEqLWhbFbEeL0PvYm4pcQ==
dependencies:
undici-types "~5.26.4"
"@types/prop-types@*":
version "15.7.11"
resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.11.tgz#2596fb352ee96a1379c657734d4b913a613ad563"
integrity sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==
"@types/react-dom@^18":
version "18.2.18"
resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.2.18.tgz#16946e6cd43971256d874bc3d0a72074bb8571dd"
integrity sha512-TJxDm6OfAX2KJWJdMEVTwWke5Sc/E/RlnPGvGfS0W7+6ocy2xhDVQVh/KvC2Uf7kACs+gDytdusDSdWfWkaNzw==
dependencies:
"@types/react" "*"
"@types/react@*", "@types/react@^18":
version "18.2.47"
resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.47.tgz#85074b27ab563df01fbc3f68dc64bf7050b0af40"
integrity sha512-xquNkkOirwyCgoClNk85BjP+aqnIS+ckAJ8i37gAbDs14jfW/J23f2GItAf33oiUPQnqNMALiFeoM9Y5mbjpVQ==
dependencies:
"@types/prop-types" "*"
"@types/scheduler" "*"
csstype "^3.0.2"
"@types/scheduler@*":
version "0.16.8"
resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.8.tgz#ce5ace04cfeabe7ef87c0091e50752e36707deff"
integrity sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==
busboy@1.6.0:
version "1.6.0"
resolved "https://registry.yarnpkg.com/busboy/-/busboy-1.6.0.tgz#966ea36a9502e43cdb9146962523b92f531f6893"
integrity sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==
dependencies:
streamsearch "^1.1.0"
caniuse-lite@^1.0.30001406:
version "1.0.30001576"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001576.tgz#893be772cf8ee6056d6c1e2d07df365b9ec0a5c4"
integrity sha512-ff5BdakGe2P3SQsMsiqmt1Lc8221NR1VzHj5jXN5vBny9A6fpze94HiVV/n7XRosOlsShJcvMv5mdnpjOGCEgg==
client-only@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/client-only/-/client-only-0.0.1.tgz#38bba5d403c41ab150bff64a95c85013cf73bca1"
integrity sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==
csstype@^3.0.2:
version "3.1.3"
resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.3.tgz#d80ff294d114fb0e6ac500fbf85b60137d7eff81"
integrity sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==
glob-to-regexp@^0.4.1:
version "0.4.1"
resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e"
integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==
graceful-fs@^4.1.2, graceful-fs@^4.2.11:
version "4.2.11"
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3"
integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==
"js-tokens@^3.0.0 || ^4.0.0":
version "4.0.0"
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==
loose-envify@^1.1.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==
dependencies:
js-tokens "^3.0.0 || ^4.0.0"
nanoid@^3.3.6:
version "3.3.7"
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.7.tgz#d0c301a691bc8d54efa0a2226ccf3fe2fd656bd8"
integrity sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==
next@14.0.4:
version "14.0.4"
resolved "https://registry.yarnpkg.com/next/-/next-14.0.4.tgz#bf00b6f835b20d10a5057838fa2dfced1d0d84dc"
integrity sha512-qbwypnM7327SadwFtxXnQdGiKpkuhaRLE2uq62/nRul9cj9KhQ5LhHmlziTNqUidZotw/Q1I9OjirBROdUJNgA==
dependencies:
"@next/env" "14.0.4"
"@swc/helpers" "0.5.2"
busboy "1.6.0"
caniuse-lite "^1.0.30001406"
graceful-fs "^4.2.11"
postcss "8.4.31"
styled-jsx "5.1.1"
watchpack "2.4.0"
optionalDependencies:
"@next/swc-darwin-arm64" "14.0.4"
"@next/swc-darwin-x64" "14.0.4"
"@next/swc-linux-arm64-gnu" "14.0.4"
"@next/swc-linux-arm64-musl" "14.0.4"
"@next/swc-linux-x64-gnu" "14.0.4"
"@next/swc-linux-x64-musl" "14.0.4"
"@next/swc-win32-arm64-msvc" "14.0.4"
"@next/swc-win32-ia32-msvc" "14.0.4"
"@next/swc-win32-x64-msvc" "14.0.4"
path2d-polyfill@2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/path2d-polyfill/-/path2d-polyfill-2.0.1.tgz#24c554a738f42700d6961992bf5f1049672f2391"
integrity sha512-ad/3bsalbbWhmBo0D6FZ4RNMwsLsPpL6gnvhuSaU5Vm7b06Kr5ubSltQQ0T7YKsiJQO+g22zJ4dJKNTXIyOXtA==
picocolors@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c"
integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==
postcss@8.4.31:
version "8.4.31"
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.31.tgz#92b451050a9f914da6755af352bdc0192508656d"
integrity sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==
dependencies:
nanoid "^3.3.6"
picocolors "^1.0.0"
source-map-js "^1.0.2"
react-dom@^18:
version "18.2.0"
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.2.0.tgz#22aaf38708db2674ed9ada224ca4aa708d821e3d"
integrity sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==
dependencies:
loose-envify "^1.1.0"
scheduler "^0.23.0"
react@^18:
version "18.2.0"
resolved "https://registry.yarnpkg.com/react/-/react-18.2.0.tgz#555bd98592883255fa00de14f1151a917b5d77d5"
integrity sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==
dependencies:
loose-envify "^1.1.0"
scheduler@^0.23.0:
version "0.23.0"
resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.23.0.tgz#ba8041afc3d30eb206a487b6b384002e4e61fdfe"
integrity sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==
dependencies:
loose-envify "^1.1.0"
source-map-js@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c"
integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==
streamsearch@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-1.1.0.tgz#404dd1e2247ca94af554e841a8ef0eaa238da764"
integrity sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==
styled-jsx@5.1.1:
version "5.1.1"
resolved "https://registry.yarnpkg.com/styled-jsx/-/styled-jsx-5.1.1.tgz#839a1c3aaacc4e735fed0781b8619ea5d0009d1f"
integrity sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw==
dependencies:
client-only "0.0.1"
tslib@^2.4.0:
version "2.6.2"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae"
integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==
typescript@^5:
version "5.3.3"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.3.3.tgz#b3ce6ba258e72e6305ba66f5c9b452aaee3ffe37"
integrity sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==
undici-types@~5.26.4:
version "5.26.5"
resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617"
integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==
watchpack@2.4.0:
version "2.4.0"
resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.4.0.tgz#fa33032374962c78113f93c7f2fb4c54c9862a5d"
integrity sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==
dependencies:
glob-to-regexp "^0.4.1"
graceful-fs "^4.1.2"

View File

@@ -12,18 +12,21 @@
<script>
window.name = "codesandbox";
</script>
<link rel="stylesheet" href="/dist/browser/dev/index.css" />
</head>
<body>
<noscript> You need to enable JavaScript to run this app. </noscript>
<div id="root"></div>
<script src="https://unpkg.com/react@18.2.0/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@18.2.0/umd/react-dom.development.js"></script>
<!-- This is so that we use the bundled excalidraw.development.js file instead
of the actual source code -->
<script src="./excalidraw.development.js"></script>
<script type="module">
import * as ExcalidrawLib from "@excalidraw/excalidraw";
<script src="./bundle.js"></script>
console.log(ExcalidrawLib);
window.ExcalidrawLib = ExcalidrawLib;
</script>
<script type="module" src="index.tsx"></script>
</body>
</html>

View File

@@ -0,0 +1,28 @@
import App from "../components/App";
import React, { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import type * as TExcalidraw from "@excalidraw/excalidraw";
import "@excalidraw/excalidraw/index.css";
declare global {
interface Window {
ExcalidrawLib: typeof TExcalidraw;
}
}
const rootElement = document.getElementById("root")!;
const root = createRoot(rootElement);
const { Excalidraw } = window.ExcalidrawLib;
root.render(
<StrictMode>
<App
appTitle={"Excalidraw Example"}
useCustom={(api: any, args?: any[]) => {}}
excalidrawLib={window.ExcalidrawLib}
>
<Excalidraw />
</App>
</StrictMode>,
);

View File

@@ -0,0 +1,19 @@
{
"name": "with-script-in-browser",
"version": "1.0.0",
"private": true,
"dependencies": {
"react": "18.2.0",
"react-dom": "18.2.0",
"@excalidraw/excalidraw": "*"
},
"devDependencies": {
"vite": "5.0.12",
"typescript": "^5"
},
"scripts": {
"start": "yarn workspace @excalidraw/excalidraw run build:esm && vite",
"build": "yarn workspace @excalidraw/excalidraw run build:esm && vite build",
"build:preview": "yarn build && vite preview --port 5002"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 197 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

View File

@@ -0,0 +1,4 @@
{
"outputDirectory": "dist",
"installCommand": "yarn install"
}

View File

@@ -0,0 +1,11 @@
import { defineConfig } from "vite";
// https://vitejs.dev/config/
export default defineConfig({
server: {
port: 3001,
// open the browser
open: true,
},
publicDir: "public",
});

View File

@@ -0,0 +1,313 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
"@esbuild/aix-ppc64@0.19.11":
version "0.19.11"
resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.19.11.tgz#2acd20be6d4f0458bc8c784103495ff24f13b1d3"
integrity sha512-FnzU0LyE3ySQk7UntJO4+qIiQgI7KoODnZg5xzXIrFJlKd2P2gwHsHY4927xj9y5PJmJSzULiUCWmv7iWnNa7g==
"@esbuild/android-arm64@0.19.11":
version "0.19.11"
resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.19.11.tgz#b45d000017385c9051a4f03e17078abb935be220"
integrity sha512-aiu7K/5JnLj//KOnOfEZ0D90obUkRzDMyqd/wNAUQ34m4YUPVhRZpnqKV9uqDGxT7cToSDnIHsGooyIczu9T+Q==
"@esbuild/android-arm@0.19.11":
version "0.19.11"
resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.19.11.tgz#f46f55414e1c3614ac682b29977792131238164c"
integrity sha512-5OVapq0ClabvKvQ58Bws8+wkLCV+Rxg7tUVbo9xu034Nm536QTII4YzhaFriQ7rMrorfnFKUsArD2lqKbFY4vw==
"@esbuild/android-x64@0.19.11":
version "0.19.11"
resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.19.11.tgz#bfc01e91740b82011ef503c48f548950824922b2"
integrity sha512-eccxjlfGw43WYoY9QgB82SgGgDbibcqyDTlk3l3C0jOVHKxrjdc9CTwDUQd0vkvYg5um0OH+GpxYvp39r+IPOg==
"@esbuild/darwin-arm64@0.19.11":
version "0.19.11"
resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.19.11.tgz#533fb7f5a08c37121d82c66198263dcc1bed29bf"
integrity sha512-ETp87DRWuSt9KdDVkqSoKoLFHYTrkyz2+65fj9nfXsaV3bMhTCjtQfw3y+um88vGRKRiF7erPrh/ZuIdLUIVxQ==
"@esbuild/darwin-x64@0.19.11":
version "0.19.11"
resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.19.11.tgz#62f3819eff7e4ddc656b7c6815a31cf9a1e7d98e"
integrity sha512-fkFUiS6IUK9WYUO/+22omwetaSNl5/A8giXvQlcinLIjVkxwTLSktbF5f/kJMftM2MJp9+fXqZ5ezS7+SALp4g==
"@esbuild/freebsd-arm64@0.19.11":
version "0.19.11"
resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.11.tgz#d478b4195aa3ca44160272dab85ef8baf4175b4a"
integrity sha512-lhoSp5K6bxKRNdXUtHoNc5HhbXVCS8V0iZmDvyWvYq9S5WSfTIHU2UGjcGt7UeS6iEYp9eeymIl5mJBn0yiuxA==
"@esbuild/freebsd-x64@0.19.11":
version "0.19.11"
resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.19.11.tgz#7bdcc1917409178257ca6a1a27fe06e797ec18a2"
integrity sha512-JkUqn44AffGXitVI6/AbQdoYAq0TEullFdqcMY/PCUZ36xJ9ZJRtQabzMA+Vi7r78+25ZIBosLTOKnUXBSi1Kw==
"@esbuild/linux-arm64@0.19.11":
version "0.19.11"
resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.19.11.tgz#58ad4ff11685fcc735d7ff4ca759ab18fcfe4545"
integrity sha512-LneLg3ypEeveBSMuoa0kwMpCGmpu8XQUh+mL8XXwoYZ6Be2qBnVtcDI5azSvh7vioMDhoJFZzp9GWp9IWpYoUg==
"@esbuild/linux-arm@0.19.11":
version "0.19.11"
resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.19.11.tgz#ce82246d873b5534d34de1e5c1b33026f35e60e3"
integrity sha512-3CRkr9+vCV2XJbjwgzjPtO8T0SZUmRZla+UL1jw+XqHZPkPgZiyWvbDvl9rqAN8Zl7qJF0O/9ycMtjU67HN9/Q==
"@esbuild/linux-ia32@0.19.11":
version "0.19.11"
resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.19.11.tgz#cbae1f313209affc74b80f4390c4c35c6ab83fa4"
integrity sha512-caHy++CsD8Bgq2V5CodbJjFPEiDPq8JJmBdeyZ8GWVQMjRD0sU548nNdwPNvKjVpamYYVL40AORekgfIubwHoA==
"@esbuild/linux-loong64@0.19.11":
version "0.19.11"
resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.19.11.tgz#5f32aead1c3ec8f4cccdb7ed08b166224d4e9121"
integrity sha512-ppZSSLVpPrwHccvC6nQVZaSHlFsvCQyjnvirnVjbKSHuE5N24Yl8F3UwYUUR1UEPaFObGD2tSvVKbvR+uT1Nrg==
"@esbuild/linux-mips64el@0.19.11":
version "0.19.11"
resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.19.11.tgz#38eecf1cbb8c36a616261de858b3c10d03419af9"
integrity sha512-B5x9j0OgjG+v1dF2DkH34lr+7Gmv0kzX6/V0afF41FkPMMqaQ77pH7CrhWeR22aEeHKaeZVtZ6yFwlxOKPVFyg==
"@esbuild/linux-ppc64@0.19.11":
version "0.19.11"
resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.19.11.tgz#9c5725a94e6ec15b93195e5a6afb821628afd912"
integrity sha512-MHrZYLeCG8vXblMetWyttkdVRjQlQUb/oMgBNurVEnhj4YWOr4G5lmBfZjHYQHHN0g6yDmCAQRR8MUHldvvRDA==
"@esbuild/linux-riscv64@0.19.11":
version "0.19.11"
resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.19.11.tgz#2dc4486d474a2a62bbe5870522a9a600e2acb916"
integrity sha512-f3DY++t94uVg141dozDu4CCUkYW+09rWtaWfnb3bqe4w5NqmZd6nPVBm+qbz7WaHZCoqXqHz5p6CM6qv3qnSSQ==
"@esbuild/linux-s390x@0.19.11":
version "0.19.11"
resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.19.11.tgz#4ad8567df48f7dd4c71ec5b1753b6f37561a65a8"
integrity sha512-A5xdUoyWJHMMlcSMcPGVLzYzpcY8QP1RtYzX5/bS4dvjBGVxdhuiYyFwp7z74ocV7WDc0n1harxmpq2ePOjI0Q==
"@esbuild/linux-x64@0.19.11":
version "0.19.11"
resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.19.11.tgz#b7390c4d5184f203ebe7ddaedf073df82a658766"
integrity sha512-grbyMlVCvJSfxFQUndw5mCtWs5LO1gUlwP4CDi4iJBbVpZcqLVT29FxgGuBJGSzyOxotFG4LoO5X+M1350zmPA==
"@esbuild/netbsd-x64@0.19.11":
version "0.19.11"
resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.19.11.tgz#d633c09492a1721377f3bccedb2d821b911e813d"
integrity sha512-13jvrQZJc3P230OhU8xgwUnDeuC/9egsjTkXN49b3GcS5BKvJqZn86aGM8W9pd14Kd+u7HuFBMVtrNGhh6fHEQ==
"@esbuild/openbsd-x64@0.19.11":
version "0.19.11"
resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.19.11.tgz#17388c76e2f01125bf831a68c03a7ffccb65d1a2"
integrity sha512-ysyOGZuTp6SNKPE11INDUeFVVQFrhcNDVUgSQVDzqsqX38DjhPEPATpid04LCoUr2WXhQTEZ8ct/EgJCUDpyNw==
"@esbuild/sunos-x64@0.19.11":
version "0.19.11"
resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.19.11.tgz#e320636f00bb9f4fdf3a80e548cb743370d41767"
integrity sha512-Hf+Sad9nVwvtxy4DXCZQqLpgmRTQqyFyhT3bZ4F2XlJCjxGmRFF0Shwn9rzhOYRB61w9VMXUkxlBy56dk9JJiQ==
"@esbuild/win32-arm64@0.19.11":
version "0.19.11"
resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.19.11.tgz#c778b45a496e90b6fc373e2a2bb072f1441fe0ee"
integrity sha512-0P58Sbi0LctOMOQbpEOvOL44Ne0sqbS0XWHMvvrg6NE5jQ1xguCSSw9jQeUk2lfrXYsKDdOe6K+oZiwKPilYPQ==
"@esbuild/win32-ia32@0.19.11":
version "0.19.11"
resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.19.11.tgz#481a65fee2e5cce74ec44823e6b09ecedcc5194c"
integrity sha512-6YOrWS+sDJDmshdBIQU+Uoyh7pQKrdykdefC1avn76ss5c+RN6gut3LZA4E2cH5xUEp5/cA0+YxRaVtRAb0xBg==
"@esbuild/win32-x64@0.19.11":
version "0.19.11"
resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.19.11.tgz#a5d300008960bb39677c46bf16f53ec70d8dee04"
integrity sha512-vfkhltrjCAb603XaFhqhAF4LGDi2M4OrCRrFusyQ+iTLQ/o60QQXxc9cZC/FFpihBI9N1Grn6SMKVJ4KP7Fuiw==
"@rollup/rollup-android-arm-eabi@4.9.5":
version "4.9.5"
resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.9.5.tgz#b752b6c88a14ccfcbdf3f48c577ccc3a7f0e66b9"
integrity sha512-idWaG8xeSRCfRq9KpRysDHJ/rEHBEXcHuJ82XY0yYFIWnLMjZv9vF/7DOq8djQ2n3Lk6+3qfSH8AqlmHlmi1MA==
"@rollup/rollup-android-arm64@4.9.5":
version "4.9.5"
resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.9.5.tgz#33757c3a448b9ef77b6f6292d8b0ec45c87e9c1a"
integrity sha512-f14d7uhAMtsCGjAYwZGv6TwuS3IFaM4ZnGMUn3aCBgkcHAYErhV1Ad97WzBvS2o0aaDv4mVz+syiN0ElMyfBPg==
"@rollup/rollup-darwin-arm64@4.9.5":
version "4.9.5"
resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.9.5.tgz#5234ba62665a3f443143bc8bcea9df2cc58f55fb"
integrity sha512-ndoXeLx455FffL68OIUrVr89Xu1WLzAG4n65R8roDlCoYiQcGGg6MALvs2Ap9zs7AHg8mpHtMpwC8jBBjZrT/w==
"@rollup/rollup-darwin-x64@4.9.5":
version "4.9.5"
resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.9.5.tgz#981256c054d3247b83313724938d606798a919d1"
integrity sha512-UmElV1OY2m/1KEEqTlIjieKfVwRg0Zwg4PLgNf0s3glAHXBN99KLpw5A5lrSYCa1Kp63czTpVll2MAqbZYIHoA==
"@rollup/rollup-linux-arm-gnueabihf@4.9.5":
version "4.9.5"
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.9.5.tgz#120678a5a2b3a283a548dbb4d337f9187a793560"
integrity sha512-Q0LcU61v92tQB6ae+udZvOyZ0wfpGojtAKrrpAaIqmJ7+psq4cMIhT/9lfV6UQIpeItnq/2QDROhNLo00lOD1g==
"@rollup/rollup-linux-arm64-gnu@4.9.5":
version "4.9.5"
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.9.5.tgz#c99d857e2372ece544b6f60b85058ad259f64114"
integrity sha512-dkRscpM+RrR2Ee3eOQmRWFjmV/payHEOrjyq1VZegRUa5OrZJ2MAxBNs05bZuY0YCtpqETDy1Ix4i/hRqX98cA==
"@rollup/rollup-linux-arm64-musl@4.9.5":
version "4.9.5"
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.9.5.tgz#3064060f568a5718c2a06858cd6e6d24f2ff8632"
integrity sha512-QaKFVOzzST2xzY4MAmiDmURagWLFh+zZtttuEnuNn19AiZ0T3fhPyjPPGwLNdiDT82ZE91hnfJsUiDwF9DClIQ==
"@rollup/rollup-linux-riscv64-gnu@4.9.5":
version "4.9.5"
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.9.5.tgz#987d30b5d2b992fff07d055015991a57ff55fbad"
integrity sha512-HeGqmRJuyVg6/X6MpE2ur7GbymBPS8Np0S/vQFHDmocfORT+Zt76qu+69NUoxXzGqVP1pzaY6QIi0FJWLC3OPA==
"@rollup/rollup-linux-x64-gnu@4.9.5":
version "4.9.5"
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.9.5.tgz#85946ee4d068bd12197aeeec2c6f679c94978a49"
integrity sha512-Dq1bqBdLaZ1Gb/l2e5/+o3B18+8TI9ANlA1SkejZqDgdU/jK/ThYaMPMJpVMMXy2uRHvGKbkz9vheVGdq3cJfA==
"@rollup/rollup-linux-x64-musl@4.9.5":
version "4.9.5"
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.9.5.tgz#fe0b20f9749a60eb1df43d20effa96c756ddcbd4"
integrity sha512-ezyFUOwldYpj7AbkwyW9AJ203peub81CaAIVvckdkyH8EvhEIoKzaMFJj0G4qYJ5sw3BpqhFrsCc30t54HV8vg==
"@rollup/rollup-win32-arm64-msvc@4.9.5":
version "4.9.5"
resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.9.5.tgz#422661ef0e16699a234465d15b2c1089ef963b2a"
integrity sha512-aHSsMnUw+0UETB0Hlv7B/ZHOGY5bQdwMKJSzGfDfvyhnpmVxLMGnQPGNE9wgqkLUs3+gbG1Qx02S2LLfJ5GaRQ==
"@rollup/rollup-win32-ia32-msvc@4.9.5":
version "4.9.5"
resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.9.5.tgz#7b73a145891c202fbcc08759248983667a035d85"
integrity sha512-AiqiLkb9KSf7Lj/o1U3SEP9Zn+5NuVKgFdRIZkvd4N0+bYrTOovVd0+LmYCPQGbocT4kvFyK+LXCDiXPBF3fyA==
"@rollup/rollup-win32-x64-msvc@4.9.5":
version "4.9.5"
resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.9.5.tgz#10491ccf4f63c814d4149e0316541476ea603602"
integrity sha512-1q+mykKE3Vot1kaFJIDoUFv5TuW+QQVaf2FmTT9krg86pQrGStOSJJ0Zil7CFagyxDuouTepzt5Y5TVzyajOdQ==
"@types/estree@1.0.5":
version "1.0.5"
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.5.tgz#a6ce3e556e00fd9895dd872dd172ad0d4bd687f4"
integrity sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==
esbuild@^0.19.3:
version "0.19.11"
resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.19.11.tgz#4a02dca031e768b5556606e1b468fe72e3325d96"
integrity sha512-HJ96Hev2hX/6i5cDVwcqiJBBtuo9+FeIJOtZ9W1kA5M6AMJRHUZlpYZ1/SbEwtO0ioNAW8rUooVpC/WehY2SfA==
optionalDependencies:
"@esbuild/aix-ppc64" "0.19.11"
"@esbuild/android-arm" "0.19.11"
"@esbuild/android-arm64" "0.19.11"
"@esbuild/android-x64" "0.19.11"
"@esbuild/darwin-arm64" "0.19.11"
"@esbuild/darwin-x64" "0.19.11"
"@esbuild/freebsd-arm64" "0.19.11"
"@esbuild/freebsd-x64" "0.19.11"
"@esbuild/linux-arm" "0.19.11"
"@esbuild/linux-arm64" "0.19.11"
"@esbuild/linux-ia32" "0.19.11"
"@esbuild/linux-loong64" "0.19.11"
"@esbuild/linux-mips64el" "0.19.11"
"@esbuild/linux-ppc64" "0.19.11"
"@esbuild/linux-riscv64" "0.19.11"
"@esbuild/linux-s390x" "0.19.11"
"@esbuild/linux-x64" "0.19.11"
"@esbuild/netbsd-x64" "0.19.11"
"@esbuild/openbsd-x64" "0.19.11"
"@esbuild/sunos-x64" "0.19.11"
"@esbuild/win32-arm64" "0.19.11"
"@esbuild/win32-ia32" "0.19.11"
"@esbuild/win32-x64" "0.19.11"
fsevents@~2.3.2, fsevents@~2.3.3:
version "2.3.3"
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6"
integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==
"js-tokens@^3.0.0 || ^4.0.0":
version "4.0.0"
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==
loose-envify@^1.1.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==
dependencies:
js-tokens "^3.0.0 || ^4.0.0"
nanoid@^3.3.7:
version "3.3.7"
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.7.tgz#d0c301a691bc8d54efa0a2226ccf3fe2fd656bd8"
integrity sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==
picocolors@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c"
integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==
postcss@^8.4.32:
version "8.4.33"
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.33.tgz#1378e859c9f69bf6f638b990a0212f43e2aaa742"
integrity sha512-Kkpbhhdjw2qQs2O2DGX+8m5OVqEcbB9HRBvuYM9pgrjEFUg30A9LmXNlTAUj4S9kgtGyrMbTzVjH7E+s5Re2yg==
dependencies:
nanoid "^3.3.7"
picocolors "^1.0.0"
source-map-js "^1.0.2"
react-dom@18.2.0:
version "18.2.0"
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.2.0.tgz#22aaf38708db2674ed9ada224ca4aa708d821e3d"
integrity sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==
dependencies:
loose-envify "^1.1.0"
scheduler "^0.23.0"
react@18.2.0:
version "18.2.0"
resolved "https://registry.yarnpkg.com/react/-/react-18.2.0.tgz#555bd98592883255fa00de14f1151a917b5d77d5"
integrity sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==
dependencies:
loose-envify "^1.1.0"
rollup@^4.2.0:
version "4.9.5"
resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.9.5.tgz#62999462c90f4c8b5d7c38fc7161e63b29101b05"
integrity sha512-E4vQW0H/mbNMw2yLSqJyjtkHY9dslf/p0zuT1xehNRqUTBOFMqEjguDvqhXr7N7r/4ttb2jr4T41d3dncmIgbQ==
dependencies:
"@types/estree" "1.0.5"
optionalDependencies:
"@rollup/rollup-android-arm-eabi" "4.9.5"
"@rollup/rollup-android-arm64" "4.9.5"
"@rollup/rollup-darwin-arm64" "4.9.5"
"@rollup/rollup-darwin-x64" "4.9.5"
"@rollup/rollup-linux-arm-gnueabihf" "4.9.5"
"@rollup/rollup-linux-arm64-gnu" "4.9.5"
"@rollup/rollup-linux-arm64-musl" "4.9.5"
"@rollup/rollup-linux-riscv64-gnu" "4.9.5"
"@rollup/rollup-linux-x64-gnu" "4.9.5"
"@rollup/rollup-linux-x64-musl" "4.9.5"
"@rollup/rollup-win32-arm64-msvc" "4.9.5"
"@rollup/rollup-win32-ia32-msvc" "4.9.5"
"@rollup/rollup-win32-x64-msvc" "4.9.5"
fsevents "~2.3.2"
scheduler@^0.23.0:
version "0.23.0"
resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.23.0.tgz#ba8041afc3d30eb206a487b6b384002e4e61fdfe"
integrity sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==
dependencies:
loose-envify "^1.1.0"
source-map-js@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c"
integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==
vite@5.0.6:
version "5.0.6"
resolved "https://registry.yarnpkg.com/vite/-/vite-5.0.6.tgz#f9e13503a4c5ccd67312c67803dec921f3bdea7c"
integrity sha512-MD3joyAEBtV7QZPl2JVVUai6zHms3YOmLR+BpMzLlX2Yzjfcc4gTgNi09d/Rua3F4EtC8zdwPU8eQYyib4vVMQ==
dependencies:
esbuild "^0.19.3"
postcss "^8.4.32"
rollup "^4.2.0"
optionalDependencies:
fsevents "~2.3.3"

1122
excalidraw-app/App.tsx Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,14 +1,14 @@
import { useEffect, useState } from "react";
import { debounce, getVersion, nFormatter } from "../src/utils";
import { debounce, getVersion, nFormatter } from "../packages/excalidraw/utils";
import {
getElementsStorageSize,
getTotalStorageSize,
} from "./data/localStorage";
import { DEFAULT_VERSION } from "../src/constants";
import { t } from "../src/i18n";
import { copyTextToSystemClipboard } from "../src/clipboard";
import { NonDeletedExcalidrawElement } from "../src/element/types";
import { UIAppState } from "../src/types";
import { DEFAULT_VERSION } from "../packages/excalidraw/constants";
import { t } from "../packages/excalidraw/i18n";
import { copyTextToSystemClipboard } from "../packages/excalidraw/clipboard";
import { NonDeletedExcalidrawElement } from "../packages/excalidraw/element/types";
import { UIAppState } from "../packages/excalidraw/types";
type StorageSizes = { scene: number; total: number };

View File

@@ -15,11 +15,17 @@ export const FILE_CACHE_MAX_AGE_SEC = 31536000;
export const WS_EVENTS = {
SERVER_VOLATILE: "server-volatile-broadcast",
SERVER: "server-broadcast",
};
USER_FOLLOW_CHANGE: "user-follow",
USER_FOLLOW_ROOM_CHANGE: "user-follow-room-change",
} as const;
export enum WS_SCENE_EVENT_TYPES {
export enum WS_SUBTYPES {
INVALID_RESPONSE = "INVALID_RESPONSE",
INIT = "SCENE_INIT",
UPDATE = "SCENE_UPDATE",
MOUSE_LOCATION = "MOUSE_LOCATION",
IDLE_STATUS = "IDLE_STATUS",
USER_VISIBLE_SCENE_BOUNDS = "USER_VISIBLE_SCENE_BOUNDS",
}
export const FIREBASE_STORAGE_PREFIXES = {
@@ -33,10 +39,14 @@ export const STORAGE_KEYS = {
LOCAL_STORAGE_ELEMENTS: "excalidraw",
LOCAL_STORAGE_APP_STATE: "excalidraw-state",
LOCAL_STORAGE_COLLAB: "excalidraw-collab",
LOCAL_STORAGE_LIBRARY: "excalidraw-library",
LOCAL_STORAGE_THEME: "excalidraw-theme",
VERSION_DATA_STATE: "version-dataState",
VERSION_FILES: "version-files",
IDB_LIBRARY: "excalidraw-library",
// do not use apart from migrations
__LEGACY_LOCAL_STORAGE_LIBRARY: "excalidraw-library",
} as const;
export const COOKIES = {

View File

@@ -1,36 +1,42 @@
import throttle from "lodash.throttle";
import { PureComponent } from "react";
import { ExcalidrawImperativeAPI } from "../../src/types";
import { ErrorDialog } from "../../src/components/ErrorDialog";
import { APP_NAME, ENV, EVENT } from "../../src/constants";
import { ImportedDataState } from "../../src/data/types";
import {
ExcalidrawImperativeAPI,
SocketId,
} from "../../packages/excalidraw/types";
import { ErrorDialog } from "../../packages/excalidraw/components/ErrorDialog";
import { APP_NAME, ENV, EVENT } from "../../packages/excalidraw/constants";
import { ImportedDataState } from "../../packages/excalidraw/data/types";
import {
ExcalidrawElement,
InitializedExcalidrawImageElement,
} from "../../src/element/types";
OrderedExcalidrawElement,
} from "../../packages/excalidraw/element/types";
import {
getSceneVersion,
restoreElements,
} from "../../src/packages/excalidraw/index";
import { Collaborator, Gesture } from "../../src/types";
zoomToFitBounds,
} from "../../packages/excalidraw/index";
import { Collaborator, Gesture } from "../../packages/excalidraw/types";
import {
assertNever,
preventUnload,
resolvablePromise,
withBatchedUpdates,
} from "../../src/utils";
throttleRAF,
} from "../../packages/excalidraw/utils";
import {
CURSOR_SYNC_TIMEOUT,
FILE_UPLOAD_MAX_BYTES,
FIREBASE_STORAGE_PREFIXES,
INITIAL_SCENE_UPDATE_TIMEOUT,
LOAD_IMAGES_TIMEOUT,
WS_SCENE_EVENT_TYPES,
WS_SUBTYPES,
SYNC_FULL_SCENE_INTERVAL_MS,
WS_EVENTS,
} from "../app_constants";
import {
generateCollaborationLinkData,
getCollaborationLink,
getCollabServer,
getSyncableElements,
SocketUpdateDataSource,
SyncableExcalidrawElement,
@@ -47,42 +53,52 @@ import {
saveUsernameToLocalStorage,
} from "../data/localStorage";
import Portal from "./Portal";
import RoomDialog from "./RoomDialog";
import { t } from "../../src/i18n";
import { UserIdleState } from "../../src/types";
import { IDLE_THRESHOLD, ACTIVE_THRESHOLD } from "../../src/constants";
import { t } from "../../packages/excalidraw/i18n";
import { UserIdleState } from "../../packages/excalidraw/types";
import {
IDLE_THRESHOLD,
ACTIVE_THRESHOLD,
} from "../../packages/excalidraw/constants";
import {
encodeFilesForUpload,
FileManager,
updateStaleImageStatuses,
} from "../data/FileManager";
import { AbortError } from "../../src/errors";
import { AbortError } from "../../packages/excalidraw/errors";
import {
isImageElement,
isInitializedImageElement,
} from "../../src/element/typeChecks";
import { newElementWith } from "../../src/element/mutateElement";
import {
ReconciledElements,
reconcileElements as _reconcileElements,
} from "./reconciliation";
import { decryptData } from "../../src/data/encryption";
} from "../../packages/excalidraw/element/typeChecks";
import { newElementWith } from "../../packages/excalidraw/element/mutateElement";
import { decryptData } from "../../packages/excalidraw/data/encryption";
import { resetBrowserStateVersions } from "../data/tabSync";
import { LocalData } from "../data/LocalData";
import { atom, useAtom } from "jotai";
import { atom } from "jotai";
import { appJotaiStore } from "../app-jotai";
import { Mutable, ValueOf } from "../../packages/excalidraw/utility-types";
import { getVisibleSceneBounds } from "../../packages/excalidraw/element/bounds";
import { withBatchedUpdates } from "../../packages/excalidraw/reactUtils";
import { collabErrorIndicatorAtom } from "./CollabError";
import {
ReconciledExcalidrawElement,
RemoteExcalidrawElement,
reconcileElements,
} from "../../packages/excalidraw/data/reconcile";
export const collabAPIAtom = atom<CollabAPI | null>(null);
export const collabDialogShownAtom = atom(false);
export const isCollaboratingAtom = atom(false);
export const isOfflineAtom = atom(false);
interface CollabState {
errorMessage: string;
errorMessage: string | null;
/** errors related to saving */
dialogNotifiedErrors: Record<string, boolean>;
username: string;
activeRoomLink: string;
activeRoomLink: string | null;
}
export const activeRoomLinkAtom = atom<string | null>(null);
type CollabInstance = InstanceType<typeof Collab>;
export interface CollabAPI {
@@ -93,32 +109,34 @@ export interface CollabAPI {
stopCollaboration: CollabInstance["stopCollaboration"];
syncElements: CollabInstance["syncElements"];
fetchImageFilesFromFirebase: CollabInstance["fetchImageFilesFromFirebase"];
setUsername: (username: string) => void;
setUsername: CollabInstance["setUsername"];
getUsername: CollabInstance["getUsername"];
getActiveRoomLink: CollabInstance["getActiveRoomLink"];
setCollabError: CollabInstance["setErrorDialog"];
}
interface PublicProps {
interface CollabProps {
excalidrawAPI: ExcalidrawImperativeAPI;
}
type Props = PublicProps & { modalIsShown: boolean };
class Collab extends PureComponent<Props, CollabState> {
class Collab extends PureComponent<CollabProps, CollabState> {
portal: Portal;
fileManager: FileManager;
excalidrawAPI: Props["excalidrawAPI"];
excalidrawAPI: CollabProps["excalidrawAPI"];
activeIntervalId: number | null;
idleTimeoutId: number | null;
private socketInitializationTimer?: number;
private lastBroadcastedOrReceivedSceneVersion: number = -1;
private collaborators = new Map<string, Collaborator>();
private collaborators = new Map<SocketId, Collaborator>();
constructor(props: Props) {
constructor(props: CollabProps) {
super(props);
this.state = {
errorMessage: "",
errorMessage: null,
dialogNotifiedErrors: {},
username: importUsernameFromLocalStorage() || "",
activeRoomLink: "",
activeRoomLink: null,
};
this.portal = new Portal(this);
this.fileManager = new FileManager({
@@ -151,12 +169,28 @@ class Collab extends PureComponent<Props, CollabState> {
this.idleTimeoutId = null;
}
private onUmmount: (() => void) | null = null;
componentDidMount() {
window.addEventListener(EVENT.BEFORE_UNLOAD, this.beforeUnload);
window.addEventListener("online", this.onOfflineStatusToggle);
window.addEventListener("offline", this.onOfflineStatusToggle);
window.addEventListener(EVENT.UNLOAD, this.onUnload);
const unsubOnUserFollow = this.excalidrawAPI.onUserFollow((payload) => {
this.portal.socket && this.portal.broadcastUserFollowed(payload);
});
const throttledRelayUserViewportBounds = throttleRAF(
this.relayVisibleSceneBounds,
);
const unsubOnScrollChange = this.excalidrawAPI.onScrollChange(() =>
throttledRelayUserViewportBounds(),
);
this.onUmmount = () => {
unsubOnUserFollow();
unsubOnScrollChange();
};
this.onOfflineStatusToggle();
const collabAPI: CollabAPI = {
@@ -167,6 +201,9 @@ class Collab extends PureComponent<Props, CollabState> {
fetchImageFilesFromFirebase: this.fetchImageFilesFromFirebase,
stopCollaboration: this.stopCollaboration,
setUsername: this.setUsername,
getUsername: this.getUsername,
getActiveRoomLink: this.getActiveRoomLink,
setCollabError: this.setErrorDialog,
};
appJotaiStore.set(collabAPIAtom, collabAPI);
@@ -204,6 +241,7 @@ class Collab extends PureComponent<Props, CollabState> {
window.clearTimeout(this.idleTimeoutId);
this.idleTimeoutId = null;
}
this.onUmmount?.();
}
isCollaborating = () => appJotaiStore.get(isCollaboratingAtom)!;
@@ -238,24 +276,39 @@ class Collab extends PureComponent<Props, CollabState> {
syncableElements: readonly SyncableExcalidrawElement[],
) => {
try {
const savedData = await saveToFirebase(
const storedElements = await saveToFirebase(
this.portal,
syncableElements,
this.excalidrawAPI.getAppState(),
);
if (this.isCollaborating() && savedData && savedData.reconciledElements) {
this.handleRemoteSceneUpdate(
this.reconcileElements(savedData.reconciledElements),
);
this.resetErrorIndicator();
if (this.isCollaborating() && storedElements) {
this.handleRemoteSceneUpdate(this._reconcileElements(storedElements));
}
} catch (error: any) {
this.setState({
// firestore doesn't return a specific error code when size exceeded
errorMessage: /is longer than.*?bytes/.test(error.message)
? t("errors.collabSaveFailed_sizeExceeded")
: t("errors.collabSaveFailed"),
});
const errorMessage = /is longer than.*?bytes/.test(error.message)
? t("errors.collabSaveFailed_sizeExceeded")
: t("errors.collabSaveFailed");
if (
!this.state.dialogNotifiedErrors[errorMessage] ||
!this.isCollaborating()
) {
this.setErrorDialog(errorMessage);
this.setState({
dialogNotifiedErrors: {
...this.state.dialogNotifiedErrors,
[errorMessage]: true,
},
});
}
if (this.isCollaborating()) {
this.setErrorIndicator(errorMessage);
}
console.error(error);
}
};
@@ -264,6 +317,7 @@ class Collab extends PureComponent<Props, CollabState> {
this.queueBroadcastAllElements.cancel();
this.queueSaveToFirebase.cancel();
this.loadImageFiles.cancel();
this.resetErrorIndicator(true);
this.saveCollabRoomToFirebase(
getSyncableElements(
@@ -313,9 +367,7 @@ class Collab extends PureComponent<Props, CollabState> {
this.fileManager.reset();
if (!opts?.isUnload) {
this.setIsCollaborating(false);
this.setState({
activeRoomLink: "",
});
this.setActiveRoomLink(null);
this.collaborators = new Map();
this.excalidrawAPI.updateScene({
collaborators: this.collaborators,
@@ -356,7 +408,7 @@ class Collab extends PureComponent<Props, CollabState> {
iv: Uint8Array,
encryptedData: ArrayBuffer,
decryptionKey: string,
) => {
): Promise<ValueOf<SocketUpdateDataSource>> => {
try {
const decrypted = await decryptData(iv, encryptedData, decryptionKey);
@@ -368,7 +420,7 @@ class Collab extends PureComponent<Props, CollabState> {
window.alert(t("alerts.decryptFailed"));
console.error(error);
return {
type: "INVALID_RESPONSE",
type: WS_SUBTYPES.INVALID_RESPONSE,
};
}
};
@@ -377,11 +429,11 @@ class Collab extends PureComponent<Props, CollabState> {
startCollaboration = async (
existingRoomLinkData: null | { roomId: string; roomKey: string },
): Promise<ImportedDataState | null> => {
) => {
if (!this.state.username) {
import("@excalidraw/random-username").then(({ getRandomUsername }) => {
const username = getRandomUsername();
this.onUsernameChange(username);
this.setUsername(username);
});
}
@@ -403,7 +455,11 @@ class Collab extends PureComponent<Props, CollabState> {
);
}
const scenePromise = resolvablePromise<ImportedDataState | null>();
// TODO: `ImportedDataState` type here seems abused
const scenePromise = resolvablePromise<
| (ImportedDataState & { elements: readonly OrderedExcalidrawElement[] })
| null
>();
this.setIsCollaborating(true);
LocalData.pauseSave("collaboration");
@@ -423,13 +479,9 @@ class Collab extends PureComponent<Props, CollabState> {
this.fallbackInitializationHandler = fallbackInitializationHandler;
try {
const socketServerData = await getCollabServer();
this.portal.socket = this.portal.open(
socketIOClient(socketServerData.url, {
transports: socketServerData.polling
? ["websocket", "polling"]
: ["websocket"],
socketIOClient(import.meta.env.VITE_APP_WS_SERVER_URL, {
transports: ["websocket", "polling"],
}),
roomId,
roomKey,
@@ -438,7 +490,7 @@ class Collab extends PureComponent<Props, CollabState> {
this.portal.socket.once("connect_error", fallbackInitializationHandler);
} catch (error: any) {
console.error(error);
this.setState({ errorMessage: error.message });
this.setErrorDialog(error.message);
return null;
}
@@ -484,13 +536,14 @@ class Collab extends PureComponent<Props, CollabState> {
);
switch (decryptedData.type) {
case "INVALID_RESPONSE":
case WS_SUBTYPES.INVALID_RESPONSE:
return;
case WS_SCENE_EVENT_TYPES.INIT: {
case WS_SUBTYPES.INIT: {
if (!this.portal.socketInitialized) {
this.initializeRoom({ fetchScene: false });
const remoteElements = decryptedData.payload.elements;
const reconciledElements = this.reconcileElements(remoteElements);
const reconciledElements =
this._reconcileElements(remoteElements);
this.handleRemoteSceneUpdate(reconciledElements, {
init: true,
});
@@ -502,41 +555,75 @@ class Collab extends PureComponent<Props, CollabState> {
}
break;
}
case WS_SCENE_EVENT_TYPES.UPDATE:
case WS_SUBTYPES.UPDATE:
this.handleRemoteSceneUpdate(
this.reconcileElements(decryptedData.payload.elements),
this._reconcileElements(decryptedData.payload.elements),
);
break;
case "MOUSE_LOCATION": {
case WS_SUBTYPES.MOUSE_LOCATION: {
const { pointer, button, username, selectedElementIds } =
decryptedData.payload;
const socketId: SocketUpdateDataSource["MOUSE_LOCATION"]["payload"]["socketId"] =
decryptedData.payload.socketId ||
// @ts-ignore legacy, see #2094 (#2097)
decryptedData.payload.socketID;
const collaborators = new Map(this.collaborators);
const user = collaborators.get(socketId) || {}!;
user.pointer = pointer;
user.button = button;
user.selectedElementIds = selectedElementIds;
user.username = username;
collaborators.set(socketId, user);
this.updateCollaborator(socketId, {
pointer,
button,
selectedElementIds,
username,
});
break;
}
case WS_SUBTYPES.USER_VISIBLE_SCENE_BOUNDS: {
const { sceneBounds, socketId } = decryptedData.payload;
const appState = this.excalidrawAPI.getAppState();
// we're not following the user
// (shouldn't happen, but could be late message or bug upstream)
if (appState.userToFollow?.socketId !== socketId) {
console.warn(
`receiving remote client's (from ${socketId}) viewport bounds even though we're not subscribed to it!`,
);
return;
}
// cross-follow case, ignore updates in this case
if (
appState.userToFollow &&
appState.followedBy.has(appState.userToFollow.socketId)
) {
return;
}
this.excalidrawAPI.updateScene({
collaborators,
appState: zoomToFitBounds({
appState,
bounds: sceneBounds,
fitToViewport: true,
viewportZoomFactor: 1,
}).appState,
});
break;
}
case WS_SUBTYPES.IDLE_STATUS: {
const { userState, socketId, username } = decryptedData.payload;
this.updateCollaborator(socketId, {
userState,
username,
});
break;
}
case "IDLE_STATUS": {
const { userState, socketId, username } = decryptedData.payload;
const collaborators = new Map(this.collaborators);
const user = collaborators.get(socketId) || {}!;
user.userState = userState;
user.username = username;
this.excalidrawAPI.updateScene({
collaborators,
});
break;
default: {
assertNever(decryptedData, null);
}
}
},
@@ -553,11 +640,20 @@ class Collab extends PureComponent<Props, CollabState> {
scenePromise.resolve(sceneData);
});
this.portal.socket.on(
WS_EVENTS.USER_FOLLOW_ROOM_CHANGE,
(followedBy: SocketId[]) => {
this.excalidrawAPI.updateScene({
appState: { followedBy: new Set(followedBy) },
});
this.relayVisibleSceneBounds({ force: true });
},
);
this.initializeIdleDetector();
this.setState({
activeRoomLink: window.location.href,
});
this.setActiveRoomLink(window.location.href);
return scenePromise;
};
@@ -609,17 +705,15 @@ class Collab extends PureComponent<Props, CollabState> {
return null;
};
private reconcileElements = (
private _reconcileElements = (
remoteElements: readonly ExcalidrawElement[],
): ReconciledElements => {
): ReconciledExcalidrawElement[] => {
const localElements = this.getSceneElementsIncludingDeleted();
const appState = this.excalidrawAPI.getAppState();
remoteElements = restoreElements(remoteElements, null);
const reconciledElements = _reconcileElements(
const restoredRemoteElements = restoreElements(remoteElements, null);
const reconciledElements = reconcileElements(
localElements,
remoteElements,
restoredRemoteElements as RemoteExcalidrawElement[],
appState,
);
@@ -650,7 +744,7 @@ class Collab extends PureComponent<Props, CollabState> {
}, LOAD_IMAGES_TIMEOUT);
private handleRemoteSceneUpdate = (
elements: ReconciledElements,
elements: ReconciledExcalidrawElement[],
{ init = false }: { init?: boolean } = {},
) => {
this.excalidrawAPI.updateScene({
@@ -721,20 +815,39 @@ class Collab extends PureComponent<Props, CollabState> {
document.addEventListener(EVENT.VISIBILITY_CHANGE, this.onVisibilityChange);
};
setCollaborators(sockets: string[]) {
setCollaborators(sockets: SocketId[]) {
const collaborators: InstanceType<typeof Collab>["collaborators"] =
new Map();
for (const socketId of sockets) {
if (this.collaborators.has(socketId)) {
collaborators.set(socketId, this.collaborators.get(socketId)!);
} else {
collaborators.set(socketId, {});
}
collaborators.set(
socketId,
Object.assign({}, this.collaborators.get(socketId), {
isCurrentUser: socketId === this.portal.socket?.id,
}),
);
}
this.collaborators = collaborators;
this.excalidrawAPI.updateScene({ collaborators });
}
updateCollaborator = (socketId: SocketId, updates: Partial<Collaborator>) => {
const collaborators = new Map(this.collaborators);
const user: Mutable<Collaborator> = Object.assign(
{},
collaborators.get(socketId),
updates,
{
isCurrentUser: socketId === this.portal.socket?.id,
},
);
collaborators.set(socketId, user);
this.collaborators = collaborators;
this.excalidrawAPI.updateScene({
collaborators,
});
};
public setLastBroadcastedOrReceivedSceneVersion = (version: number) => {
this.lastBroadcastedOrReceivedSceneVersion = version;
};
@@ -760,29 +873,42 @@ class Collab extends PureComponent<Props, CollabState> {
CURSOR_SYNC_TIMEOUT,
);
relayVisibleSceneBounds = (props?: { force: boolean }) => {
const appState = this.excalidrawAPI.getAppState();
if (this.portal.socket && (appState.followedBy.size > 0 || props?.force)) {
this.portal.broadcastVisibleSceneBounds(
{
sceneBounds: getVisibleSceneBounds(appState),
},
`follow@${this.portal.socket.id}`,
);
}
};
onIdleStateChange = (userState: UserIdleState) => {
this.portal.broadcastIdleChange(userState);
};
broadcastElements = (elements: readonly ExcalidrawElement[]) => {
broadcastElements = (elements: readonly OrderedExcalidrawElement[]) => {
if (
getSceneVersion(elements) >
this.getLastBroadcastedOrReceivedSceneVersion()
) {
this.portal.broadcastScene(WS_SCENE_EVENT_TYPES.UPDATE, elements, false);
this.portal.broadcastScene(WS_SUBTYPES.UPDATE, elements, false);
this.lastBroadcastedOrReceivedSceneVersion = getSceneVersion(elements);
this.queueBroadcastAllElements();
}
};
syncElements = (elements: readonly ExcalidrawElement[]) => {
syncElements = (elements: readonly OrderedExcalidrawElement[]) => {
this.broadcastElements(elements);
this.queueSaveToFirebase();
};
queueBroadcastAllElements = throttle(() => {
this.portal.broadcastScene(
WS_SCENE_EVENT_TYPES.UPDATE,
WS_SUBTYPES.UPDATE,
this.excalidrawAPI.getSceneElementsIncludingDeleted(),
true,
);
@@ -808,41 +934,49 @@ class Collab extends PureComponent<Props, CollabState> {
{ leading: false },
);
handleClose = () => {
appJotaiStore.set(collabDialogShownAtom, false);
};
setUsername = (username: string) => {
this.setState({ username });
};
onUsernameChange = (username: string) => {
this.setUsername(username);
saveUsernameToLocalStorage(username);
};
render() {
const { username, errorMessage, activeRoomLink } = this.state;
getUsername = () => this.state.username;
const { modalIsShown } = this.props;
setActiveRoomLink = (activeRoomLink: string | null) => {
this.setState({ activeRoomLink });
appJotaiStore.set(activeRoomLinkAtom, activeRoomLink);
};
getActiveRoomLink = () => this.state.activeRoomLink;
setErrorIndicator = (errorMessage: string | null) => {
appJotaiStore.set(collabErrorIndicatorAtom, {
message: errorMessage,
nonce: Date.now(),
});
};
resetErrorIndicator = (resetDialogNotifiedErrors = false) => {
appJotaiStore.set(collabErrorIndicatorAtom, { message: null, nonce: 0 });
if (resetDialogNotifiedErrors) {
this.setState({
dialogNotifiedErrors: {},
});
}
};
setErrorDialog = (errorMessage: string | null) => {
this.setState({
errorMessage,
});
};
render() {
const { errorMessage } = this.state;
return (
<>
{modalIsShown && (
<RoomDialog
handleClose={this.handleClose}
activeRoomLink={activeRoomLink}
username={username}
onUsernameChange={this.onUsernameChange}
onRoomCreate={() => this.startCollaboration(null)}
onRoomDestroy={this.stopCollaboration}
setErrorMessage={(errorMessage) => {
this.setState({ errorMessage });
}}
/>
)}
{errorMessage && (
<ErrorDialog onClose={() => this.setState({ errorMessage: "" })}>
{errorMessage != null && (
<ErrorDialog onClose={() => this.setErrorDialog(null)}>
{errorMessage}
</ErrorDialog>
)}
@@ -861,11 +995,6 @@ if (import.meta.env.MODE === ENV.TEST || import.meta.env.DEV) {
window.collab = window.collab || ({} as Window["collab"]);
}
const _Collab: React.FC<PublicProps> = (props) => {
const [collabDialogShown] = useAtom(collabDialogShownAtom);
return <Collab {...props} modalIsShown={collabDialogShown} />;
};
export default _Collab;
export default Collab;
export type TCollabClass = Collab;

View File

@@ -0,0 +1,35 @@
@import "../../packages/excalidraw/css/variables.module.scss";
.excalidraw {
.collab-errors-button {
width: 26px;
height: 26px;
margin-inline-end: 1rem;
color: var(--color-danger);
flex-shrink: 0;
}
.collab-errors-button-shake {
animation: strong-shake 0.15s 6;
}
@keyframes strong-shake {
0% {
transform: rotate(0deg);
}
25% {
transform: rotate(10deg);
}
50% {
transform: rotate(0eg);
}
75% {
transform: rotate(-10deg);
}
100% {
transform: rotate(0deg);
}
}
}

View File

@@ -0,0 +1,54 @@
import { Tooltip } from "../../packages/excalidraw/components/Tooltip";
import { warning } from "../../packages/excalidraw/components/icons";
import clsx from "clsx";
import { useEffect, useRef, useState } from "react";
import "./CollabError.scss";
import { atom } from "jotai";
type ErrorIndicator = {
message: string | null;
/** used to rerun the useEffect responsible for animation */
nonce: number;
};
export const collabErrorIndicatorAtom = atom<ErrorIndicator>({
message: null,
nonce: 0,
});
const CollabError = ({ collabError }: { collabError: ErrorIndicator }) => {
const [isAnimating, setIsAnimating] = useState(false);
const clearAnimationRef = useRef<string | number | NodeJS.Timeout>();
useEffect(() => {
setIsAnimating(true);
clearAnimationRef.current = setTimeout(() => {
setIsAnimating(false);
}, 1000);
return () => {
clearTimeout(clearAnimationRef.current);
};
}, [collabError.message, collabError.nonce]);
if (!collabError.message) {
return null;
}
return (
<Tooltip label={collabError.message} long={true}>
<div
className={clsx("collab-errors-button", {
"collab-errors-button-shake": isAnimating,
})}
>
{warning}
</div>
</Tooltip>
);
};
CollabError.displayName = "CollabError";
export default CollabError;

View File

@@ -2,27 +2,27 @@ import {
isSyncableElement,
SocketUpdateData,
SocketUpdateDataSource,
SyncableExcalidrawElement,
} from "../data";
import { TCollabClass } from "./Collab";
import { ExcalidrawElement } from "../../src/element/types";
import { OrderedExcalidrawElement } from "../../packages/excalidraw/element/types";
import { WS_EVENTS, FILE_UPLOAD_TIMEOUT, WS_SUBTYPES } from "../app_constants";
import {
WS_EVENTS,
FILE_UPLOAD_TIMEOUT,
WS_SCENE_EVENT_TYPES,
} from "../app_constants";
import { UserIdleState } from "../../src/types";
import { trackEvent } from "../../src/analytics";
OnUserFollowedPayload,
SocketId,
UserIdleState,
} from "../../packages/excalidraw/types";
import { trackEvent } from "../../packages/excalidraw/analytics";
import throttle from "lodash.throttle";
import { newElementWith } from "../../src/element/mutateElement";
import { BroadcastedExcalidrawElement } from "./reconciliation";
import { encryptData } from "../../src/data/encryption";
import { PRECEDING_ELEMENT_KEY } from "../../src/constants";
import { newElementWith } from "../../packages/excalidraw/element/mutateElement";
import { encryptData } from "../../packages/excalidraw/data/encryption";
import type { Socket } from "socket.io-client";
class Portal {
collab: TCollabClass;
socket: SocketIOClient.Socket | null = null;
socket: Socket | null = null;
socketInitialized: boolean = false; // we don't want the socket to emit any updates until it is fully initialized
roomId: string | null = null;
roomKey: string | null = null;
@@ -32,7 +32,7 @@ class Portal {
this.collab = collab;
}
open(socket: SocketIOClient.Socket, id: string, key: string) {
open(socket: Socket, id: string, key: string) {
this.socket = socket;
this.roomId = id;
this.roomKey = key;
@@ -46,12 +46,12 @@ class Portal {
});
this.socket.on("new-user", async (_socketId: string) => {
this.broadcastScene(
WS_SCENE_EVENT_TYPES.INIT,
WS_SUBTYPES.INIT,
this.collab.getSceneElementsIncludingDeleted(),
/* syncAll */ true,
);
});
this.socket.on("room-user-change", (clients: string[]) => {
this.socket.on("room-user-change", (clients: SocketId[]) => {
this.collab.setCollaborators(clients);
});
@@ -83,6 +83,7 @@ class Portal {
async _broadcastSocketData(
data: SocketUpdateData,
volatile: boolean = false,
roomId?: string,
) {
if (this.isOpen()) {
const json = JSON.stringify(data);
@@ -91,7 +92,7 @@ class Portal {
this.socket?.emit(
volatile ? WS_EVENTS.SERVER_VOLATILE : WS_EVENTS.SERVER,
this.roomId,
roomId ?? this.roomId,
encryptedBuffer,
iv,
);
@@ -130,36 +131,28 @@ class Portal {
}, FILE_UPLOAD_TIMEOUT);
broadcastScene = async (
updateType: WS_SCENE_EVENT_TYPES.INIT | WS_SCENE_EVENT_TYPES.UPDATE,
allElements: readonly ExcalidrawElement[],
updateType: WS_SUBTYPES.INIT | WS_SUBTYPES.UPDATE,
elements: readonly OrderedExcalidrawElement[],
syncAll: boolean,
) => {
if (updateType === WS_SCENE_EVENT_TYPES.INIT && !syncAll) {
if (updateType === WS_SUBTYPES.INIT && !syncAll) {
throw new Error("syncAll must be true when sending SCENE.INIT");
}
// sync out only the elements we think we need to to save bandwidth.
// periodically we'll resync the whole thing to make sure no one diverges
// due to a dropped message (server goes down etc).
const syncableElements = allElements.reduce(
(acc, element: BroadcastedExcalidrawElement, idx, elements) => {
if (
(syncAll ||
!this.broadcastedElementVersions.has(element.id) ||
element.version >
this.broadcastedElementVersions.get(element.id)!) &&
isSyncableElement(element)
) {
acc.push({
...element,
// z-index info for the reconciler
[PRECEDING_ELEMENT_KEY]: idx === 0 ? "^" : elements[idx - 1]?.id,
});
}
return acc;
},
[] as BroadcastedExcalidrawElement[],
);
const syncableElements = elements.reduce((acc, element) => {
if (
(syncAll ||
!this.broadcastedElementVersions.has(element.id) ||
element.version > this.broadcastedElementVersions.get(element.id)!) &&
isSyncableElement(element)
) {
acc.push(element);
}
return acc;
}, [] as SyncableExcalidrawElement[]);
const data: SocketUpdateDataSource[typeof updateType] = {
type: updateType,
@@ -183,9 +176,9 @@ class Portal {
broadcastIdleChange = (userState: UserIdleState) => {
if (this.socket?.id) {
const data: SocketUpdateDataSource["IDLE_STATUS"] = {
type: "IDLE_STATUS",
type: WS_SUBTYPES.IDLE_STATUS,
payload: {
socketId: this.socket.id,
socketId: this.socket.id as SocketId,
userState,
username: this.collab.state.username,
},
@@ -203,9 +196,9 @@ class Portal {
}) => {
if (this.socket?.id) {
const data: SocketUpdateDataSource["MOUSE_LOCATION"] = {
type: "MOUSE_LOCATION",
type: WS_SUBTYPES.MOUSE_LOCATION,
payload: {
socketId: this.socket.id,
socketId: this.socket.id as SocketId,
pointer: payload.pointer,
button: payload.button || "up",
selectedElementIds:
@@ -213,12 +206,43 @@ class Portal {
username: this.collab.state.username,
},
};
return this._broadcastSocketData(
data as SocketUpdateData,
true, // volatile
);
}
};
broadcastVisibleSceneBounds = (
payload: {
sceneBounds: SocketUpdateDataSource["USER_VISIBLE_SCENE_BOUNDS"]["payload"]["sceneBounds"];
},
roomId: string,
) => {
if (this.socket?.id) {
const data: SocketUpdateDataSource["USER_VISIBLE_SCENE_BOUNDS"] = {
type: WS_SUBTYPES.USER_VISIBLE_SCENE_BOUNDS,
payload: {
socketId: this.socket.id as SocketId,
username: this.collab.state.username,
sceneBounds: payload.sceneBounds,
},
};
return this._broadcastSocketData(
data as SocketUpdateData,
true, // volatile
roomId,
);
}
};
broadcastUserFollowed = (payload: OnUserFollowedPayload) => {
if (this.socket?.id) {
this.socket.emit(WS_EVENTS.USER_FOLLOW_CHANGE, payload);
}
};
}
export default Portal;

View File

@@ -1,13 +1,13 @@
import { useRef, useState } from "react";
import * as Popover from "@radix-ui/react-popover";
import { copyTextToSystemClipboard } from "../../src/clipboard";
import { trackEvent } from "../../src/analytics";
import { getFrame } from "../../src/utils";
import { useI18n } from "../../src/i18n";
import { KEYS } from "../../src/keys";
import { copyTextToSystemClipboard } from "../../packages/excalidraw/clipboard";
import { trackEvent } from "../../packages/excalidraw/analytics";
import { getFrame } from "../../packages/excalidraw/utils";
import { useI18n } from "../../packages/excalidraw/i18n";
import { KEYS } from "../../packages/excalidraw/keys";
import { Dialog } from "../../src/components/Dialog";
import { Dialog } from "../../packages/excalidraw/components/Dialog";
import {
copyIcon,
playerPlayIcon,
@@ -16,11 +16,11 @@ import {
shareIOS,
shareWindows,
tablerCheckIcon,
} from "../../src/components/icons";
import { TextField } from "../../src/components/TextField";
import { FilledButton } from "../../src/components/FilledButton";
} from "../../packages/excalidraw/components/icons";
import { TextField } from "../../packages/excalidraw/components/TextField";
import { FilledButton } from "../../packages/excalidraw/components/FilledButton";
import { ReactComponent as CollabImage } from "../../src/assets/lock.svg";
import { ReactComponent as CollabImage } from "../../packages/excalidraw/assets/lock.svg";
import "./RoomDialog.scss";
const getShareIcon = () => {
@@ -65,19 +65,18 @@ export const RoomModal = ({
const copyRoomLink = async () => {
try {
await copyTextToSystemClipboard(activeRoomLink);
setJustCopied(true);
if (timerRef.current) {
window.clearTimeout(timerRef.current);
}
timerRef.current = window.setTimeout(() => {
setJustCopied(false);
}, 3000);
} catch (error: any) {
setErrorMessage(error.message);
} catch (e) {
setErrorMessage(t("errors.copyToSystemClipboardFailed"));
}
setJustCopied(true);
if (timerRef.current) {
window.clearTimeout(timerRef.current);
}
timerRef.current = window.setTimeout(() => {
setJustCopied(false);
}, 3000);
ref.current?.select();
};
@@ -120,7 +119,7 @@ export const RoomModal = ({
size="large"
variant="icon"
label="Share"
startIcon={getShareIcon()}
icon={getShareIcon()}
className="RoomDialog__active__share"
onClick={shareRoomLink}
/>
@@ -130,7 +129,7 @@ export const RoomModal = ({
<FilledButton
size="large"
label="Copy link"
startIcon={copyIcon}
icon={copyIcon}
onClick={copyRoomLink}
/>
</Popover.Trigger>
@@ -166,7 +165,7 @@ export const RoomModal = ({
variant="outlined"
color="danger"
label={t("roomDialog.button_stopSession")}
startIcon={playerStopFilledIcon}
icon={playerStopFilledIcon}
onClick={() => {
trackEvent("share", "room closed");
onRoomDestroy();
@@ -195,7 +194,7 @@ export const RoomModal = ({
<FilledButton
size="large"
label={t("roomDialog.button_startSession")}
startIcon={playerPlayIcon}
icon={playerPlayIcon}
onClick={() => {
trackEvent("share", "room creation", `ui (${getFrame()})`);
onRoomCreate();

View File

@@ -1,154 +0,0 @@
import { PRECEDING_ELEMENT_KEY } from "../../src/constants";
import { ExcalidrawElement } from "../../src/element/types";
import { AppState } from "../../src/types";
import { arrayToMapWithIndex } from "../../src/utils";
export type ReconciledElements = readonly ExcalidrawElement[] & {
_brand: "reconciledElements";
};
export type BroadcastedExcalidrawElement = ExcalidrawElement & {
[PRECEDING_ELEMENT_KEY]?: string;
};
const shouldDiscardRemoteElement = (
localAppState: AppState,
local: ExcalidrawElement | undefined,
remote: BroadcastedExcalidrawElement,
): boolean => {
if (
local &&
// local element is being edited
(local.id === localAppState.editingElement?.id ||
local.id === localAppState.resizingElement?.id ||
local.id === localAppState.draggingElement?.id ||
// local element is newer
local.version > remote.version ||
// resolve conflicting edits deterministically by taking the one with
// the lowest versionNonce
(local.version === remote.version &&
local.versionNonce < remote.versionNonce))
) {
return true;
}
return false;
};
export const reconcileElements = (
localElements: readonly ExcalidrawElement[],
remoteElements: readonly BroadcastedExcalidrawElement[],
localAppState: AppState,
): ReconciledElements => {
const localElementsData =
arrayToMapWithIndex<ExcalidrawElement>(localElements);
const reconciledElements: ExcalidrawElement[] = localElements.slice();
const duplicates = new WeakMap<ExcalidrawElement, true>();
let cursor = 0;
let offset = 0;
let remoteElementIdx = -1;
for (const remoteElement of remoteElements) {
remoteElementIdx++;
const local = localElementsData.get(remoteElement.id);
if (shouldDiscardRemoteElement(localAppState, local?.[0], remoteElement)) {
if (remoteElement[PRECEDING_ELEMENT_KEY]) {
delete remoteElement[PRECEDING_ELEMENT_KEY];
}
continue;
}
// Mark duplicate for removal as it'll be replaced with the remote element
if (local) {
// Unless the remote and local elements are the same element in which case
// we need to keep it as we'd otherwise discard it from the resulting
// array.
if (local[0] === remoteElement) {
continue;
}
duplicates.set(local[0], true);
}
// parent may not be defined in case the remote client is running an older
// excalidraw version
const parent =
remoteElement[PRECEDING_ELEMENT_KEY] ||
remoteElements[remoteElementIdx - 1]?.id ||
null;
if (parent != null) {
delete remoteElement[PRECEDING_ELEMENT_KEY];
// ^ indicates the element is the first in elements array
if (parent === "^") {
offset++;
if (cursor === 0) {
reconciledElements.unshift(remoteElement);
localElementsData.set(remoteElement.id, [
remoteElement,
cursor - offset,
]);
} else {
reconciledElements.splice(cursor + 1, 0, remoteElement);
localElementsData.set(remoteElement.id, [
remoteElement,
cursor + 1 - offset,
]);
cursor++;
}
} else {
let idx = localElementsData.has(parent)
? localElementsData.get(parent)![1]
: null;
if (idx != null) {
idx += offset;
}
if (idx != null && idx >= cursor) {
reconciledElements.splice(idx + 1, 0, remoteElement);
offset++;
localElementsData.set(remoteElement.id, [
remoteElement,
idx + 1 - offset,
]);
cursor = idx + 1;
} else if (idx != null) {
reconciledElements.splice(cursor + 1, 0, remoteElement);
offset++;
localElementsData.set(remoteElement.id, [
remoteElement,
cursor + 1 - offset,
]);
cursor++;
} else {
reconciledElements.push(remoteElement);
localElementsData.set(remoteElement.id, [
remoteElement,
reconciledElements.length - 1 - offset,
]);
}
}
// no parent z-index information, local element exists → replace in place
} else if (local) {
reconciledElements[local[1]] = remoteElement;
localElementsData.set(remoteElement.id, [remoteElement, local[1]]);
// otherwise push to the end
} else {
reconciledElements.push(remoteElement);
localElementsData.set(remoteElement.id, [
remoteElement,
reconciledElements.length - 1 - offset,
]);
}
}
const ret: readonly ExcalidrawElement[] = reconciledElements.filter(
(element) => !duplicates.has(element),
);
return ret as ReconciledElements;
};

View File

@@ -1,5 +1,5 @@
import React from "react";
import { Footer } from "../../src/packages/excalidraw/index";
import { Footer } from "../../packages/excalidraw/index";
import { EncryptedIcon } from "./EncryptedIcon";
import { ExcalidrawPlusAppLink } from "./ExcalidrawPlusAppLink";
import { isExcalidrawPlusSignedUser } from "../app_constants";

View File

@@ -1,12 +1,19 @@
import React from "react";
import { PlusPromoIcon } from "../../src/components/icons";
import { MainMenu } from "../../src/packages/excalidraw/index";
import {
arrowBarToLeftIcon,
ExcalLogo,
} from "../../packages/excalidraw/components/icons";
import { Theme } from "../../packages/excalidraw/element/types";
import { MainMenu } from "../../packages/excalidraw/index";
import { isExcalidrawPlusSignedUser } from "../app_constants";
import { LanguageList } from "./LanguageList";
export const AppMainMenu: React.FC<{
setCollabDialogShown: (toggle: boolean) => any;
onCollabDialogOpen: () => any;
isCollaborating: boolean;
isCollabEnabled: boolean;
theme: Theme | "system";
setTheme: (theme: Theme | "system") => void;
}> = React.memo((props) => {
return (
<MainMenu>
@@ -17,25 +24,38 @@ export const AppMainMenu: React.FC<{
{props.isCollabEnabled && (
<MainMenu.DefaultItems.LiveCollaborationTrigger
isCollaborating={props.isCollaborating}
onSelect={() => props.setCollabDialogShown(true)}
onSelect={() => props.onCollabDialogOpen()}
/>
)}
<MainMenu.DefaultItems.CommandPalette className="highlighted" />
<MainMenu.DefaultItems.Help />
<MainMenu.DefaultItems.ClearCanvas />
<MainMenu.Separator />
<MainMenu.ItemLink
icon={PlusPromoIcon}
icon={ExcalLogo}
href={`${
import.meta.env.VITE_APP_PLUS_LP
import.meta.env.VITE_APP_PLUS_APP
}/plus?utm_source=excalidraw&utm_medium=app&utm_content=hamburger`}
className="ExcalidrawPlus"
className=""
>
Excalidraw+
</MainMenu.ItemLink>
<MainMenu.DefaultItems.Socials />
<MainMenu.ItemLink
icon={arrowBarToLeftIcon}
href={`${import.meta.env.VITE_APP_PLUS_APP}${
isExcalidrawPlusSignedUser ? "" : "/sign-up"
}?utm_source=signin&utm_medium=app&utm_content=hamburger`}
className="highlighted"
>
{isExcalidrawPlusSignedUser ? "Sign in" : "Sign up"}
</MainMenu.ItemLink>
<MainMenu.Separator />
<MainMenu.DefaultItems.ToggleTheme />
<MainMenu.DefaultItems.ToggleTheme
allowSystemTheme
theme={props.theme}
onSelect={props.setTheme}
/>
<MainMenu.ItemCustom>
<LanguageList style={{ width: "100%" }} />
</MainMenu.ItemCustom>

View File

@@ -1,12 +1,12 @@
import React from "react";
import { PlusPromoIcon } from "../../src/components/icons";
import { useI18n } from "../../src/i18n";
import { WelcomeScreen } from "../../src/packages/excalidraw/index";
import { arrowBarToLeftIcon } from "../../packages/excalidraw/components/icons";
import { useI18n } from "../../packages/excalidraw/i18n";
import { WelcomeScreen } from "../../packages/excalidraw/index";
import { isExcalidrawPlusSignedUser } from "../app_constants";
import { POINTER_EVENTS } from "../../src/constants";
import { POINTER_EVENTS } from "../../packages/excalidraw/constants";
export const AppWelcomeScreen: React.FC<{
setCollabDialogShown: (toggle: boolean) => any;
onCollabDialogOpen: () => any;
isCollabEnabled: boolean;
}> = React.memo((props) => {
const { t } = useI18n();
@@ -52,7 +52,7 @@ export const AppWelcomeScreen: React.FC<{
<WelcomeScreen.Center.MenuItemHelp />
{props.isCollabEnabled && (
<WelcomeScreen.Center.MenuItemLiveCollaborationTrigger
onSelect={() => props.setCollabDialogShown(true)}
onSelect={() => props.onCollabDialogOpen()}
/>
)}
{!isExcalidrawPlusSignedUser && (
@@ -61,9 +61,9 @@ export const AppWelcomeScreen: React.FC<{
import.meta.env.VITE_APP_PLUS_LP
}/plus?utm_source=excalidraw&utm_medium=app&utm_content=welcomeScreenGuest`}
shortcut={null}
icon={PlusPromoIcon}
icon={arrowBarToLeftIcon}
>
Try Excalidraw Plus!
Sign up
</WelcomeScreen.Center.MenuItemLink>
)}
</WelcomeScreen.Center.Menu>

View File

@@ -1,6 +1,6 @@
import { shield } from "../../src/components/icons";
import { Tooltip } from "../../src/components/Tooltip";
import { useI18n } from "../../src/i18n";
import { shield } from "../../packages/excalidraw/components/icons";
import { Tooltip } from "../../packages/excalidraw/components/Tooltip";
import { useI18n } from "../../packages/excalidraw/i18n";
export const EncryptedIcon = () => {
const { t } = useI18n();

View File

@@ -1,25 +1,36 @@
import React from "react";
import { Card } from "../../src/components/Card";
import { ToolButton } from "../../src/components/ToolButton";
import { serializeAsJSON } from "../../src/data/json";
import { Card } from "../../packages/excalidraw/components/Card";
import { ToolButton } from "../../packages/excalidraw/components/ToolButton";
import { serializeAsJSON } from "../../packages/excalidraw/data/json";
import { loadFirebaseStorage, saveFilesToFirebase } from "../data/firebase";
import { FileId, NonDeletedExcalidrawElement } from "../../src/element/types";
import { AppState, BinaryFileData, BinaryFiles } from "../../src/types";
import {
FileId,
NonDeletedExcalidrawElement,
} from "../../packages/excalidraw/element/types";
import {
AppState,
BinaryFileData,
BinaryFiles,
} from "../../packages/excalidraw/types";
import { nanoid } from "nanoid";
import { useI18n } from "../../src/i18n";
import { encryptData, generateEncryptionKey } from "../../src/data/encryption";
import { isInitializedImageElement } from "../../src/element/typeChecks";
import { useI18n } from "../../packages/excalidraw/i18n";
import {
encryptData,
generateEncryptionKey,
} from "../../packages/excalidraw/data/encryption";
import { isInitializedImageElement } from "../../packages/excalidraw/element/typeChecks";
import { FILE_UPLOAD_MAX_BYTES } from "../app_constants";
import { encodeFilesForUpload } from "../data/FileManager";
import { MIME_TYPES } from "../../src/constants";
import { trackEvent } from "../../src/analytics";
import { getFrame } from "../../src/utils";
import { ExcalidrawLogo } from "../../src/components/ExcalidrawLogo";
import { MIME_TYPES } from "../../packages/excalidraw/constants";
import { trackEvent } from "../../packages/excalidraw/analytics";
import { getFrame } from "../../packages/excalidraw/utils";
import { ExcalidrawLogo } from "../../packages/excalidraw/components/ExcalidrawLogo";
export const exportToExcalidrawPlus = async (
elements: readonly NonDeletedExcalidrawElement[],
appState: Partial<AppState>,
files: BinaryFiles,
name: string,
) => {
const firebase = await loadFirebaseStorage();
@@ -43,7 +54,7 @@ export const exportToExcalidrawPlus = async (
.ref(`/migrations/scenes/${id}`)
.put(blob, {
customMetadata: {
data: JSON.stringify({ version: 2, name: appState.name }),
data: JSON.stringify({ version: 2, name }),
created: Date.now().toString(),
},
});
@@ -79,9 +90,10 @@ export const ExportToExcalidrawPlus: React.FC<{
elements: readonly NonDeletedExcalidrawElement[];
appState: Partial<AppState>;
files: BinaryFiles;
name: string;
onError: (error: Error) => void;
onSuccess: () => void;
}> = ({ elements, appState, files, onError, onSuccess }) => {
}> = ({ elements, appState, files, name, onError, onSuccess }) => {
const { t } = useI18n();
return (
<Card color="primary">
@@ -107,7 +119,7 @@ export const ExportToExcalidrawPlus: React.FC<{
onClick={async () => {
try {
trackEvent("export", "eplus", `ui (${getFrame()})`);
await exportToExcalidrawPlus(elements, appState, files);
await exportToExcalidrawPlus(elements, appState, files, name);
onSuccess();
} catch (error: any) {
console.error(error);

View File

@@ -1,7 +1,7 @@
import oc from "open-color";
import React from "react";
import { THEME } from "../../src/constants";
import { Theme } from "../../src/element/types";
import { THEME } from "../../packages/excalidraw/constants";
import { Theme } from "../../packages/excalidraw/element/types";
// https://github.com/tholman/github-corners
export const GitHubCorner = React.memo(

View File

@@ -1,8 +1,8 @@
import { useSetAtom } from "jotai";
import React from "react";
import { appLangCodeAtom } from "..";
import { useI18n } from "../../src/i18n";
import { languages } from "../../src/i18n";
import { appLangCodeAtom } from "../App";
import { useI18n } from "../../packages/excalidraw/i18n";
import { languages } from "../../packages/excalidraw/i18n";
export const LanguageList = ({ style }: { style?: React.CSSProperties }) => {
const { t, langCode } = useI18n();

View File

@@ -1,7 +1,7 @@
import React from "react";
import * as Sentry from "@sentry/browser";
import { t } from "../i18n";
import Trans from "./Trans";
import { t } from "../../packages/excalidraw/i18n";
import Trans from "../../packages/excalidraw/components/Trans";
interface TopErrorBoundaryState {
hasError: boolean;
@@ -67,6 +67,8 @@ export class TopErrorBoundary extends React.Component<
window.open(
`https://github.com/excalidraw/excalidraw/issues/new?body=${body}`,
"_blank",
"noopener noreferrer",
);
}

View File

@@ -1,19 +1,19 @@
import { compressData } from "../../src/data/encode";
import { newElementWith } from "../../src/element/mutateElement";
import { isInitializedImageElement } from "../../src/element/typeChecks";
import { compressData } from "../../packages/excalidraw/data/encode";
import { newElementWith } from "../../packages/excalidraw/element/mutateElement";
import { isInitializedImageElement } from "../../packages/excalidraw/element/typeChecks";
import {
ExcalidrawElement,
ExcalidrawImageElement,
FileId,
InitializedExcalidrawImageElement,
} from "../../src/element/types";
import { t } from "../../src/i18n";
} from "../../packages/excalidraw/element/types";
import { t } from "../../packages/excalidraw/i18n";
import {
BinaryFileData,
BinaryFileMetadata,
ExcalidrawImperativeAPI,
BinaryFiles,
} from "../../src/types";
} from "../../packages/excalidraw/types";
export class FileManager {
/** files being fetched */

View File

@@ -6,16 +6,34 @@
*
* - DataState refers to full state of the app: appState, elements, images,
* though some state is saved separately (collab username, library) for one
* reason or another. We also save different data to different sotrage
* reason or another. We also save different data to different storage
* (localStorage, indexedDB).
*/
import { createStore, entries, del, getMany, set, setMany } from "idb-keyval";
import { clearAppStateForLocalStorage } from "../../src/appState";
import { clearElementsForLocalStorage } from "../../src/element";
import { ExcalidrawElement, FileId } from "../../src/element/types";
import { AppState, BinaryFileData, BinaryFiles } from "../../src/types";
import { debounce } from "../../src/utils";
import {
createStore,
entries,
del,
getMany,
set,
setMany,
get,
} from "idb-keyval";
import { clearAppStateForLocalStorage } from "../../packages/excalidraw/appState";
import { LibraryPersistedData } from "../../packages/excalidraw/data/library";
import { ImportedDataState } from "../../packages/excalidraw/data/types";
import { clearElementsForLocalStorage } from "../../packages/excalidraw/element";
import {
ExcalidrawElement,
FileId,
} from "../../packages/excalidraw/element/types";
import {
AppState,
BinaryFileData,
BinaryFiles,
} from "../../packages/excalidraw/types";
import { MaybePromise } from "../../packages/excalidraw/utility-types";
import { debounce } from "../../packages/excalidraw/utils";
import { SAVE_TO_LOCAL_STORAGE_TIMEOUT, STORAGE_KEYS } from "../app_constants";
import { FileManager } from "./FileManager";
import { Locker } from "./Locker";
@@ -176,3 +194,52 @@ export class LocalData {
},
});
}
export class LibraryIndexedDBAdapter {
/** IndexedDB database and store name */
private static idb_name = STORAGE_KEYS.IDB_LIBRARY;
/** library data store key */
private static key = "libraryData";
private static store = createStore(
`${LibraryIndexedDBAdapter.idb_name}-db`,
`${LibraryIndexedDBAdapter.idb_name}-store`,
);
static async load() {
const IDBData = await get<LibraryPersistedData>(
LibraryIndexedDBAdapter.key,
LibraryIndexedDBAdapter.store,
);
return IDBData || null;
}
static save(data: LibraryPersistedData): MaybePromise<void> {
return set(
LibraryIndexedDBAdapter.key,
data,
LibraryIndexedDBAdapter.store,
);
}
}
/** LS Adapter used only for migrating LS library data
* to indexedDB */
export class LibraryLocalStorageMigrationAdapter {
static load() {
const LSData = localStorage.getItem(
STORAGE_KEYS.__LEGACY_LOCAL_STORAGE_LIBRARY,
);
if (LSData != null) {
const libraryItems: ImportedDataState["libraryItems"] =
JSON.parse(LSData);
if (libraryItems) {
return { libraryItems };
}
}
return null;
}
static clear() {
localStorage.removeItem(STORAGE_KEYS.__LEGACY_LOCAL_STORAGE_LIBRARY);
}
}

View File

@@ -1,20 +1,31 @@
import { ExcalidrawElement, FileId } from "../../src/element/types";
import { getSceneVersion } from "../../src/element";
import {
ExcalidrawElement,
FileId,
OrderedExcalidrawElement,
} from "../../packages/excalidraw/element/types";
import { getSceneVersion } from "../../packages/excalidraw/element";
import Portal from "../collab/Portal";
import { restoreElements } from "../../src/data/restore";
import { restoreElements } from "../../packages/excalidraw/data/restore";
import {
AppState,
BinaryFileData,
BinaryFileMetadata,
DataURL,
} from "../../src/types";
} from "../../packages/excalidraw/types";
import { FILE_CACHE_MAX_AGE_SEC } from "../app_constants";
import { decompressData } from "../../src/data/encode";
import { encryptData, decryptData } from "../../src/data/encryption";
import { MIME_TYPES } from "../../src/constants";
import { reconcileElements } from "../collab/reconciliation";
import { decompressData } from "../../packages/excalidraw/data/encode";
import {
encryptData,
decryptData,
} from "../../packages/excalidraw/data/encryption";
import { MIME_TYPES } from "../../packages/excalidraw/constants";
import { getSyncableElements, SyncableExcalidrawElement } from ".";
import { ResolutionType } from "../../src/utility-types";
import { ResolutionType } from "../../packages/excalidraw/utility-types";
import type { Socket } from "socket.io-client";
import {
RemoteExcalidrawElement,
reconcileElements,
} from "../../packages/excalidraw/data/reconcile";
// private
// -----------------------------------------------------------------------------
@@ -132,12 +143,12 @@ const decryptElements = async (
};
class FirebaseSceneVersionCache {
private static cache = new WeakMap<SocketIOClient.Socket, number>();
static get = (socket: SocketIOClient.Socket) => {
private static cache = new WeakMap<Socket, number>();
static get = (socket: Socket) => {
return FirebaseSceneVersionCache.cache.get(socket);
};
static set = (
socket: SocketIOClient.Socket,
socket: Socket,
elements: readonly SyncableExcalidrawElement[],
) => {
FirebaseSceneVersionCache.cache.set(socket, getSceneVersion(elements));
@@ -223,7 +234,7 @@ export const saveToFirebase = async (
!socket ||
isSavedToFirebase(portal, elements)
) {
return false;
return null;
}
const firebase = await loadFirestore();
@@ -231,56 +242,59 @@ export const saveToFirebase = async (
const docRef = firestore.collection("scenes").doc(roomId);
const savedData = await firestore.runTransaction(async (transaction) => {
const storedScene = await firestore.runTransaction(async (transaction) => {
const snapshot = await transaction.get(docRef);
if (!snapshot.exists) {
const sceneDocument = await createFirebaseSceneDocument(
const storedScene = await createFirebaseSceneDocument(
firebase,
elements,
roomKey,
);
transaction.set(docRef, sceneDocument);
transaction.set(docRef, storedScene);
return {
elements,
reconciledElements: null,
};
return storedScene;
}
const prevDocData = snapshot.data() as FirebaseStoredScene;
const prevElements = getSyncableElements(
await decryptElements(prevDocData, roomKey),
const prevStoredScene = snapshot.data() as FirebaseStoredScene;
const prevStoredElements = getSyncableElements(
restoreElements(await decryptElements(prevStoredScene, roomKey), null),
);
const reconciledElements = getSyncableElements(
reconcileElements(elements, prevElements, appState),
reconcileElements(
elements,
prevStoredElements as OrderedExcalidrawElement[] as RemoteExcalidrawElement[],
appState,
),
);
const sceneDocument = await createFirebaseSceneDocument(
const storedScene = await createFirebaseSceneDocument(
firebase,
reconciledElements,
roomKey,
);
transaction.update(docRef, sceneDocument);
return {
elements,
reconciledElements,
};
transaction.update(docRef, storedScene);
// Return the stored elements as the in memory `reconciledElements` could have mutated in the meantime
return storedScene;
});
FirebaseSceneVersionCache.set(socket, savedData.elements);
const storedElements = getSyncableElements(
restoreElements(await decryptElements(storedScene, roomKey), null),
);
return { reconciledElements: savedData.reconciledElements };
FirebaseSceneVersionCache.set(socket, storedElements);
return storedElements;
};
export const loadFromFirebase = async (
roomId: string,
roomKey: string,
socket: SocketIOClient.Socket | null,
): Promise<readonly ExcalidrawElement[] | null> => {
socket: Socket | null,
): Promise<readonly SyncableExcalidrawElement[] | null> => {
const firebase = await loadFirestore();
const db = firebase.firestore();
@@ -291,14 +305,14 @@ export const loadFromFirebase = async (
}
const storedScene = doc.data() as FirebaseStoredScene;
const elements = getSyncableElements(
await decryptElements(storedScene, roomKey),
restoreElements(await decryptElements(storedScene, roomKey), null),
);
if (socket) {
FirebaseSceneVersionCache.set(socket, elements);
}
return restoreElements(elements, null);
return elements;
};
export const loadFilesFromFirebase = async (

View File

@@ -1,37 +1,47 @@
import { compressData, decompressData } from "../../src/data/encode";
import {
compressData,
decompressData,
} from "../../packages/excalidraw/data/encode";
import {
decryptData,
generateEncryptionKey,
IV_LENGTH_BYTES,
} from "../../src/data/encryption";
import { serializeAsJSON } from "../../src/data/json";
import { restore } from "../../src/data/restore";
import { ImportedDataState } from "../../src/data/types";
import { isInvisiblySmallElement } from "../../src/element/sizeHelpers";
import { isInitializedImageElement } from "../../src/element/typeChecks";
import { ExcalidrawElement, FileId } from "../../src/element/types";
import { t } from "../../src/i18n";
} from "../../packages/excalidraw/data/encryption";
import { serializeAsJSON } from "../../packages/excalidraw/data/json";
import { restore } from "../../packages/excalidraw/data/restore";
import { ImportedDataState } from "../../packages/excalidraw/data/types";
import { SceneBounds } from "../../packages/excalidraw/element/bounds";
import { isInvisiblySmallElement } from "../../packages/excalidraw/element/sizeHelpers";
import { isInitializedImageElement } from "../../packages/excalidraw/element/typeChecks";
import {
ExcalidrawElement,
FileId,
OrderedExcalidrawElement,
} from "../../packages/excalidraw/element/types";
import { t } from "../../packages/excalidraw/i18n";
import {
AppState,
BinaryFileData,
BinaryFiles,
SocketId,
UserIdleState,
} from "../../src/types";
import { bytesToHexString } from "../../src/utils";
} from "../../packages/excalidraw/types";
import { MakeBrand } from "../../packages/excalidraw/utility-types";
import { bytesToHexString } from "../../packages/excalidraw/utils";
import {
DELETED_ELEMENT_TIMEOUT,
FILE_UPLOAD_MAX_BYTES,
ROOM_ID_BYTES,
WS_SUBTYPES,
} from "../app_constants";
import { encodeFilesForUpload } from "./FileManager";
import { saveFilesToFirebase } from "./firebase";
export type SyncableExcalidrawElement = ExcalidrawElement & {
_brand: "SyncableExcalidrawElement";
};
export type SyncableExcalidrawElement = OrderedExcalidrawElement &
MakeBrand<"SyncableExcalidrawElement">;
export const isSyncableElement = (
element: ExcalidrawElement,
element: OrderedExcalidrawElement,
): element is SyncableExcalidrawElement => {
if (element.isDeleted) {
if (element.updated > Date.now() - DELETED_ELEMENT_TIMEOUT) {
@@ -42,7 +52,9 @@ export const isSyncableElement = (
return !isInvisiblySmallElement(element);
};
export const getSyncableElements = (elements: readonly ExcalidrawElement[]) =>
export const getSyncableElements = (
elements: readonly OrderedExcalidrawElement[],
) =>
elements.filter((element) =>
isSyncableElement(element),
) as SyncableExcalidrawElement[];
@@ -56,67 +68,49 @@ const generateRoomId = async () => {
return bytesToHexString(buffer);
};
/**
* Right now the reason why we resolve connection params (url, polling...)
* from upstream is to allow changing the params immediately when needed without
* having to wait for clients to update the SW.
*
* If REACT_APP_WS_SERVER_URL env is set, we use that instead (useful for forks)
*/
export const getCollabServer = async (): Promise<{
url: string;
polling: boolean;
}> => {
if (import.meta.env.VITE_APP_WS_SERVER_URL) {
return {
url: import.meta.env.VITE_APP_WS_SERVER_URL,
polling: true,
};
}
try {
const resp = await fetch(
`${import.meta.env.VITE_APP_PORTAL_URL}/collab-server`,
);
return await resp.json();
} catch (error) {
console.error(error);
throw new Error(t("errors.cannotResolveCollabServer"));
}
};
export type EncryptedData = {
data: ArrayBuffer;
iv: Uint8Array;
};
export type SocketUpdateDataSource = {
INVALID_RESPONSE: {
type: WS_SUBTYPES.INVALID_RESPONSE;
};
SCENE_INIT: {
type: "SCENE_INIT";
type: WS_SUBTYPES.INIT;
payload: {
elements: readonly ExcalidrawElement[];
};
};
SCENE_UPDATE: {
type: "SCENE_UPDATE";
type: WS_SUBTYPES.UPDATE;
payload: {
elements: readonly ExcalidrawElement[];
};
};
MOUSE_LOCATION: {
type: "MOUSE_LOCATION";
type: WS_SUBTYPES.MOUSE_LOCATION;
payload: {
socketId: string;
socketId: SocketId;
pointer: { x: number; y: number; tool: "pointer" | "laser" };
button: "down" | "up";
selectedElementIds: AppState["selectedElementIds"];
username: string;
};
};
IDLE_STATUS: {
type: "IDLE_STATUS";
USER_VISIBLE_SCENE_BOUNDS: {
type: WS_SUBTYPES.USER_VISIBLE_SCENE_BOUNDS;
payload: {
socketId: string;
socketId: SocketId;
username: string;
sceneBounds: SceneBounds;
};
};
IDLE_STATUS: {
type: WS_SUBTYPES.IDLE_STATUS;
payload: {
socketId: SocketId;
userState: UserIdleState;
username: string;
};
@@ -124,10 +118,7 @@ export type SocketUpdateDataSource = {
};
export type SocketUpdateDataIncoming =
| SocketUpdateDataSource[keyof SocketUpdateDataSource]
| {
type: "INVALID_RESPONSE";
};
SocketUpdateDataSource[keyof SocketUpdateDataSource];
export type SocketUpdateData =
SocketUpdateDataSource[keyof SocketUpdateDataSource] & {

Some files were not shown because too many files have changed in this diff Show More