mirror of
https://github.com/element-hq/element-web.git
synced 2025-12-07 01:21:02 +00:00
Compare commits
3353 Commits
dx/typescr
...
t3chguy/de
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
96ba5a02b9 | ||
|
|
705625da7d | ||
|
|
e859efe29e | ||
|
|
77c822a155 | ||
|
|
898b6bdd2c | ||
|
|
f56f8148b7 | ||
|
|
f26b51c0b6 | ||
|
|
5f7e8077cd | ||
|
|
2a81dc40cd | ||
|
|
8d235bdb19 | ||
|
|
3b75e2a3fb | ||
|
|
c05c429803 | ||
|
|
2b99496025 | ||
|
|
fd62350ce9 | ||
|
|
07ed8e8a2d | ||
|
|
80018bccff | ||
|
|
bc0ae8de14 | ||
|
|
89380ab59f | ||
|
|
63c8550791 | ||
|
|
8d7f2b5c13 | ||
|
|
8904453bbf | ||
|
|
0943ffa0aa | ||
|
|
b428b4aa9d | ||
|
|
786a0286cf | ||
|
|
450ad1dd85 | ||
|
|
8d77b2a15a | ||
|
|
7cb80d560d | ||
|
|
b318c40f4d | ||
|
|
46d6935517 | ||
|
|
097506f0c1 | ||
|
|
b5944e2eeb | ||
|
|
8720a7cef7 | ||
|
|
2a33d553e4 | ||
|
|
36285699ac | ||
|
|
1691468145 | ||
|
|
9407af0bfb | ||
|
|
c65da80f51 | ||
|
|
00a9bb3f0e | ||
|
|
6a797684db | ||
|
|
36c80099fb | ||
|
|
07ce53ce99 | ||
|
|
50871f6973 | ||
|
|
013086cbaf | ||
|
|
aa3096ab79 | ||
|
|
c44555cdf0 | ||
|
|
60cf3ce192 | ||
|
|
ebd632cf47 | ||
|
|
3f1a32105a | ||
|
|
42be67e57a | ||
|
|
350b84a159 | ||
|
|
ec60099105 | ||
|
|
14dc9a0418 | ||
|
|
d282416ea6 | ||
|
|
3baba1da65 | ||
|
|
e428a1eb53 | ||
|
|
1c0b04a3a5 | ||
|
|
34c80bb785 | ||
|
|
de02f04395 | ||
|
|
1b31e7f67b | ||
|
|
e0ab0cfa4e | ||
|
|
53bbe891eb | ||
|
|
7721c9e410 | ||
|
|
63c1ba07e8 | ||
|
|
7475c507aa | ||
|
|
861ac3b50c | ||
|
|
994fcd6319 | ||
|
|
11d70feb90 | ||
|
|
fed93f5759 | ||
|
|
95b981a203 | ||
|
|
8b7dafffc9 | ||
|
|
8fa6acd0f0 | ||
|
|
e92d75b4fd | ||
|
|
787feca6a4 | ||
|
|
42b6703f9f | ||
|
|
1bbe4c3fbc | ||
|
|
a37d5d6a2b | ||
|
|
f81f82c404 | ||
|
|
7076859a02 | ||
|
|
573f438a6b | ||
|
|
19166b57ba | ||
|
|
8a4990b56a | ||
|
|
773754df3a | ||
|
|
fb7b123d43 | ||
|
|
72733bcac1 | ||
|
|
87f2b6fb0b | ||
|
|
5a84da09cc | ||
|
|
3c2614e62c | ||
|
|
473fce9b8b | ||
|
|
4535503e71 | ||
|
|
a2f9b5efdf | ||
|
|
205d7f820f | ||
|
|
1ec143f7fe | ||
|
|
97c10116ad | ||
|
|
bfe83e024d | ||
|
|
acf95b18b8 | ||
|
|
7fff2900c5 | ||
|
|
a17be672d3 | ||
|
|
9ac9bc77aa | ||
|
|
a3e7ab0bb4 | ||
|
|
6512b236cd | ||
|
|
07b42061a1 | ||
|
|
191b1dd570 | ||
|
|
11be4ab422 | ||
|
|
a083d2fd38 | ||
|
|
ddc789320a | ||
|
|
ff9286fe28 | ||
|
|
f7c08d1c68 | ||
|
|
eadff6333b | ||
|
|
baac24adf3 | ||
|
|
f42f7c923f | ||
|
|
78ed91041b | ||
|
|
804a57c80e | ||
|
|
4e47537614 | ||
|
|
7584d58d11 | ||
|
|
f1a9e080c3 | ||
|
|
96934a5a8d | ||
|
|
179ba97543 | ||
|
|
227b56a412 | ||
|
|
8822a0b4b7 | ||
|
|
3a4e6302ad | ||
|
|
7b19facce1 | ||
|
|
e3a4b9ebad | ||
|
|
9520798c7f | ||
|
|
8c76fe4765 | ||
|
|
7b8d9d3313 | ||
|
|
ea89fe3955 | ||
|
|
aa8d22984e | ||
|
|
69c28ad74f | ||
|
|
85d5c2aafc | ||
|
|
bad5edae68 | ||
|
|
c32994f6f7 | ||
|
|
f937dea88b | ||
|
|
49375dc94b | ||
|
|
ba7622d5bc | ||
|
|
0801898ada | ||
|
|
885b70650d | ||
|
|
d40b99b2a8 | ||
|
|
f09554a5f3 | ||
|
|
727fca80b9 | ||
|
|
2325911922 | ||
|
|
39894a26f9 | ||
|
|
4239abadc4 | ||
|
|
d83534548a | ||
|
|
34c25bb581 | ||
|
|
80cea67a3d | ||
|
|
9a24e3df2d | ||
|
|
7bb7934a85 | ||
|
|
a6e78dbf6c | ||
|
|
5e555ff44f | ||
|
|
20f3425e4e | ||
|
|
bc7655c930 | ||
|
|
e8ebdd4bff | ||
|
|
30d7e5c0b2 | ||
|
|
85a2a0893a | ||
|
|
5ee3f4cb9e | ||
|
|
7dc006e13e | ||
|
|
4713502232 | ||
|
|
74c796d77a | ||
|
|
a0c0d366af | ||
|
|
f5ae24dbd2 | ||
|
|
addb335281 | ||
|
|
2cabeb68ce | ||
|
|
0a1c4b9e60 | ||
|
|
29ddd9e292 | ||
|
|
9da1263581 | ||
|
|
b90b0617dc | ||
|
|
8805220c9d | ||
|
|
2b13ae3649 | ||
|
|
405060cb6a | ||
|
|
9045d9ccaa | ||
|
|
5b8628ecd8 | ||
|
|
d7fb7cb1e5 | ||
|
|
a0875c9aae | ||
|
|
c5508e0c43 | ||
|
|
bb8b256bbb | ||
|
|
599da30c4b | ||
|
|
58e860de1b | ||
|
|
cb79af0d58 | ||
|
|
5ff2e8fa16 | ||
|
|
37d607181c | ||
|
|
80b9ca79e0 | ||
|
|
48aab77424 | ||
|
|
720bfacbd9 | ||
|
|
c4762d6c86 | ||
|
|
a193d8b726 | ||
|
|
82d8d734b1 | ||
|
|
2bca0fd08c | ||
|
|
ebe41efec2 | ||
|
|
d2a3de8b5a | ||
|
|
0a858e7a79 | ||
|
|
c73301deb1 | ||
|
|
a24dab6859 | ||
|
|
1e9112aee8 | ||
|
|
0935e48b1c | ||
|
|
f05b2691b8 | ||
|
|
43fa2e533f | ||
|
|
7bd04185b5 | ||
|
|
62fe7e5024 | ||
|
|
63197f8a25 | ||
|
|
dc9e929758 | ||
|
|
b3daf21561 | ||
|
|
8848df1aa2 | ||
|
|
40faccd4ee | ||
|
|
b230e8ae62 | ||
|
|
15cc3fbcf3 | ||
|
|
aa17b85823 | ||
|
|
1e3c145018 | ||
|
|
ccb3922202 | ||
|
|
81b8e864f7 | ||
|
|
3f4ae7382b | ||
|
|
f614c8f0a0 | ||
|
|
48b9ec2690 | ||
|
|
cbcb0be14a | ||
|
|
557a40fad5 | ||
|
|
cd196acfd1 | ||
|
|
8893393f79 | ||
|
|
e9e9bce1ad | ||
|
|
2fd4c4f6c4 | ||
|
|
a0c654a2e4 | ||
|
|
54f818b64d | ||
|
|
7073fb2faf | ||
|
|
6e8f0f6f6d | ||
|
|
627377229c | ||
|
|
3153f8862a | ||
|
|
6efd8a4642 | ||
|
|
3080c97007 | ||
|
|
380ab17932 | ||
|
|
1424314f12 | ||
|
|
446a4c87b6 | ||
|
|
d5f4b1bc86 | ||
|
|
bc45415513 | ||
|
|
4b8ed0f16f | ||
|
|
26ac7462fd | ||
|
|
25d05f8ab2 | ||
|
|
676547e54c | ||
|
|
03a6b59eb5 | ||
|
|
c9aa0ceb00 | ||
|
|
59e526e318 | ||
|
|
79b6a6fb69 | ||
|
|
181f91a7e8 | ||
|
|
9a3f00a621 | ||
|
|
31345ddd36 | ||
|
|
88ddf05930 | ||
|
|
5a1b38cd74 | ||
|
|
dd17436eb0 | ||
|
|
334d268555 | ||
|
|
d6e3be31d8 | ||
|
|
af144e28d8 | ||
|
|
98568bd2ad | ||
|
|
95f3d3c2b7 | ||
|
|
6af3afa6fb | ||
|
|
a177fef95b | ||
|
|
dc72285f6f | ||
|
|
054484bc42 | ||
|
|
8568578095 | ||
|
|
260eec2fb7 | ||
|
|
939ddbbee3 | ||
|
|
4ec06daf3e | ||
|
|
d43767dfa8 | ||
|
|
971d6736a3 | ||
|
|
9f9e56c008 | ||
|
|
e4d2edb624 | ||
|
|
75e7fd5e87 | ||
|
|
2f88b3d1fd | ||
|
|
cffdaa6281 | ||
|
|
916b883de1 | ||
|
|
45410dc883 | ||
|
|
0b21ba0a27 | ||
|
|
5bd9529d37 | ||
|
|
630be696b1 | ||
|
|
085294d7b5 | ||
|
|
f22d719d38 | ||
|
|
df53ba6d3a | ||
|
|
7f66d65796 | ||
|
|
03e6280b6a | ||
|
|
88b3b922f9 | ||
|
|
d3f0af6fd1 | ||
|
|
9f27685a54 | ||
|
|
1f4006ac13 | ||
|
|
36ff766be3 | ||
|
|
ab54cbc329 | ||
|
|
f8701ee1fc | ||
|
|
1eea7fffbe | ||
|
|
8ecf47bce8 | ||
|
|
bc805d2989 | ||
|
|
4728503f66 | ||
|
|
419f37b31e | ||
|
|
a32aca434c | ||
|
|
73a8aad088 | ||
|
|
0273909a43 | ||
|
|
dd685934a3 | ||
|
|
5eebd54baf | ||
|
|
764654fffb | ||
|
|
a238990c25 | ||
|
|
655a1ae065 | ||
|
|
41d6fe3b23 | ||
|
|
a10d2b1828 | ||
|
|
af3fb76ecf | ||
|
|
d030a7d86f | ||
|
|
79163a1f16 | ||
|
|
9d1c724402 | ||
|
|
493e7f7f3e | ||
|
|
39bdcafbe2 | ||
|
|
df92294056 | ||
|
|
7a45ca2614 | ||
|
|
6d84073bec | ||
|
|
8e1561b1c7 | ||
|
|
0f01d7adbe | ||
|
|
579e9a3d3f | ||
|
|
167bcdf9d9 | ||
|
|
118f71ea3b | ||
|
|
7b4e00c72e | ||
|
|
35fdffb245 | ||
|
|
67fd02dc4a | ||
|
|
b1d94de413 | ||
|
|
a2589cab2e | ||
|
|
cfb800d916 | ||
|
|
4a25cc4b43 | ||
|
|
fd65226b1a | ||
|
|
722923befd | ||
|
|
fdefe624d2 | ||
|
|
2443ae118a | ||
|
|
bc27c1dcc3 | ||
|
|
be4f779150 | ||
|
|
d584dc0d52 | ||
|
|
e6a60e0770 | ||
|
|
31032525c9 | ||
|
|
42f1ae1dde | ||
|
|
fbd1e4f731 | ||
|
|
3091db7bb1 | ||
|
|
99553210be | ||
|
|
8fc13ba4b6 | ||
|
|
5722f074d1 | ||
|
|
4f718cb7d3 | ||
|
|
6452f27cb6 | ||
|
|
700886c0e2 | ||
|
|
668450325c | ||
|
|
b4aa375619 | ||
|
|
be92e64458 | ||
|
|
4d0c740ad2 | ||
|
|
438d07bc75 | ||
|
|
b4d343053d | ||
|
|
88d507f4f9 | ||
|
|
8e03b273ae | ||
|
|
4ffc77dfef | ||
|
|
e4d138f4d1 | ||
|
|
746c20bdba | ||
|
|
cd2bd81268 | ||
|
|
561868f12a | ||
|
|
833072f753 | ||
|
|
d1f0cbea27 | ||
|
|
9353b27ce7 | ||
|
|
60b3b95603 | ||
|
|
944516c2f7 | ||
|
|
e80ab738ce | ||
|
|
d60768daec | ||
|
|
a7ace95eac | ||
|
|
cdb65233b0 | ||
|
|
83186c0403 | ||
|
|
8776371ed4 | ||
|
|
5f9637b14e | ||
|
|
c924f59f41 | ||
|
|
c6134b1849 | ||
|
|
818ec7529c | ||
|
|
7c7cbe655a | ||
|
|
d379103352 | ||
|
|
844a318eb2 | ||
|
|
205f0f9f30 | ||
|
|
703ad190f8 | ||
|
|
1237fbf74c | ||
|
|
137b20b784 | ||
|
|
5de07e091f | ||
|
|
f3237fb0b0 | ||
|
|
e41b476be3 | ||
|
|
4506988ad6 | ||
|
|
734e698c7e | ||
|
|
ba9f962570 | ||
|
|
1dca6b60c3 | ||
|
|
4e47b75f0f | ||
|
|
55634304b0 | ||
|
|
eb2ff67e7b | ||
|
|
c5d04b3649 | ||
|
|
0845c515c4 | ||
|
|
76416ec7b9 | ||
|
|
b02a418cbb | ||
|
|
039b2d421f | ||
|
|
a26818ee3b | ||
|
|
e3aee58a6d | ||
|
|
ea158ed63f | ||
|
|
38c0bf3b62 | ||
|
|
6821a35444 | ||
|
|
9f9cd6ff08 | ||
|
|
f8b3be682a | ||
|
|
ab5ff85bff | ||
|
|
aa9851dc4e | ||
|
|
437b5241b9 | ||
|
|
42943f3ffc | ||
|
|
2fd4e474cb | ||
|
|
cf1eddf0ea | ||
|
|
cee4a754d7 | ||
|
|
72354161e2 | ||
|
|
fa1d2c7dfb | ||
|
|
42c0c19556 | ||
|
|
d3a0925e42 | ||
|
|
351a31c9ee | ||
|
|
2614cab64b | ||
|
|
15db387425 | ||
|
|
53cc1c78b1 | ||
|
|
be6528de26 | ||
|
|
087f1bc948 | ||
|
|
4360f5a63e | ||
|
|
65a87f1a53 | ||
|
|
b0c04834b6 | ||
|
|
b61d5b4475 | ||
|
|
6c3817fa34 | ||
|
|
e151d9ab53 | ||
|
|
f15b188297 | ||
|
|
ea16928d35 | ||
|
|
4651bf4eb4 | ||
|
|
5442d4050d | ||
|
|
695cc1b28b | ||
|
|
c94e3f00ed | ||
|
|
79e0661be3 | ||
|
|
6cf0809064 | ||
|
|
a0eb94704e | ||
|
|
e1e0d37478 | ||
|
|
9039e70990 | ||
|
|
596f297094 | ||
|
|
4f92927a3d | ||
|
|
b77218e65a | ||
|
|
c21e9f6383 | ||
|
|
4f8a8a2543 | ||
|
|
d615e69a86 | ||
|
|
db1d440e3b | ||
|
|
24fafe2588 | ||
|
|
1e06e3083f | ||
|
|
8e9f3a786c | ||
|
|
95f134a7c5 | ||
|
|
50f5c15027 | ||
|
|
65b43d8dc7 | ||
|
|
8dad4f5f10 | ||
|
|
a3a436ad64 | ||
|
|
ffb69d4c47 | ||
|
|
369ae1208e | ||
|
|
050dae7a9f | ||
|
|
a9cd567fc9 | ||
|
|
82073aea3e | ||
|
|
9cf7b8b6f6 | ||
|
|
fa5bd19368 | ||
|
|
fb72597fcf | ||
|
|
3ce0d78961 | ||
|
|
361636a3d1 | ||
|
|
0b49a7724b | ||
|
|
2db2cf2b1b | ||
|
|
c38505598f | ||
|
|
7e21f12678 | ||
|
|
4f43c57a96 | ||
|
|
60d3b59076 | ||
|
|
5a7956fd90 | ||
|
|
e193f57ac7 | ||
|
|
30f964447f | ||
|
|
cb9eccebed | ||
|
|
a0ae97c2e3 | ||
|
|
fd62e04bc0 | ||
|
|
e6c0b8d8e5 | ||
|
|
67e78a56a6 | ||
|
|
153d0c36b8 | ||
|
|
18bfe3cb43 | ||
|
|
61ba9b48f9 | ||
|
|
5e02a42ca0 | ||
|
|
89622749e2 | ||
|
|
eced524029 | ||
|
|
c4263b3330 | ||
|
|
68f4a7d4b0 | ||
|
|
7df5028c51 | ||
|
|
4de49c76d0 | ||
|
|
165cbcda89 | ||
|
|
c11bfaf07e | ||
|
|
98babd140e | ||
|
|
575a726361 | ||
|
|
ed2440f8cf | ||
|
|
59592f84fb | ||
|
|
ab690372d2 | ||
|
|
571028f124 | ||
|
|
36391187da | ||
|
|
35f2f5055a | ||
|
|
e2c974f53b | ||
|
|
74172969c1 | ||
|
|
6db392025c | ||
|
|
a61de47bb6 | ||
|
|
bcd5c838e8 | ||
|
|
482b81b0ed | ||
|
|
095c613b69 | ||
|
|
5eed034389 | ||
|
|
7a3bc83a55 | ||
|
|
706f4c6e20 | ||
|
|
f43bb0a9f7 | ||
|
|
64f0bb5460 | ||
|
|
e651330ff1 | ||
|
|
6a6a362a8d | ||
|
|
35046bb7b2 | ||
|
|
a10f2e1258 | ||
|
|
a0d7805484 | ||
|
|
ae77dac66d | ||
|
|
5f1f018a30 | ||
|
|
f2da5fcf2c | ||
|
|
9cce1e060a | ||
|
|
50c8cb7bf0 | ||
|
|
58e5b3959d | ||
|
|
84b6bf9789 | ||
|
|
9efa04da7a | ||
|
|
8ba3f53d2c | ||
|
|
36571edb95 | ||
|
|
3a159beb21 | ||
|
|
6ebe844fc0 | ||
|
|
7359c9bf93 | ||
|
|
02fd35dad0 | ||
|
|
a71b7f0e66 | ||
|
|
f0672082b3 | ||
|
|
2ee54dd4bc | ||
|
|
e852282270 | ||
|
|
80a7ea7649 | ||
|
|
9b988f70de | ||
|
|
27d4e1d990 | ||
|
|
f7132ff139 | ||
|
|
b82100ede8 | ||
|
|
729534401f | ||
|
|
dc85c9fb13 | ||
|
|
2c8b32d2c9 | ||
|
|
011f7465e7 | ||
|
|
4561b2d35d | ||
|
|
5dcaf8ab80 | ||
|
|
ac20fffb40 | ||
|
|
aeef12ef8b | ||
|
|
73f2dba0c3 | ||
|
|
ea56d6774c | ||
|
|
0937c161f4 | ||
|
|
ad31575ddc | ||
|
|
3fc2cdfbab | ||
|
|
ba186a22d0 | ||
|
|
8449bdc5c1 | ||
|
|
686816b8a4 | ||
|
|
6d457e3559 | ||
|
|
91e9891892 | ||
|
|
c8e866e384 | ||
|
|
f5997aaf7c | ||
|
|
9a2066d98a | ||
|
|
6e59f6f413 | ||
|
|
7e8177edb3 | ||
|
|
d3deda62a8 | ||
|
|
f990918e49 | ||
|
|
9ce7b19147 | ||
|
|
786c590dcf | ||
|
|
bbf37ba7cf | ||
|
|
c50556a957 | ||
|
|
4a895f6daf | ||
|
|
7f5af1ccdf | ||
|
|
eac221c2d3 | ||
|
|
c5b98a5e93 | ||
|
|
88c49e7c50 | ||
|
|
3cb5b840ce | ||
|
|
e0deabceb3 | ||
|
|
2e15e5e3c7 | ||
|
|
050e9126d8 | ||
|
|
3b52d375e7 | ||
|
|
a1c6f0a1d2 | ||
|
|
4bd351f167 | ||
|
|
5bed03f37e | ||
|
|
315ee8a64d | ||
|
|
f51622a507 | ||
|
|
ce95e1abcd | ||
|
|
70e480a3e9 | ||
|
|
6ca67ff1ef | ||
|
|
ff63c92c2c | ||
|
|
36ff005d11 | ||
|
|
38ea3312f6 | ||
|
|
8c61026761 | ||
|
|
5d32728f3e | ||
|
|
159ef4cc15 | ||
|
|
8baab4ce8e | ||
|
|
491ad6de17 | ||
|
|
f62076cdc1 | ||
|
|
674650f24d | ||
|
|
9f5bd7bf66 | ||
|
|
fa5a842257 | ||
|
|
a2f1c917bc | ||
|
|
b4bff9f3b2 | ||
|
|
8ce46d3de8 | ||
|
|
2cad731f23 | ||
|
|
1cf08423ad | ||
|
|
b64ac0593e | ||
|
|
f64759e42e | ||
|
|
d0b192dbc8 | ||
|
|
fc90392982 | ||
|
|
180a1a243b | ||
|
|
5246a7824b | ||
|
|
2dffd41c6f | ||
|
|
2f72796ae7 | ||
|
|
364ad021e4 | ||
|
|
a187b54707 | ||
|
|
15c177d8b3 | ||
|
|
773e9bb015 | ||
|
|
dbf2e8c927 | ||
|
|
e794ac5ecb | ||
|
|
f4d64dcb39 | ||
|
|
a1404722ba | ||
|
|
9167d4ac56 | ||
|
|
c3376efa8d | ||
|
|
2ad9c5685e | ||
|
|
0565e614d3 | ||
|
|
1126956d56 | ||
|
|
aec32bbc35 | ||
|
|
424243c064 | ||
|
|
84f293fee2 | ||
|
|
39f51612f5 | ||
|
|
f4155fa7c4 | ||
|
|
c2fdd04681 | ||
|
|
c5da65ba60 | ||
|
|
65165247c0 | ||
|
|
e89ba979cf | ||
|
|
cf605b5e6f | ||
|
|
1984ba3b33 | ||
|
|
43db5a8731 | ||
|
|
7c9f521f65 | ||
|
|
9848bf8246 | ||
|
|
b0d8d4bbdb | ||
|
|
4cd14b58e1 | ||
|
|
2853a23679 | ||
|
|
bd931ebd74 | ||
|
|
e2b5cea7df | ||
|
|
2fb41f19a7 | ||
|
|
0cd36558c5 | ||
|
|
f835c678bf | ||
|
|
44a2666183 | ||
|
|
1b81c276fc | ||
|
|
309bb7eb47 | ||
|
|
44fff3b45c | ||
|
|
7498afcb33 | ||
|
|
9091c074a8 | ||
|
|
50a62f6105 | ||
|
|
ef29e98bdc | ||
|
|
814aa778ea | ||
|
|
2723a23ea7 | ||
|
|
23bc0d7f3d | ||
|
|
573478a630 | ||
|
|
271524e264 | ||
|
|
18446de298 | ||
|
|
a6a901109b | ||
|
|
7effb12bbe | ||
|
|
b625a8f41f | ||
|
|
786cd12636 | ||
|
|
122ecb05c9 | ||
|
|
f07ea3d2cc | ||
|
|
37612eb41a | ||
|
|
24e17182b3 | ||
|
|
7a8a72b1e8 | ||
|
|
926d944c2a | ||
|
|
ddc22578f6 | ||
|
|
8f24d68b53 | ||
|
|
5a97ad33a2 | ||
|
|
954589df1b | ||
|
|
7c9e37a2c6 | ||
|
|
913be315f3 | ||
|
|
830e7c5c45 | ||
|
|
d6671cca75 | ||
|
|
38dbedcd85 | ||
|
|
4e492da1e4 | ||
|
|
5cfacc799d | ||
|
|
31d44b4c46 | ||
|
|
ba2336ac5c | ||
|
|
33ea45301e | ||
|
|
02a315814f | ||
|
|
5fe009d094 | ||
|
|
8082d07e7b | ||
|
|
559c3788ac | ||
|
|
54ba0873da | ||
|
|
28038cc53e | ||
|
|
97c3da3789 | ||
|
|
40a6a4296b | ||
|
|
c5168ad100 | ||
|
|
89e455e9a7 | ||
|
|
b68ff2fd88 | ||
|
|
00abe771bf | ||
|
|
1a2e1474f4 | ||
|
|
d0b87400d1 | ||
|
|
0977c3839a | ||
|
|
cd7bd1b253 | ||
|
|
11b7c72e7d | ||
|
|
ddec6aed59 | ||
|
|
3f8ce55e8b | ||
|
|
43467fc7c5 | ||
|
|
7b9d7e37e4 | ||
|
|
072bc7fc8c | ||
|
|
8d04ce4255 | ||
|
|
b97f4b31fa | ||
|
|
a0c90f9657 | ||
|
|
9b01f375e9 | ||
|
|
0539c99cf8 | ||
|
|
842fa767b8 | ||
|
|
aa427ecaf3 | ||
|
|
5e72da399e | ||
|
|
1c562a0d2d | ||
|
|
f01d69f90b | ||
|
|
c9d40992a1 | ||
|
|
986ea30ef5 | ||
|
|
110e5163e0 | ||
|
|
26999ee978 | ||
|
|
ed2d6d68bb | ||
|
|
f530e7e4b4 | ||
|
|
b428f4f483 | ||
|
|
4a6ac5f8d2 | ||
|
|
5360dfa9a4 | ||
|
|
ca93577cd1 | ||
|
|
e5e536a279 | ||
|
|
1f181f1c0a | ||
|
|
66ba7054f9 | ||
|
|
5ee2f5c9c0 | ||
|
|
a7e3cb8c2c | ||
|
|
a8e9746968 | ||
|
|
91d3d9f910 | ||
|
|
3c41b70932 | ||
|
|
d1d909105f | ||
|
|
831eddfbd4 | ||
|
|
16f197eda8 | ||
|
|
946f35577e | ||
|
|
7856a2aac3 | ||
|
|
617dd777a0 | ||
|
|
4d52fe0334 | ||
|
|
8b2cd6caa8 | ||
|
|
f3f249194b | ||
|
|
4a014ea056 | ||
|
|
494f9eccf3 | ||
|
|
f8a2e41df3 | ||
|
|
f601f0b889 | ||
|
|
67898d8ba7 | ||
|
|
a440a57945 | ||
|
|
276afcd02f | ||
|
|
e876c45581 | ||
|
|
4a77466cae | ||
|
|
f41d46866d | ||
|
|
282d71730b | ||
|
|
465131a836 | ||
|
|
432bd3421d | ||
|
|
64cec89085 | ||
|
|
f502a4049a | ||
|
|
ade8f795b2 | ||
|
|
c022ae2853 | ||
|
|
e35d040cc6 | ||
|
|
b44719aa67 | ||
|
|
03b7aeee75 | ||
|
|
ad696bceb7 | ||
|
|
e03b52b946 | ||
|
|
1ead4e1f4c | ||
|
|
4f5e1bb5ee | ||
|
|
3e38fd749d | ||
|
|
4b093489dd | ||
|
|
1d429cca6b | ||
|
|
6e5f2ad66e | ||
|
|
31a0dcab4d | ||
|
|
8a71a98119 | ||
|
|
ab0c396705 | ||
|
|
0788253645 | ||
|
|
3b4bc60041 | ||
|
|
0bf0794956 | ||
|
|
4126d6807f | ||
|
|
4fb185ad70 | ||
|
|
8559fb3eaa | ||
|
|
36002f6d76 | ||
|
|
fa1ff8f566 | ||
|
|
0e7ee62872 | ||
|
|
bf99ab262f | ||
|
|
f372a924b5 | ||
|
|
854a81056b | ||
|
|
3ac096619b | ||
|
|
fea4ae5939 | ||
|
|
4bd9f41f9e | ||
|
|
77b9cc18cc | ||
|
|
35fe447aae | ||
|
|
7da5e48d89 | ||
|
|
88d6340b37 | ||
|
|
588094339a | ||
|
|
18b9052c57 | ||
|
|
9f450c877d | ||
|
|
de46ba01e3 | ||
|
|
c47f8c8fa8 | ||
|
|
c73548ccbd | ||
|
|
b40db8a89b | ||
|
|
aa5024adae | ||
|
|
c19737b387 | ||
|
|
92c831094d | ||
|
|
bb337a1cd8 | ||
|
|
6ca50e537e | ||
|
|
3e84bb3a6e | ||
|
|
2a8b00f928 | ||
|
|
3e5c054243 | ||
|
|
fab68c1c5d | ||
|
|
ee72d0de75 | ||
|
|
09dff6ab05 | ||
|
|
7622dd35c5 | ||
|
|
c64af5671a | ||
|
|
313753483a | ||
|
|
502a00dba1 | ||
|
|
fa8ae283eb | ||
|
|
1d8fb46580 | ||
|
|
3b7fd88ef0 | ||
|
|
def12eb7d5 | ||
|
|
ddae8f0b6d | ||
|
|
2e882b138a | ||
|
|
c1ff276828 | ||
|
|
d248fa9ea0 | ||
|
|
b0bb33cccf | ||
|
|
fa7ff50482 | ||
|
|
8892bd659c | ||
|
|
ca2016d041 | ||
|
|
f4f78af477 | ||
|
|
d658103530 | ||
|
|
32d4d33e3e | ||
|
|
9144983794 | ||
|
|
a80895074b | ||
|
|
48b5eddd79 | ||
|
|
a21a1cad1f | ||
|
|
e46c4d06c3 | ||
|
|
92b3fb1e5e | ||
|
|
a41cf2140c | ||
|
|
037996711e | ||
|
|
8f9cf862fe | ||
|
|
0266f73965 | ||
|
|
01c64013c2 | ||
|
|
fc04258231 | ||
|
|
010d835d2c | ||
|
|
fcec34f4e7 | ||
|
|
1162820af9 | ||
|
|
9511d46a83 | ||
|
|
145f551cd3 | ||
|
|
7c584df3e8 | ||
|
|
46415c3439 | ||
|
|
c512e49639 | ||
|
|
0cd4a4faac | ||
|
|
e0abf63d87 | ||
|
|
e1715e2c00 | ||
|
|
e6543bbde6 | ||
|
|
96bcde4e35 | ||
|
|
285ba42316 | ||
|
|
aaeb1081c7 | ||
|
|
8af9fe2e27 | ||
|
|
6e1f842351 | ||
|
|
b90966fd1c | ||
|
|
eb93fb6ab5 | ||
|
|
4c4331193e | ||
|
|
cee3bfc031 | ||
|
|
7f0434523f | ||
|
|
1f46d61c1b | ||
|
|
7285773737 | ||
|
|
3ebe9f4196 | ||
|
|
58059d1f0a | ||
|
|
3000a48907 | ||
|
|
c02f153c2a | ||
|
|
feba18abd4 | ||
|
|
41576e41ca | ||
|
|
8ab44c98b2 | ||
|
|
e7ce9b4751 | ||
|
|
db78839e86 | ||
|
|
0aed37a2e5 | ||
|
|
19ed4a86c6 | ||
|
|
71840ee63c | ||
|
|
cde1e1ecb8 | ||
|
|
3fe0325eab | ||
|
|
5dd1ed9aac | ||
|
|
3867576137 | ||
|
|
e2371c0244 | ||
|
|
bfe40d6a1b | ||
|
|
927b3165ab | ||
|
|
5b6f5e8c4c | ||
|
|
c5bf7f405c | ||
|
|
bb3954c235 | ||
|
|
1669477d87 | ||
|
|
9ca55b76b0 | ||
|
|
243515a323 | ||
|
|
feab5057bd | ||
|
|
f10214a9dd | ||
|
|
e5d0c2ae7b | ||
|
|
62b65744e5 | ||
|
|
74d52f535a | ||
|
|
a410f96802 | ||
|
|
6d9efbab7a | ||
|
|
0afcc88763 | ||
|
|
8afab3c3f6 | ||
|
|
872b7f5110 | ||
|
|
9a1956c187 | ||
|
|
1ee644aab1 | ||
|
|
c2fa3d8f04 | ||
|
|
d7ab867af3 | ||
|
|
500f3485e0 | ||
|
|
97412e5e12 | ||
|
|
03cf7ca698 | ||
|
|
cc6b519d98 | ||
|
|
4b36e06cfe | ||
|
|
3f578ad80a | ||
|
|
7cd2f78e3a | ||
|
|
d6437b2db0 | ||
|
|
e938d8d0f4 | ||
|
|
3582e2a3ae | ||
|
|
3c31f55e87 | ||
|
|
9526a94ffc | ||
|
|
3a97c74074 | ||
|
|
9ea88438f9 | ||
|
|
d5047b708f | ||
|
|
fa3d8341a9 | ||
|
|
b91d0a6a5a | ||
|
|
04a2d3c9ba | ||
|
|
75aefff539 | ||
|
|
18fee2e650 | ||
|
|
ee5a3ce4a9 | ||
|
|
dee2a8ca29 | ||
|
|
e5a7bb89e2 | ||
|
|
c02af77655 | ||
|
|
d3ff627134 | ||
|
|
e73eba5b28 | ||
|
|
96bbe07e22 | ||
|
|
136a41bf7b | ||
|
|
0e0f5f06c2 | ||
|
|
4101d36bfb | ||
|
|
5c66bc860e | ||
|
|
91a09d97b1 | ||
|
|
ded9d6b55d | ||
|
|
4032304f01 | ||
|
|
a5caa5055e | ||
|
|
3f159934e4 | ||
|
|
436790cfd8 | ||
|
|
a012fb282f | ||
|
|
68fec606f2 | ||
|
|
03a624f788 | ||
|
|
922f16812c | ||
|
|
9ee7440dfd | ||
|
|
2d26c46c1c | ||
|
|
99974e4099 | ||
|
|
a04e6c220e | ||
|
|
f926118d1d | ||
|
|
c4c0b44471 | ||
|
|
463f8e938d | ||
|
|
e3522d221a | ||
|
|
c6182b263d | ||
|
|
8ea729e98f | ||
|
|
2e3d20aa5d | ||
|
|
5d461ac48d | ||
|
|
2b09f81f60 | ||
|
|
188aac111b | ||
|
|
6ef7aab959 | ||
|
|
258fc405db | ||
|
|
2555ffc0d4 | ||
|
|
0d86bab0dc | ||
|
|
855bb568b9 | ||
|
|
da90425289 | ||
|
|
77352f53f9 | ||
|
|
10dca7f305 | ||
|
|
9d58f29f5e | ||
|
|
d42c56357c | ||
|
|
cce2dc91af | ||
|
|
632d791c48 | ||
|
|
5881f4ef9b | ||
|
|
4203c953eb | ||
|
|
e9f0a8cddc | ||
|
|
2b06101502 | ||
|
|
4e952e7cb5 | ||
|
|
fc1f706540 | ||
|
|
1038500e71 | ||
|
|
039d625031 | ||
|
|
3281523961 | ||
|
|
c9aa12d936 | ||
|
|
2cab6ed369 | ||
|
|
85d5add803 | ||
|
|
5df9eab4a9 | ||
|
|
42e860db2e | ||
|
|
85d057c427 | ||
|
|
2877e797a3 | ||
|
|
9c89d6dbd9 | ||
|
|
bfa7763f15 | ||
|
|
ad2592a253 | ||
|
|
9ed1c21159 | ||
|
|
4f3b730e90 | ||
|
|
8980ff6366 | ||
|
|
1ce3fe6e73 | ||
|
|
9ae3bade02 | ||
|
|
01c1243fe4 | ||
|
|
ab3639f7eb | ||
|
|
c26517a73a | ||
|
|
a237948991 | ||
|
|
19015fe40e | ||
|
|
9b0063dfca | ||
|
|
0562942972 | ||
|
|
007501aa9c | ||
|
|
a1a4847e09 | ||
|
|
558996e96d | ||
|
|
0041d82553 | ||
|
|
31ce458fe1 | ||
|
|
2e7fc13fe3 | ||
|
|
a798d0465f | ||
|
|
0051710ba1 | ||
|
|
1cec24074f | ||
|
|
09fd60785d | ||
|
|
b9d616a0b7 | ||
|
|
fb963b9242 | ||
|
|
e493ef1cdb | ||
|
|
98e860a8a8 | ||
|
|
bcec77c946 | ||
|
|
482a52d4e3 | ||
|
|
377a7e4308 | ||
|
|
be646418bf | ||
|
|
16df760ac2 | ||
|
|
7cb841a4cd | ||
|
|
43acadf2e3 | ||
|
|
5de3af52ab | ||
|
|
bfa50913e1 | ||
|
|
74460e6545 | ||
|
|
ad2b4d8dfd | ||
|
|
6f6fd0c5be | ||
|
|
28bf0f7a2c | ||
|
|
3c8df025c1 | ||
|
|
ba2ef79d2a | ||
|
|
709049ab7c | ||
|
|
db513593b4 | ||
|
|
198ea60677 | ||
|
|
4c182928e1 | ||
|
|
2ee082652a | ||
|
|
eac0d97738 | ||
|
|
94779bb2c9 | ||
|
|
aa5e1d79cc | ||
|
|
c378f676fd | ||
|
|
d3ef8ff658 | ||
|
|
cb5d5d00f1 | ||
|
|
6500d9a9d9 | ||
|
|
1575832766 | ||
|
|
087be3e685 | ||
|
|
b9b732134d | ||
|
|
27bba26856 | ||
|
|
b08f83b415 | ||
|
|
e8668614a7 | ||
|
|
802571176e | ||
|
|
94228574d4 | ||
|
|
49783d511c | ||
|
|
6389ffd751 | ||
|
|
e6c1a79067 | ||
|
|
acad93dd7f | ||
|
|
03b43d3c84 | ||
|
|
21cf6edae6 | ||
|
|
be0de442a2 | ||
|
|
8dae3562e9 | ||
|
|
b4891715c0 | ||
|
|
23eb48132a | ||
|
|
0ea2091b2d | ||
|
|
2debdda2b3 | ||
|
|
4bd9336be1 | ||
|
|
38dd45a51c | ||
|
|
af3f25eb4d | ||
|
|
c8b916fdff | ||
|
|
619f36b82a | ||
|
|
4a519916e5 | ||
|
|
37c1c4e8ae | ||
|
|
f46cdd0757 | ||
|
|
6093cd8fe8 | ||
|
|
e2fdddaa1f | ||
|
|
3c3ec88bba | ||
|
|
8dbefcc589 | ||
|
|
4e32b6fbe1 | ||
|
|
a56a2268f0 | ||
|
|
e6f69f7dce | ||
|
|
710336208f | ||
|
|
47b37c996d | ||
|
|
46ecafa73b | ||
|
|
d2fa827fad | ||
|
|
eb31e39f9e | ||
|
|
ccaef6f14b | ||
|
|
fd2f7884c8 | ||
|
|
37b67a8c76 | ||
|
|
897bca6ca2 | ||
|
|
ec1ff4b606 | ||
|
|
fd9cb159ca | ||
|
|
829c0ec22f | ||
|
|
3bf7017f37 | ||
|
|
f9293f92e5 | ||
|
|
277016d104 | ||
|
|
64028270dd | ||
|
|
9d9a81aca4 | ||
|
|
ba72b3b09b | ||
|
|
8a3f8a499e | ||
|
|
08bc6d816a | ||
|
|
2a26d39867 | ||
|
|
613b50a4c6 | ||
|
|
4bb0cdf298 | ||
|
|
e1b5c72e14 | ||
|
|
651b6db5cc | ||
|
|
1300a2bfbb | ||
|
|
6c38ad7179 | ||
|
|
5e9763e3a1 | ||
|
|
432c1d65e1 | ||
|
|
bbd449f9f4 | ||
|
|
781a067772 | ||
|
|
fc28d15c07 | ||
|
|
6a79993019 | ||
|
|
5b1b7acc62 | ||
|
|
3f2dea5b6b | ||
|
|
5928fb9735 | ||
|
|
f69b58e797 | ||
|
|
db2ab2f07d | ||
|
|
b42c1cfeb3 | ||
|
|
3d29596e6e | ||
|
|
e4b0429c0e | ||
|
|
91f46cc8f4 | ||
|
|
0584c39a70 | ||
|
|
c6e5280ae8 | ||
|
|
2bc514357d | ||
|
|
ac16b9cfad | ||
|
|
3e03b2ea29 | ||
|
|
37632d84c8 | ||
|
|
42da986ed3 | ||
|
|
ae1d21f08e | ||
|
|
e6ba36d1cf | ||
|
|
de9def13b3 | ||
|
|
99c10cb422 | ||
|
|
edeaf8065e | ||
|
|
f0c5ed8a30 | ||
|
|
0a36934d55 | ||
|
|
25bb2ae492 | ||
|
|
fe46b05bfb | ||
|
|
e271f2cadb | ||
|
|
4ffac57990 | ||
|
|
8b01798bd6 | ||
|
|
740bf8ae70 | ||
|
|
51f9e52538 | ||
|
|
2c1304c3bf | ||
|
|
ba11a5d68f | ||
|
|
a582cec412 | ||
|
|
b2387c3027 | ||
|
|
b350d2211c | ||
|
|
11f46a0d11 | ||
|
|
8769dbb3f7 | ||
|
|
222cf5cb67 | ||
|
|
17147ade05 | ||
|
|
019a7cc02d | ||
|
|
7e370909da | ||
|
|
61cfe56774 | ||
|
|
5ae434d90d | ||
|
|
ecb557dff2 | ||
|
|
c4c759c951 | ||
|
|
8447c77d95 | ||
|
|
b3037c73d1 | ||
|
|
e8b09f3d8a | ||
|
|
be82347b2a | ||
|
|
7ec7fb5d98 | ||
|
|
12da7c2773 | ||
|
|
718f3bb4bc | ||
|
|
1ed1a4e25a | ||
|
|
56bdaaf2f2 | ||
|
|
a2a60a4aa2 | ||
|
|
2207828333 | ||
|
|
3eaa4fb22d | ||
|
|
0fdbbeecf5 | ||
|
|
197c985332 | ||
|
|
fc824dc540 | ||
|
|
1bf3200fc1 | ||
|
|
1151a3b20f | ||
|
|
e5d4d5108d | ||
|
|
bce8207293 | ||
|
|
e462d7e894 | ||
|
|
588e056699 | ||
|
|
d8f46abd77 | ||
|
|
3a73f6baaa | ||
|
|
de2d3ff204 | ||
|
|
413c50f503 | ||
|
|
16ec8edd58 | ||
|
|
6fa6c6517c | ||
|
|
875657eb45 | ||
|
|
54820501f3 | ||
|
|
ca24cde34d | ||
|
|
5eb399276d | ||
|
|
aab9e5de01 | ||
|
|
b8775f48f7 | ||
|
|
c22670db77 | ||
|
|
30a370644d | ||
|
|
51cd6cc9e6 | ||
|
|
bd151bf42c | ||
|
|
06e034519b | ||
|
|
98c27c8bd4 | ||
|
|
9fce52bf5f | ||
|
|
33893809ed | ||
|
|
bf0a3ef57e | ||
|
|
0796b3d088 | ||
|
|
80ba22aba2 | ||
|
|
b93db38a70 | ||
|
|
6860714572 | ||
|
|
e4d365a1ab | ||
|
|
6c017ab936 | ||
|
|
73e2d1dbe4 | ||
|
|
1265ed47aa | ||
|
|
b24a25b8b9 | ||
|
|
f8b6364694 | ||
|
|
0040181489 | ||
|
|
f1a39b3e4d | ||
|
|
f3bf750bf3 | ||
|
|
bfb071f24f | ||
|
|
775c4d335e | ||
|
|
3930c6cb04 | ||
|
|
0ebfa4174b | ||
|
|
c27aca4977 | ||
|
|
76adf57d1d | ||
|
|
7279b05ee4 | ||
|
|
8862bcda29 | ||
|
|
64d596ad26 | ||
|
|
0cd55e1f1b | ||
|
|
8419ac62be | ||
|
|
22e35c385d | ||
|
|
92a3976837 | ||
|
|
9b560e8303 | ||
|
|
0325273a68 | ||
|
|
5262c2d195 | ||
|
|
3279c44197 | ||
|
|
39ae3ccfc6 | ||
|
|
9d3a39905b | ||
|
|
9b2960a2ff | ||
|
|
3f81241e20 | ||
|
|
3b23cb8bff | ||
|
|
9696e099eb | ||
|
|
9a688e8202 | ||
|
|
88666ee647 | ||
|
|
0b706bb1de | ||
|
|
5b4eea4e09 | ||
|
|
b206e0cea0 | ||
|
|
7bfb1cd79c | ||
|
|
82cb30373c | ||
|
|
b9ea639f9d | ||
|
|
9832921d0d | ||
|
|
ce2e1f7058 | ||
|
|
d072737463 | ||
|
|
3abaee07e8 | ||
|
|
27733c364f | ||
|
|
20ad51994a | ||
|
|
aae59b93e6 | ||
|
|
d74186d7ad | ||
|
|
f49b37d06a | ||
|
|
6e57af0f1c | ||
|
|
8e39de4c75 | ||
|
|
471e6a9e94 | ||
|
|
f7f0cf1c61 | ||
|
|
473ec02aa2 | ||
|
|
22f2b1f9e9 | ||
|
|
73c77069f6 | ||
|
|
b45e72c227 | ||
|
|
5c36d20b48 | ||
|
|
24da65701c | ||
|
|
796e60c284 | ||
|
|
5aa6d0bc6a | ||
|
|
3b47b1b523 | ||
|
|
fcb961d0ea | ||
|
|
c6e1a3d59d | ||
|
|
2984c3bdfb | ||
|
|
9b8d6e7607 | ||
|
|
260e0fc8ac | ||
|
|
6c305121f4 | ||
|
|
b7cca93ceb | ||
|
|
ae98e3a593 | ||
|
|
e4ecf42a8c | ||
|
|
c47c598c0b | ||
|
|
c844d80217 | ||
|
|
bb04097912 | ||
|
|
47677c8415 | ||
|
|
1707ecd8b6 | ||
|
|
b4cc35b2da | ||
|
|
8492c22b55 | ||
|
|
e0dc62f7b1 | ||
|
|
d6cf0c7be2 | ||
|
|
09291a9cf5 | ||
|
|
9ac837068f | ||
|
|
29d5309430 | ||
|
|
7fe11a6026 | ||
|
|
21f915ffd2 | ||
|
|
af3659a90e | ||
|
|
3d65ff06e9 | ||
|
|
e0954f330a | ||
|
|
4367299885 | ||
|
|
c59d0a924b | ||
|
|
8a927e5120 | ||
|
|
eb40bc940a | ||
|
|
218a3b478d | ||
|
|
dcc0f9fbf6 | ||
|
|
ce616caf99 | ||
|
|
e288bf6ae3 | ||
|
|
0285eab20c | ||
|
|
baacd4ca8c | ||
|
|
29bd206f85 | ||
|
|
5d04a2adc3 | ||
|
|
df6b106b26 | ||
|
|
e456ca1b20 | ||
|
|
744ff5ca9a | ||
|
|
0c0f4cfdbd | ||
|
|
8436c91279 | ||
|
|
c52c62ebc0 | ||
|
|
1e303652cc | ||
|
|
361941e5d4 | ||
|
|
dc6c7022fc | ||
|
|
60585cce94 | ||
|
|
3a6a603778 | ||
|
|
28a8c1cd1e | ||
|
|
b9be840291 | ||
|
|
81b6320595 | ||
|
|
189fa14c29 | ||
|
|
ee254efcf3 | ||
|
|
c9e5df4aa0 | ||
|
|
eec8b37c49 | ||
|
|
14746004b5 | ||
|
|
be3cb55f7d | ||
|
|
0aa7368e5d | ||
|
|
24d5457518 | ||
|
|
badff8cae5 | ||
|
|
6dc6c80cc5 | ||
|
|
e84e161034 | ||
|
|
5a534e4010 | ||
|
|
34d7eca8f3 | ||
|
|
472c07c0a8 | ||
|
|
c944a273d0 | ||
|
|
501f01cdd5 | ||
|
|
e93a12d1fa | ||
|
|
8c83307371 | ||
|
|
7ede4b783d | ||
|
|
50afd46c79 | ||
|
|
f93a7c0ffe | ||
|
|
54fd7a9872 | ||
|
|
a189fab5d4 | ||
|
|
f659c47a61 | ||
|
|
b0d5eb906f | ||
|
|
adcf635f59 | ||
|
|
ee3c1192bc | ||
|
|
e94b80b9e5 | ||
|
|
cef2df4b0b | ||
|
|
c525b633bd | ||
|
|
d429e69d35 | ||
|
|
26e5cfc4fa | ||
|
|
2bfe31e242 | ||
|
|
c577b95e5e | ||
|
|
00803950bf | ||
|
|
bff5b6e8e2 | ||
|
|
cbe24e2531 | ||
|
|
1ada110fed | ||
|
|
19b2eded16 | ||
|
|
3fd6b62254 | ||
|
|
2ad80c8fcf | ||
|
|
c5a90f03d9 | ||
|
|
25460bd8b7 | ||
|
|
5ee16a9db1 | ||
|
|
61669e5cbf | ||
|
|
61fba2c32c | ||
|
|
e870fe2048 | ||
|
|
fcd805255c | ||
|
|
83b940605e | ||
|
|
a3c0324dc6 | ||
|
|
780da23c70 | ||
|
|
b464a7e106 | ||
|
|
ba5f9767f3 | ||
|
|
60a8dc592a | ||
|
|
50f7c1edfb | ||
|
|
9c06e33e78 | ||
|
|
469d11ffcb | ||
|
|
86c563cd29 | ||
|
|
c13816dce4 | ||
|
|
7f3d85c0c5 | ||
|
|
65f7545ba5 | ||
|
|
c026879237 | ||
|
|
d9b4e531b0 | ||
|
|
062e93a5d2 | ||
|
|
96c652ef08 | ||
|
|
017fbb3793 | ||
|
|
6bce017823 | ||
|
|
f9b7372883 | ||
|
|
6755448e86 | ||
|
|
9a650bd12a | ||
|
|
7dabb3ce9a | ||
|
|
8c33ebfd52 | ||
|
|
70742e0432 | ||
|
|
fb984abf12 | ||
|
|
7351c722be | ||
|
|
d1f7b0898a | ||
|
|
a61ab7c033 | ||
|
|
424cbdd47b | ||
|
|
f58b122850 | ||
|
|
f676406fb2 | ||
|
|
f77d968da9 | ||
|
|
3cce4de454 | ||
|
|
84fe974606 | ||
|
|
e3bc5f45f5 | ||
|
|
b1129e4d28 | ||
|
|
15836ac5df | ||
|
|
1093b41d70 | ||
|
|
030b1fb339 | ||
|
|
7a3e36d434 | ||
|
|
595ddc316e | ||
|
|
e059524f6e | ||
|
|
ab7536d220 | ||
|
|
0b72e925d5 | ||
|
|
bb223eedd5 | ||
|
|
8fc0763391 | ||
|
|
e395178b2b | ||
|
|
c6756ea52a | ||
|
|
4f790eb134 | ||
|
|
50ca01f8d0 | ||
|
|
3b37081818 | ||
|
|
a0e0df32af | ||
|
|
fc94e9b6d4 | ||
|
|
69c43bb142 | ||
|
|
2abff92b7b | ||
|
|
a0558a8287 | ||
|
|
b404d2d014 | ||
|
|
bca63dead7 | ||
|
|
5644c4e175 | ||
|
|
790ff16701 | ||
|
|
a19c3f5da6 | ||
|
|
58e40c597d | ||
|
|
7018f78510 | ||
|
|
4eae1d4bcf | ||
|
|
a618f95369 | ||
|
|
fef081c77b | ||
|
|
6406ae1a88 | ||
|
|
cc8afed196 | ||
|
|
2753bc9f8e | ||
|
|
1c420b436d | ||
|
|
19d663d052 | ||
|
|
494cb39984 | ||
|
|
29ca7a4bd9 | ||
|
|
af929fcf0d | ||
|
|
9be4fcf7d2 | ||
|
|
c1bbaf6c02 | ||
|
|
4cf4dc9a3d | ||
|
|
44dde72950 | ||
|
|
048d8c417d | ||
|
|
42afb0199f | ||
|
|
e68583a6e2 | ||
|
|
48044f3847 | ||
|
|
93e6ee11ab | ||
|
|
dd9678d97c | ||
|
|
49c78214f5 | ||
|
|
3ee4cbd992 | ||
|
|
d77877dc20 | ||
|
|
a84349f969 | ||
|
|
b89b000f05 | ||
|
|
0e97a178e3 | ||
|
|
767c30f2ee | ||
|
|
fe3d7f3fa9 | ||
|
|
9856863b03 | ||
|
|
231d3387e6 | ||
|
|
d67db02eea | ||
|
|
6508aca804 | ||
|
|
30aff46e40 | ||
|
|
da0b6580e5 | ||
|
|
453a361017 | ||
|
|
5a701c418f | ||
|
|
abc559388e | ||
|
|
98f0735784 | ||
|
|
ea0edf75f7 | ||
|
|
137f5c96d3 | ||
|
|
f859db9054 | ||
|
|
3b3f12fb97 | ||
|
|
a952f258be | ||
|
|
ef30662c04 | ||
|
|
311c5fec66 | ||
|
|
80075ee2cf | ||
|
|
77db00cef1 | ||
|
|
29037c8543 | ||
|
|
4c9baa60ec | ||
|
|
cb2d5efa4e | ||
|
|
71ab30432b | ||
|
|
96103269c7 | ||
|
|
98e36ffd0e | ||
|
|
a4eb2f40bb | ||
|
|
ccb0a306c8 | ||
|
|
93c17104f1 | ||
|
|
9ec3f79198 | ||
|
|
d18c69eb65 | ||
|
|
bac0da3fe9 | ||
|
|
0a4a205fbe | ||
|
|
6726b93cb4 | ||
|
|
fad458d8c5 | ||
|
|
658e282929 | ||
|
|
01a234aafa | ||
|
|
d31a498457 | ||
|
|
faa602d73a | ||
|
|
210a8eee7f | ||
|
|
ab158ceae0 | ||
|
|
c286617959 | ||
|
|
aa55a2ffa0 | ||
|
|
eec95438de | ||
|
|
53ac1d1808 | ||
|
|
7164aeb65b | ||
|
|
4f1ce3c39a | ||
|
|
0299aef79d | ||
|
|
6bbc2b8238 | ||
|
|
51baaf6667 | ||
|
|
cd3a88eb0d | ||
|
|
9be30a892f | ||
|
|
8b481fdef2 | ||
|
|
f35bbf0173 | ||
|
|
6113541b5f | ||
|
|
4ab85cb569 | ||
|
|
30bff44cf9 | ||
|
|
b64cf2e51c | ||
|
|
9c8027d03c | ||
|
|
a0ca53554f | ||
|
|
727ed6f94e | ||
|
|
b98289c660 | ||
|
|
e4bf321e65 | ||
|
|
85dbaaa5ff | ||
|
|
bdbae36f5e | ||
|
|
1e67eb2ca6 | ||
|
|
130ea1853f | ||
|
|
33eb055f24 | ||
|
|
0b6e028ade | ||
|
|
86be392f44 | ||
|
|
278c494eb3 | ||
|
|
3609ab8003 | ||
|
|
41aa36e6b4 | ||
|
|
f699c6fbe6 | ||
|
|
2cacd89408 | ||
|
|
1c403b7a63 | ||
|
|
b73a01abd4 | ||
|
|
104dcad7dd | ||
|
|
041747391c | ||
|
|
2b31b8d9d8 | ||
|
|
2d09b826d1 | ||
|
|
37203d193a | ||
|
|
15192b976e | ||
|
|
89a28b1ae5 | ||
|
|
5ba75a32f7 | ||
|
|
1a0a15a671 | ||
|
|
081706435d | ||
|
|
4ef9a60713 | ||
|
|
f8b8f17c4b | ||
|
|
b5b584d616 | ||
|
|
322dab0b58 | ||
|
|
2ec33e8e41 | ||
|
|
9358c41aad | ||
|
|
fa21a0ee17 | ||
|
|
569c9044e4 | ||
|
|
0504c8260e | ||
|
|
a7208cc07b | ||
|
|
69ad6c3993 | ||
|
|
e918170dc3 | ||
|
|
8fe89f2182 | ||
|
|
c1273590f3 | ||
|
|
bd8fabc70b | ||
|
|
945c0793b9 | ||
|
|
2a078dd713 | ||
|
|
50bfa7e86c | ||
|
|
f965f2064e | ||
|
|
82f231d7b1 | ||
|
|
fea43b7997 | ||
|
|
df6423b2b8 | ||
|
|
0a26b57789 | ||
|
|
86eaa5787b | ||
|
|
5b904c08c8 | ||
|
|
faf626e5a6 | ||
|
|
71800ba28c | ||
|
|
8997b84f24 | ||
|
|
ee4679f0f7 | ||
|
|
8c97de47a3 | ||
|
|
4296005408 | ||
|
|
22b96e0679 | ||
|
|
29c176b521 | ||
|
|
6ab7a2855b | ||
|
|
3c7a9933b9 | ||
|
|
6b7f71f973 | ||
|
|
e526bfd44c | ||
|
|
6b5c792aad | ||
|
|
ed1eaf6549 | ||
|
|
0bdc59ac41 | ||
|
|
0a5173f258 | ||
|
|
a68c535eb8 | ||
|
|
11a8fb31a4 | ||
|
|
bb52c1311a | ||
|
|
fa103b7ba8 | ||
|
|
e16f1248da | ||
|
|
41322984a6 | ||
|
|
0fe50e099c | ||
|
|
23bfce81a4 | ||
|
|
122d4d3503 | ||
|
|
88c5395349 | ||
|
|
d01eabd340 | ||
|
|
d7a98fe392 | ||
|
|
9457af27f6 | ||
|
|
cc5914a7dc | ||
|
|
1e7d001cd3 | ||
|
|
6e73a2b01c | ||
|
|
8274ad6394 | ||
|
|
df8f8415bf | ||
|
|
e902a0bd59 | ||
|
|
81397ffbf4 | ||
|
|
96cf7053bc | ||
|
|
b25a7ef505 | ||
|
|
99b68eedae | ||
|
|
aa1538ea09 | ||
|
|
1941097fed | ||
|
|
b633be382e | ||
|
|
9860f4befc | ||
|
|
349f7ee27a | ||
|
|
17c65f1a0c | ||
|
|
1fb03c82fe | ||
|
|
f00c742ebc | ||
|
|
9e6467c684 | ||
|
|
c0e070934a | ||
|
|
5f9baed93e | ||
|
|
2bcfb257ea | ||
|
|
87a2060282 | ||
|
|
09bfb8ad2a | ||
|
|
024ad5311f | ||
|
|
71c491db62 | ||
|
|
0ae3cfdcdd | ||
|
|
15ef05791f | ||
|
|
152923306f | ||
|
|
86ab757571 | ||
|
|
a722b71b6c | ||
|
|
6e8f76e93c | ||
|
|
ed15578eed | ||
|
|
f5452fb097 | ||
|
|
2b17090855 | ||
|
|
afab95288e | ||
|
|
59b6285458 | ||
|
|
1709b3e9ba | ||
|
|
3eddc939ce | ||
|
|
e558661a77 | ||
|
|
506a1b6dc7 | ||
|
|
0035580aef | ||
|
|
f59d4c9574 | ||
|
|
ba5e8670a4 | ||
|
|
50d44864b0 | ||
|
|
2dc54ec80b | ||
|
|
f5b8bccb65 | ||
|
|
a2da1eb79d | ||
|
|
40f95a6c06 | ||
|
|
ece117b33f | ||
|
|
66c86a6397 | ||
|
|
a0791ff48f | ||
|
|
1a04705960 | ||
|
|
2dc3f523aa | ||
|
|
ac33b4a428 | ||
|
|
5557487ef2 | ||
|
|
fa4d1addd3 | ||
|
|
77074cce44 | ||
|
|
e447f6d6dd | ||
|
|
22996fd55a | ||
|
|
b3b834cab2 | ||
|
|
b31aa17253 | ||
|
|
f7c9bdcd97 | ||
|
|
fc49190efe | ||
|
|
acc9b4c1d4 | ||
|
|
447b9dc661 | ||
|
|
38dbd66474 | ||
|
|
3015b90a6e | ||
|
|
a1176ce66d | ||
|
|
c0ba077d06 | ||
|
|
586309e851 | ||
|
|
decbd0aa04 | ||
|
|
cdabefa285 | ||
|
|
8b1d3a1265 | ||
|
|
dcb9dec749 | ||
|
|
b9fd456bf4 | ||
|
|
c1371fee27 | ||
|
|
a4b10a8766 | ||
|
|
80b9f7baab | ||
|
|
d26d56e579 | ||
|
|
ddc65d5cff | ||
|
|
22e3ebd89a | ||
|
|
8a54f74589 | ||
|
|
1ebe574ab1 | ||
|
|
0714d74956 | ||
|
|
6cfa1eea7b | ||
|
|
892ee3a707 | ||
|
|
2df33458a1 | ||
|
|
27dc1fb1ef | ||
|
|
88ade4a995 | ||
|
|
7899cd3077 | ||
|
|
3182508238 | ||
|
|
1237e73c1b | ||
|
|
04f2a55500 | ||
|
|
04cf98d0e5 | ||
|
|
1a34ded0a1 | ||
|
|
79de2f6262 | ||
|
|
508d562040 | ||
|
|
12a380a08e | ||
|
|
407891073d | ||
|
|
8df1d67a83 | ||
|
|
6d241c8ce0 | ||
|
|
34662d13c8 | ||
|
|
a79fba39de | ||
|
|
7b191b90df | ||
|
|
472518fcc9 | ||
|
|
4cf671d005 | ||
|
|
ddc2932541 | ||
|
|
ea6056fa59 | ||
|
|
b3c88f7a16 | ||
|
|
95f166ad61 | ||
|
|
1a7c5a294b | ||
|
|
569e5cb0c1 | ||
|
|
f2160391c2 | ||
|
|
62fa62dc3a | ||
|
|
e0aa7754b1 | ||
|
|
89054a50ac | ||
|
|
f833c57348 | ||
|
|
1a63a7ff2e | ||
|
|
a66df9d434 | ||
|
|
c0cd678542 | ||
|
|
b9837cc771 | ||
|
|
9faa625551 | ||
|
|
ebda5f4d31 | ||
|
|
145564719f | ||
|
|
166d88058c | ||
|
|
60d5ab427a | ||
|
|
bcc5bd8e54 | ||
|
|
b9b52c8c06 | ||
|
|
3210ff2e9c | ||
|
|
7cbd8e04c2 | ||
|
|
86c2cb7649 | ||
|
|
84242fc81f | ||
|
|
48e845575a | ||
|
|
39061f9b8c | ||
|
|
41d025bf48 | ||
|
|
581beee0b2 | ||
|
|
9ec10a274e | ||
|
|
c848295b8b | ||
|
|
b472f34d63 | ||
|
|
7a002341f4 | ||
|
|
4969a80c06 | ||
|
|
21fa0887bd | ||
|
|
11f56b06bf | ||
|
|
dfaeb6368b | ||
|
|
f033becebb | ||
|
|
f10171b6bc | ||
|
|
dcc0cb74fe | ||
|
|
389f55c261 | ||
|
|
1716a7f9ca | ||
|
|
2575322360 | ||
|
|
ab19f5654c | ||
|
|
b9b0b096a4 | ||
|
|
b391109469 | ||
|
|
50f8be4a62 | ||
|
|
d35f3df621 | ||
|
|
4121f72593 | ||
|
|
6a1a47aae1 | ||
|
|
4440315cfb | ||
|
|
b2a7d65fc9 | ||
|
|
c8b3f5d512 | ||
|
|
21a2a028a5 | ||
|
|
77e7bad4f1 | ||
|
|
292449369e | ||
|
|
e7be53fe85 | ||
|
|
310b478b75 | ||
|
|
86ab455b54 | ||
|
|
a66f5e7530 | ||
|
|
e300d45831 | ||
|
|
1046920b6c | ||
|
|
db501e8e2d | ||
|
|
22a1fee04b | ||
|
|
7059420be8 | ||
|
|
afe2ac2ae6 | ||
|
|
4fed510631 | ||
|
|
43e516227e | ||
|
|
11babeeed5 | ||
|
|
8122b85567 | ||
|
|
4a18ab6d1b | ||
|
|
714ba20b41 | ||
|
|
93d2112bfe | ||
|
|
e8bfd38865 | ||
|
|
f43e6fddfc | ||
|
|
b2f8875175 | ||
|
|
eb31df7d1d | ||
|
|
2b8a819d3d | ||
|
|
a36b76faf0 | ||
|
|
f9edd3668f | ||
|
|
f5bb7a2513 | ||
|
|
9371737104 | ||
|
|
764e1a01cc | ||
|
|
3d7d82ab2a | ||
|
|
9b571e12a7 | ||
|
|
bc785e9860 | ||
|
|
e2a9da1020 | ||
|
|
9bca5175e5 | ||
|
|
691f4aa6f1 | ||
|
|
c2d21d02ab | ||
|
|
c85eb81ed0 | ||
|
|
23d496d0e8 | ||
|
|
6a4986ee06 | ||
|
|
296d1e2b75 | ||
|
|
2bfa2edd60 | ||
|
|
f8a844fd83 | ||
|
|
8e317bd130 | ||
|
|
af7cfe74f1 | ||
|
|
d5122566ea | ||
|
|
5ae88eb30b | ||
|
|
fb3e71d457 | ||
|
|
3c4d25d6c2 | ||
|
|
467f097071 | ||
|
|
cdbddedbdb | ||
|
|
209a08b291 | ||
|
|
4c809b5de5 | ||
|
|
2386aa2e38 | ||
|
|
4d9ec5d63b | ||
|
|
aa321ca5b8 | ||
|
|
a82c989328 | ||
|
|
edf1a44a79 | ||
|
|
43c630108e | ||
|
|
2f4b3d4ce3 | ||
|
|
b9aaee0009 | ||
|
|
9e5ed112e8 | ||
|
|
2a1bbdb38a | ||
|
|
57f45286d9 | ||
|
|
3903e86d9c | ||
|
|
3095ec01cd | ||
|
|
460f3d2a22 | ||
|
|
5d050d8d60 | ||
|
|
6bd7966e88 | ||
|
|
f3353eea1b | ||
|
|
760cb78280 | ||
|
|
b9ba84979d | ||
|
|
f23cc0cb4e | ||
|
|
8f34ea462d | ||
|
|
e90cc1d72a | ||
|
|
bfc672c580 | ||
|
|
e442920292 | ||
|
|
641ef3725b | ||
|
|
6bc25ee59c | ||
|
|
37a8190dc1 | ||
|
|
b9b6c1ace3 | ||
|
|
e83b8633b1 | ||
|
|
16e31fd36d | ||
|
|
8303e66e80 | ||
|
|
7a1d08faad | ||
|
|
4f8f7f65a9 | ||
|
|
3d414d7f07 | ||
|
|
ed60c90081 | ||
|
|
1d0c8351ec | ||
|
|
5de1b0a012 | ||
|
|
9f673fdb04 | ||
|
|
957c299299 | ||
|
|
d5ddb5eea1 | ||
|
|
1a21fdf4db | ||
|
|
9a08d36443 | ||
|
|
ccd7cf8144 | ||
|
|
c31562dffd | ||
|
|
64b8bd480b | ||
|
|
6db1e0bc35 | ||
|
|
0933038cb4 | ||
|
|
0a3fc2b7ff | ||
|
|
efe7e12c90 | ||
|
|
77f8e4d822 | ||
|
|
b7455b2ccc | ||
|
|
754adef302 | ||
|
|
6c3268ac84 | ||
|
|
3f55d9ad06 | ||
|
|
128e0e3047 | ||
|
|
70de3e4729 | ||
|
|
7107d83357 | ||
|
|
d42799dc62 | ||
|
|
cd02510ccc | ||
|
|
69742e5118 | ||
|
|
c463a50159 | ||
|
|
86430da9ac | ||
|
|
5aa694e232 | ||
|
|
bb296802b0 | ||
|
|
537bf993cd | ||
|
|
b7ef6738f1 | ||
|
|
570aba57b5 | ||
|
|
0ab29bd483 | ||
|
|
519eed91b5 | ||
|
|
dfe2a21b58 | ||
|
|
6bdb5cf7c3 | ||
|
|
0e41e53d70 | ||
|
|
75cb68159d | ||
|
|
0909eb46ca | ||
|
|
40475f864d | ||
|
|
6a9547797d | ||
|
|
1e1fd225e1 | ||
|
|
df729f48f6 | ||
|
|
2b779e5e4a | ||
|
|
f76bdf8932 | ||
|
|
deb1197503 | ||
|
|
e7b97402b5 | ||
|
|
5f92373db2 | ||
|
|
73b290995c | ||
|
|
c19728dc20 | ||
|
|
087ecc8538 | ||
|
|
1e02b57ceb | ||
|
|
b6ad059c60 | ||
|
|
e79d3352f8 | ||
|
|
adf7085adf | ||
|
|
6a29ebbcfb | ||
|
|
a26be2665f | ||
|
|
cb02527f7d | ||
|
|
27f1d999a0 | ||
|
|
cfe4a779f2 | ||
|
|
7a4563d6ef | ||
|
|
e047e5d803 | ||
|
|
e5bdb724c4 | ||
|
|
a479f86952 | ||
|
|
de2e0782d7 | ||
|
|
934eb22d3a | ||
|
|
32d8db588f | ||
|
|
4a1a563daa | ||
|
|
ff6feb7bcd | ||
|
|
4c19d2bd02 | ||
|
|
f868289959 | ||
|
|
dcdc8c6e10 | ||
|
|
f3e1569ec2 | ||
|
|
43c0b67505 | ||
|
|
87650aaf84 | ||
|
|
8b0c530a99 | ||
|
|
1803ae57c5 | ||
|
|
f4cf3a27b3 | ||
|
|
583ac3de96 | ||
|
|
40b4e82802 | ||
|
|
50f2b532e9 | ||
|
|
a92eb3ddce | ||
|
|
9db99f6412 | ||
|
|
ee80d1b963 | ||
|
|
2ef14d322b | ||
|
|
f081b628f0 | ||
|
|
1bb354e96d | ||
|
|
5bdb1bc417 | ||
|
|
bd26775dcb | ||
|
|
1ea3e2ea3a | ||
|
|
a1680a0fa5 | ||
|
|
f8ad575dfa | ||
|
|
22c0b4e4df | ||
|
|
b1c9bb02b2 | ||
|
|
89564accb6 | ||
|
|
d4556045dd | ||
|
|
2e6ecc832e | ||
|
|
53c98baa6d | ||
|
|
c614c5bf13 | ||
|
|
2084ef4bbc | ||
|
|
0990a0dcdd | ||
|
|
022a269e99 | ||
|
|
665b5d05ae | ||
|
|
138957dc4e | ||
|
|
bf515ea265 | ||
|
|
ae638d2643 | ||
|
|
31816f859b | ||
|
|
b339ac565f | ||
|
|
54e6faca7c | ||
|
|
0edd42b9fc | ||
|
|
5438709be3 | ||
|
|
28b14c62ce | ||
|
|
55afed3897 | ||
|
|
eaace937b8 | ||
|
|
a8cbb03218 | ||
|
|
1619fc62e0 | ||
|
|
33e1144c81 | ||
|
|
a2b40942e2 | ||
|
|
03c2a101f3 | ||
|
|
a38661f9cb | ||
|
|
0065c6c082 | ||
|
|
106c01f1a7 | ||
|
|
cdc94a6370 | ||
|
|
c4cdeb0335 | ||
|
|
11662d5fbb | ||
|
|
a9c24c1a08 | ||
|
|
27aa653e9d | ||
|
|
7196614a96 | ||
|
|
86c5042563 | ||
|
|
8a632832f8 | ||
|
|
4cdb7c8e2b | ||
|
|
b096f2296e | ||
|
|
9412f6c161 | ||
|
|
08280a71ea | ||
|
|
bc9e5ea410 | ||
|
|
f2a08072ef | ||
|
|
ffd895e1b2 | ||
|
|
ad092508f8 | ||
|
|
a840932500 | ||
|
|
4aa3b0b637 | ||
|
|
67cc8b4860 | ||
|
|
e95e47b954 | ||
|
|
79c1b68f3c | ||
|
|
7c4e1ccf67 | ||
|
|
c53ba7c07f | ||
|
|
372e7b9590 | ||
|
|
f026aef154 | ||
|
|
a04370b24d | ||
|
|
655d16e76e | ||
|
|
a359cb1730 | ||
|
|
fef0b21b2d | ||
|
|
5b6c4dd76d | ||
|
|
a0bb31aaf6 | ||
|
|
c525678d7e | ||
|
|
9f76afaac8 | ||
|
|
02d0c092b2 | ||
|
|
06b79a2785 | ||
|
|
68a3bdc412 | ||
|
|
5b730f4b07 | ||
|
|
6ff0524260 | ||
|
|
8d4215557a | ||
|
|
d684f7f336 | ||
|
|
411b40a59c | ||
|
|
9aa23980ba | ||
|
|
c39bbb5b85 | ||
|
|
f5fea0be04 | ||
|
|
c49e8ed76c | ||
|
|
f8a847d3db | ||
|
|
211de2b4c8 | ||
|
|
63cb001c1d | ||
|
|
50b17aa357 | ||
|
|
3c3230d28c | ||
|
|
07bd0f180c | ||
|
|
805c90ade7 | ||
|
|
9a55019d65 | ||
|
|
85e2f063ac | ||
|
|
1f3516a474 | ||
|
|
212bbf18f5 | ||
|
|
193eb51d09 | ||
|
|
25283a8ed1 | ||
|
|
08095f5e01 | ||
|
|
ebd71f89e0 | ||
|
|
a7124c935e | ||
|
|
7f067903bf | ||
|
|
60d805e4ce | ||
|
|
c4806b9c4f | ||
|
|
acbe597e32 | ||
|
|
26c101d69a | ||
|
|
4e9ba16101 | ||
|
|
61253c3497 | ||
|
|
96c0a373e3 | ||
|
|
7122a338ee | ||
|
|
c736076308 | ||
|
|
60d05f03a5 | ||
|
|
e8fc433a1a | ||
|
|
11572f94de | ||
|
|
fa2e306d6e | ||
|
|
d4b9767586 | ||
|
|
c6e0f0f8da | ||
|
|
6710a289ff | ||
|
|
7921a6cbf8 | ||
|
|
a32f12c8f3 | ||
|
|
d8131eb5d4 | ||
|
|
c473cb6e77 | ||
|
|
549b0e8db2 | ||
|
|
f2787855fd | ||
|
|
dd0134180c | ||
|
|
65dbfe4ae7 | ||
|
|
2bb05080f4 | ||
|
|
d4a0046e7c | ||
|
|
7defcf3957 | ||
|
|
2cf4c5a26f | ||
|
|
eb6d617175 | ||
|
|
4376a65311 | ||
|
|
12bb305aa6 | ||
|
|
c0c84ede5d | ||
|
|
43335ed3a1 | ||
|
|
6d724cb4cb | ||
|
|
003fc7cdf4 | ||
|
|
76eb76f185 | ||
|
|
546c503914 | ||
|
|
c7c9d4f861 | ||
|
|
bdc112ca98 | ||
|
|
7c4081e6fb | ||
|
|
22341bc996 | ||
|
|
40a29348da | ||
|
|
6c85cac1f5 | ||
|
|
6ba67ea641 | ||
|
|
293d119b36 | ||
|
|
bff0009b83 | ||
|
|
957e93e114 | ||
|
|
81966e4c8c | ||
|
|
c6a34ca007 | ||
|
|
cbf5c43ae7 | ||
|
|
c1d4abbeb0 | ||
|
|
5cc0462c08 | ||
|
|
6a07d25b5c | ||
|
|
8c271f3d2d | ||
|
|
e9df9428cd | ||
|
|
1ec2155cc2 | ||
|
|
c777be5102 | ||
|
|
b34a4ed311 | ||
|
|
4bf0dbb59c | ||
|
|
5ae6b4909c | ||
|
|
ad466a2860 | ||
|
|
923120625c | ||
|
|
6bdc8daa36 | ||
|
|
d352c78f2a | ||
|
|
a788d3fc91 | ||
|
|
75df90d838 | ||
|
|
c92961097f | ||
|
|
78bf0f6898 | ||
|
|
fe78b16789 | ||
|
|
5a9baf730e | ||
|
|
8f8a9e1e49 | ||
|
|
46c005a5d3 | ||
|
|
bc6d1c3a2b | ||
|
|
8ed23291c0 | ||
|
|
14e4834009 | ||
|
|
d5041b8bd0 | ||
|
|
1cf1973e9b | ||
|
|
1d8e353767 | ||
|
|
500c59fee6 | ||
|
|
3fa3153a23 | ||
|
|
9e624563bb | ||
|
|
d2549263e4 | ||
|
|
f77e5e713d | ||
|
|
3bcaf75023 | ||
|
|
3be527cac8 | ||
|
|
fde64885ae | ||
|
|
65b8bc196a | ||
|
|
778c6d68cf | ||
|
|
577a6b7c5a | ||
|
|
77d75984fa | ||
|
|
e21eb2505c | ||
|
|
2e81324e27 | ||
|
|
1b51456718 | ||
|
|
9c302f303a | ||
|
|
b92dd88303 | ||
|
|
0e36757780 | ||
|
|
5a734685d9 | ||
|
|
235d6bce5d | ||
|
|
1cc06397a2 | ||
|
|
7353853624 | ||
|
|
b467ec1072 | ||
|
|
730c576d48 | ||
|
|
da80530cb3 | ||
|
|
2422d96436 | ||
|
|
1176e51b5f | ||
|
|
42b73de184 | ||
|
|
8eafb70327 | ||
|
|
6882e6432b | ||
|
|
e347f50700 | ||
|
|
3402b388a1 | ||
|
|
8f466061c3 | ||
|
|
a3659d864c | ||
|
|
1b98601870 | ||
|
|
2a46122f28 | ||
|
|
5da11ae436 | ||
|
|
fe0280cbf0 | ||
|
|
3f192f927c | ||
|
|
271d2d7078 | ||
|
|
0b92a7fe7c | ||
|
|
446d944888 | ||
|
|
12bde9a514 | ||
|
|
3366ed1af0 | ||
|
|
2b3467a5d0 | ||
|
|
2f49467152 | ||
|
|
b4399402a6 | ||
|
|
b3ed90a9b3 | ||
|
|
6eed898183 | ||
|
|
c67f5da4c1 | ||
|
|
5f38137734 | ||
|
|
748c900dce | ||
|
|
a45ecef20b | ||
|
|
fc0e61b666 | ||
|
|
4599cc9ca2 | ||
|
|
bb00ad5fb0 | ||
|
|
629341894b | ||
|
|
416ca55fa9 | ||
|
|
a3ece528e5 | ||
|
|
b924594c19 | ||
|
|
663754e7ed | ||
|
|
189f4c53b2 | ||
|
|
7af1f21d9b | ||
|
|
d5b6f64033 | ||
|
|
e4e2738c3c | ||
|
|
a7478f58ae | ||
|
|
921deab6ad | ||
|
|
5d9eee8e4b | ||
|
|
322745464c | ||
|
|
1e8ffe5e74 | ||
|
|
8fb0147fb6 | ||
|
|
7fec677d8f | ||
|
|
172f2f3993 | ||
|
|
aa6b1d128a | ||
|
|
66798c75b5 | ||
|
|
2ef6abbfb8 | ||
|
|
326a1a9056 | ||
|
|
341b0b469e | ||
|
|
0e8e472138 | ||
|
|
44eeb6fddc | ||
|
|
8383c021f1 | ||
|
|
7afa416ed5 | ||
|
|
bd5d22d0e9 | ||
|
|
93b57b2baa | ||
|
|
e356c38948 | ||
|
|
d1f7454dc0 | ||
|
|
3bf3237774 | ||
|
|
f0e6673fec | ||
|
|
8ac2e0100e | ||
|
|
f42c865878 | ||
|
|
2aae3de956 | ||
|
|
c61556e885 | ||
|
|
8891698745 | ||
|
|
ec4cc52b7e | ||
|
|
d2c2a51ce6 | ||
|
|
3e3d7566a6 | ||
|
|
5f355bf25e | ||
|
|
1708f7f1b8 | ||
|
|
fb686ec5b6 | ||
|
|
1d86a75a29 | ||
|
|
ee5b20e12e | ||
|
|
c8184e2497 | ||
|
|
4d00249d97 | ||
|
|
4c43daf336 | ||
|
|
e5dcb6e8c2 | ||
|
|
db89364395 | ||
|
|
6bd52ff6f5 | ||
|
|
d8124d37e4 | ||
|
|
8e841be393 | ||
|
|
1b164dbc42 | ||
|
|
5ae4d0b8c9 | ||
|
|
72ca95e97d | ||
|
|
151ef4d583 | ||
|
|
2d0becc8c5 | ||
|
|
a074636773 | ||
|
|
9009e62cc6 | ||
|
|
dca486ca10 | ||
|
|
fa966348ee | ||
|
|
981a64aac4 | ||
|
|
3eba2211ca | ||
|
|
a529afc133 | ||
|
|
2ba9c13165 | ||
|
|
40ba9c76b1 | ||
|
|
958f4d6b86 | ||
|
|
9ea7fa0518 | ||
|
|
7eb899b780 | ||
|
|
4552cb9778 | ||
|
|
51117fa11f | ||
|
|
fd40c7a24a | ||
|
|
c797c06f92 | ||
|
|
5ec96f5abe | ||
|
|
31b4dae26b | ||
|
|
287a73506c | ||
|
|
8de92bb14b | ||
|
|
991fee51c5 | ||
|
|
d1754559ad | ||
|
|
ec4c811a98 | ||
|
|
ac67e7220b | ||
|
|
b87ecc3ae5 | ||
|
|
fc8920a69a | ||
|
|
c4a1caedae | ||
|
|
fed77108e6 | ||
|
|
779f951c2f | ||
|
|
48562f96f5 | ||
|
|
461bd8c572 | ||
|
|
1617ab45db | ||
|
|
216059c2e5 | ||
|
|
60157fffe2 | ||
|
|
6e2f66987c | ||
|
|
75116b3361 | ||
|
|
a5e00ae57c | ||
|
|
f5ffd4dd77 | ||
|
|
226e189c4a | ||
|
|
665f532301 | ||
|
|
db3ca10c91 | ||
|
|
f9ee80d314 | ||
|
|
5814bcfd99 | ||
|
|
993ea317d7 | ||
|
|
e8aa7edbdc | ||
|
|
15f046a344 | ||
|
|
24947ad280 | ||
|
|
4e0c2382ff | ||
|
|
dcf41fc1a7 | ||
|
|
b279ebe97e | ||
|
|
c3d4bfc05e | ||
|
|
46dcd771f1 | ||
|
|
94efdd9f54 | ||
|
|
04882b603c | ||
|
|
92f6402b2a | ||
|
|
e30eb4de12 | ||
|
|
ae2c163441 | ||
|
|
351d5faa9b | ||
|
|
143632adb0 | ||
|
|
7b904cd89b | ||
|
|
7ade21ad9b | ||
|
|
900df8ce16 | ||
|
|
d50454ece6 | ||
|
|
4292bb1c28 | ||
|
|
320c58dbfc | ||
|
|
9d830f4837 | ||
|
|
269ffe385a | ||
|
|
ed1ecde348 | ||
|
|
26077db644 | ||
|
|
6232c3a471 | ||
|
|
1bca364a03 | ||
|
|
89691b19fd | ||
|
|
44e01823a3 | ||
|
|
6741ee61d8 | ||
|
|
a9d1fd7cdf | ||
|
|
75522c771e | ||
|
|
cce899bf69 | ||
|
|
09562bccf6 | ||
|
|
0b23334ed2 | ||
|
|
6cc71e1f13 | ||
|
|
a302dba006 | ||
|
|
65edff3821 | ||
|
|
5946f1cd87 | ||
|
|
5d0deff937 | ||
|
|
40a114a80a | ||
|
|
33caca80e2 | ||
|
|
f698ce7e79 | ||
|
|
538b1a2294 | ||
|
|
fd3289f67e | ||
|
|
d7f2eba310 | ||
|
|
73189872b3 | ||
|
|
cad20f3e0f | ||
|
|
ee0d29f4e7 | ||
|
|
39eee10c57 | ||
|
|
e9a7b3349b | ||
|
|
2cd0bb7312 | ||
|
|
9c36adc4df | ||
|
|
9d05e01907 | ||
|
|
2a38ccbd77 | ||
|
|
22f011bdbf | ||
|
|
f15f5a59de | ||
|
|
8cd3294192 | ||
|
|
adf4a7fb21 | ||
|
|
b17149ab39 | ||
|
|
9a6de19e9d | ||
|
|
822e262a93 | ||
|
|
847e6b03cb | ||
|
|
4b6d9a067b | ||
|
|
9df3774886 | ||
|
|
0ed179d94c | ||
|
|
039141f91c | ||
|
|
3e3f279469 | ||
|
|
0d18e4ea8e | ||
|
|
31636dcbaa | ||
|
|
db3d10f731 | ||
|
|
1af4f75688 | ||
|
|
fc6c859976 | ||
|
|
bf9d69cd1b | ||
|
|
f103492e50 | ||
|
|
35a9852b42 | ||
|
|
ccfd1b5d95 | ||
|
|
ef7dab792d | ||
|
|
4a789991c8 | ||
|
|
6d3c49d866 | ||
|
|
394907fb7a | ||
|
|
ec81bd5715 | ||
|
|
c4593091d6 | ||
|
|
070f4735cd | ||
|
|
c21ba402ad | ||
|
|
88f25d7444 | ||
|
|
d86e897ba6 | ||
|
|
4738dc9da2 | ||
|
|
0f88d86c89 | ||
|
|
f4480c9968 | ||
|
|
267179aac0 | ||
|
|
1e445a75a9 | ||
|
|
a620ff2b6a | ||
|
|
ce5210d35b | ||
|
|
03cce754d4 | ||
|
|
d6d02631ab | ||
|
|
a1d1b9105e | ||
|
|
8ec574017c | ||
|
|
bf0a05798c | ||
|
|
2fa98d7ad6 | ||
|
|
fc23d3f669 | ||
|
|
ebfa4c4b09 | ||
|
|
6726a1d3e9 | ||
|
|
3de75c20c1 | ||
|
|
70dabba32d | ||
|
|
8f1ab66b04 | ||
|
|
9f53b83bdb | ||
|
|
caf6a1ce62 | ||
|
|
ee3b9c3310 | ||
|
|
b3b8e2e0a2 | ||
|
|
a6a1e1fffd | ||
|
|
dd82f4b47d | ||
|
|
1519d5672e | ||
|
|
787d4c4135 | ||
|
|
72afc206d3 | ||
|
|
9518e61eae | ||
|
|
dffc6acc1a | ||
|
|
64ed6ebdad | ||
|
|
73df4077da | ||
|
|
e873e84130 | ||
|
|
ecda0a1073 | ||
|
|
9414af4dca | ||
|
|
4d277a6bd9 | ||
|
|
e1d4817d54 | ||
|
|
0cf8abcc6f | ||
|
|
293ece5cec | ||
|
|
c12f51c7ab | ||
|
|
3b109fbaeb | ||
|
|
fc1db94c80 | ||
|
|
796aeff168 | ||
|
|
c10735ad04 | ||
|
|
a271516c8b | ||
|
|
2047c09d61 | ||
|
|
7708d0584b | ||
|
|
017dfb6606 | ||
|
|
a4f9e7adad | ||
|
|
688dbc6cba | ||
|
|
2032668e3a | ||
|
|
f1e5b95554 | ||
|
|
f03200f8e6 | ||
|
|
1070081217 | ||
|
|
3d15650bd6 | ||
|
|
9abbcd041f | ||
|
|
1ab9c3aee1 | ||
|
|
2b29c24483 | ||
|
|
9c40422b7d | ||
|
|
f92b157117 | ||
|
|
53ce8388f1 | ||
|
|
961135c85d | ||
|
|
cb84f0f913 | ||
|
|
abc4c62fe4 | ||
|
|
323fb47c79 | ||
|
|
0baca38c31 | ||
|
|
ab8cfa2d28 | ||
|
|
836ba7a755 | ||
|
|
91918f2a58 | ||
|
|
feccdec581 | ||
|
|
5f176fa9a6 | ||
|
|
9eda502a9b | ||
|
|
659f41482b | ||
|
|
7a131fc50f | ||
|
|
6c37574857 | ||
|
|
b69d4b6346 | ||
|
|
a7260f004e | ||
|
|
b400463ff3 | ||
|
|
ba38b73a15 | ||
|
|
4013651ae2 | ||
|
|
e0adf93e21 | ||
|
|
3a4ac1373c | ||
|
|
2ea12ea68d | ||
|
|
2c0965c240 | ||
|
|
867fc30ebf | ||
|
|
0fd1bc7f5a | ||
|
|
5698389789 | ||
|
|
af609e35a3 | ||
|
|
0a8938db4e | ||
|
|
5630a7defe | ||
|
|
b44df4bcc3 | ||
|
|
1f3826f3ce | ||
|
|
91c56831d1 | ||
|
|
44979978a1 | ||
|
|
b7b5408fb1 | ||
|
|
657af4f844 | ||
|
|
59d90b3a69 | ||
|
|
e89892c4d5 | ||
|
|
3c170bbe96 | ||
|
|
2a9587d4ff | ||
|
|
69426387dc | ||
|
|
76c9535255 | ||
|
|
97fb7f0235 | ||
|
|
e2d5aebea2 | ||
|
|
e24d66410b | ||
|
|
82a564a1be | ||
|
|
fa585521d0 | ||
|
|
41f05541ed | ||
|
|
4a91c172b2 | ||
|
|
7c8ded1526 | ||
|
|
e92d44eb56 | ||
|
|
70a247446e | ||
|
|
5ade461ea5 | ||
|
|
9df5bf17f4 | ||
|
|
51ed7784d5 | ||
|
|
359e0e205f | ||
|
|
89bffd132a | ||
|
|
9c92f55afd | ||
|
|
745140e9e7 | ||
|
|
863e5f6c78 | ||
|
|
4e6836d00e | ||
|
|
1cdbcf29ce | ||
|
|
c46c112c32 | ||
|
|
d5cf793fad | ||
|
|
bf1f297bed | ||
|
|
1c8b52e1cd | ||
|
|
7c949f9f5a | ||
|
|
11a3011cbd | ||
|
|
6c7f663983 | ||
|
|
57499c721f | ||
|
|
61a8b6fbc6 | ||
|
|
095f2733f7 | ||
|
|
b9af13b533 | ||
|
|
fab52795e3 | ||
|
|
b2d057b7c3 | ||
|
|
d36dcd2766 | ||
|
|
ff7398b21f | ||
|
|
f906cc3067 | ||
|
|
06349e4a9c | ||
|
|
0039572231 | ||
|
|
676cf4fd39 | ||
|
|
91805c9f44 | ||
|
|
fa2f438a89 | ||
|
|
20cc77401c | ||
|
|
56f3afc7f8 | ||
|
|
b3ef2c179a | ||
|
|
aca0346f4e | ||
|
|
88b5368f72 | ||
|
|
ca98529bd2 | ||
|
|
0292f66365 | ||
|
|
6c87e294c4 | ||
|
|
f080b1fb27 | ||
|
|
f2c8e89053 | ||
|
|
479d4bf64d | ||
|
|
d7a6fbc5fe | ||
|
|
3a5091f2d8 | ||
|
|
f552ad6908 | ||
|
|
20abdc6fe2 | ||
|
|
79f193bd48 | ||
|
|
c014b51a85 | ||
|
|
915c839148 | ||
|
|
cdf95ab8b7 | ||
|
|
1783645108 | ||
|
|
31b43542cd | ||
|
|
a94323fc36 | ||
|
|
e749bb3ce3 | ||
|
|
166c72fb31 | ||
|
|
c85c8e60a3 | ||
|
|
75c291e360 | ||
|
|
a885de4eda | ||
|
|
9cb0185ec2 | ||
|
|
abb31c9b01 | ||
|
|
bf1e8a07c1 | ||
|
|
092f919e60 | ||
|
|
b98e605574 | ||
|
|
8bb13e8d2d | ||
|
|
4ce4ced69d | ||
|
|
bbe243fbf6 | ||
|
|
cd0ec54009 | ||
|
|
318273ae17 | ||
|
|
1aafcaff7a | ||
|
|
850a250cea | ||
|
|
f733e2af87 | ||
|
|
b5336c9a4d | ||
|
|
2c7680bd87 | ||
|
|
7c326f49d9 | ||
|
|
c627001fc8 | ||
|
|
cc572450c5 | ||
|
|
c9a0e4d2d5 | ||
|
|
b9668aceff | ||
|
|
a797421641 | ||
|
|
f2cfb75d18 | ||
|
|
9b333e9c44 | ||
|
|
2ffb3a1180 | ||
|
|
691b8d5c38 | ||
|
|
b41e215112 | ||
|
|
ff89eef01a | ||
|
|
2a5486a4da | ||
|
|
f5797428ff | ||
|
|
dc649eae77 | ||
|
|
3daddf3d1a | ||
|
|
f46a6f2d92 | ||
|
|
a0e08bff4f | ||
|
|
4a56509d66 | ||
|
|
a4c20dd045 | ||
|
|
32e6fd1f5b | ||
|
|
03ab1237ed | ||
|
|
96d9fac281 | ||
|
|
e6414787d4 | ||
|
|
4ef985f878 | ||
|
|
3a53260ccc | ||
|
|
ed0f003cb1 | ||
|
|
861def67bf | ||
|
|
e8d6653854 | ||
|
|
5feae5141b | ||
|
|
1a91e5bc82 | ||
|
|
52025b8b6f | ||
|
|
45e6a716d9 | ||
|
|
7e5beb8c7f | ||
|
|
2a922e847b | ||
|
|
74fd8eea20 | ||
|
|
cec31d0e71 | ||
|
|
ef1d90ad41 | ||
|
|
6b6ac94fd0 | ||
|
|
1edeed1cf2 | ||
|
|
4b184905e8 | ||
|
|
ecf1c41f7c | ||
|
|
98ced973a9 | ||
|
|
d9a77eb1c3 | ||
|
|
4325930e21 | ||
|
|
ba0ea71cf7 | ||
|
|
2d4444fec1 | ||
|
|
95de3c1b04 | ||
|
|
d39ae8a91b | ||
|
|
eab8a19ec7 | ||
|
|
b79133c694 | ||
|
|
b1a60b25b4 | ||
|
|
aeb6cddc2f | ||
|
|
f7dea9421f | ||
|
|
58cca0a77a | ||
|
|
8ce9488bb5 | ||
|
|
5077157282 | ||
|
|
f029b68ad4 | ||
|
|
a8e914ad9f | ||
|
|
5eecc768a3 | ||
|
|
9c23f6c476 | ||
|
|
7bd584abe0 | ||
|
|
5b592eca4f | ||
|
|
5459c1eb96 | ||
|
|
0bcb1d18ce | ||
|
|
e1f9e9a8f8 | ||
|
|
384903361d | ||
|
|
585c777878 | ||
|
|
1bbecdff6c | ||
|
|
303f06cc61 | ||
|
|
02a5789dd3 | ||
|
|
951fdaf3ab | ||
|
|
7ce2538778 | ||
|
|
23608855c6 | ||
|
|
d34b628583 | ||
|
|
6ceefe2a27 | ||
|
|
33e515608f | ||
|
|
14f46a8ca9 | ||
|
|
6ae7d60f4a | ||
|
|
fe6a9c257b | ||
|
|
f2c3f880c7 | ||
|
|
e638abf7c2 | ||
|
|
072f87a06a | ||
|
|
6103f4a9d3 | ||
|
|
6a20bd53de | ||
|
|
0b69601fcc | ||
|
|
ee66e3e127 | ||
|
|
5ab6374bc0 | ||
|
|
269ec4609a | ||
|
|
585b651b4c | ||
|
|
1384783a77 | ||
|
|
071a5410b8 | ||
|
|
7fc258453f | ||
|
|
849fc96438 | ||
|
|
adad5e16c2 | ||
|
|
1f97bc2325 | ||
|
|
cce4e9e87a | ||
|
|
f54f59bd9b | ||
|
|
6ae414fe60 | ||
|
|
6681338e05 | ||
|
|
f74a7a69c7 | ||
|
|
c8d3d1b8a8 | ||
|
|
f149f9a9ad | ||
|
|
2d3757c37f | ||
|
|
75fb1b8d65 | ||
|
|
29d732900d | ||
|
|
fb523fcd36 | ||
|
|
59eefdbcd8 | ||
|
|
3be2c38a73 | ||
|
|
81fdae0d88 | ||
|
|
31702e9a26 | ||
|
|
f975d85806 | ||
|
|
8ec86eb7d5 | ||
|
|
30339bd9a3 | ||
|
|
3f2ad33b2b | ||
|
|
43a55698e3 | ||
|
|
b80a2cbd18 | ||
|
|
9223d93450 | ||
|
|
491999281f | ||
|
|
6721a7162f | ||
|
|
9a17a61809 | ||
|
|
240c3be014 | ||
|
|
087aed80dd | ||
|
|
c13a1908df | ||
|
|
ce7094182d | ||
|
|
fe88030bc9 | ||
|
|
38fee6fc4d | ||
|
|
46dd44dd70 | ||
|
|
de9e65de2b | ||
|
|
65adc3ba93 | ||
|
|
c8127dc4b6 | ||
|
|
a154696962 | ||
|
|
15497a143b | ||
|
|
cb46202ee1 | ||
|
|
682f4e6b5a | ||
|
|
8c3c8f6daa | ||
|
|
302e7a56cc | ||
|
|
db55c75ada | ||
|
|
95de708f4e | ||
|
|
a2b0cf9248 | ||
|
|
3810b7e329 | ||
|
|
481ab9d8fa | ||
|
|
d08e714706 | ||
|
|
daa57e156a | ||
|
|
ee0aaf1c33 | ||
|
|
d8ce23c767 | ||
|
|
a0506459da | ||
|
|
a01684e126 | ||
|
|
53f6282a53 | ||
|
|
8d0f616ffa | ||
|
|
ba55473a0e | ||
|
|
8e480c72d3 | ||
|
|
6d042a6b35 | ||
|
|
bae36cbc59 | ||
|
|
b46c241c96 | ||
|
|
52c86264dc | ||
|
|
c275ef6b49 | ||
|
|
135f37eeaf | ||
|
|
f14450fdd2 | ||
|
|
4532999582 | ||
|
|
900816b82c | ||
|
|
76c1a7b5de | ||
|
|
f9e8fc6666 | ||
|
|
b53c009fd9 | ||
|
|
87a20a5e57 | ||
|
|
388df406b1 | ||
|
|
5552ac0624 | ||
|
|
fd9016b5f1 | ||
|
|
f41f03a5b2 | ||
|
|
b723889dc2 | ||
|
|
dd8855cffc | ||
|
|
fa64d65e6e | ||
|
|
42416021ad | ||
|
|
d4a019b27a | ||
|
|
c4b75669ed | ||
|
|
954cb35903 | ||
|
|
74f117f7e6 | ||
|
|
762fc53c61 | ||
|
|
37c81f39f6 | ||
|
|
b5735578b8 | ||
|
|
041447e57d | ||
|
|
35a434df40 | ||
|
|
74e0510dc3 | ||
|
|
55b383f78a | ||
|
|
64242a004e | ||
|
|
ba20134d1f | ||
|
|
6bc7036dc8 | ||
|
|
0041ad7230 | ||
|
|
e70c52eaec | ||
|
|
53a937eb6c | ||
|
|
b41c899a91 | ||
|
|
d731a25619 | ||
|
|
60e23d9383 | ||
|
|
e6488e7e16 | ||
|
|
22ace3c597 | ||
|
|
d98ff93872 | ||
|
|
6113812307 | ||
|
|
d72d1ba2c5 | ||
|
|
84b47f20b9 | ||
|
|
147b2ab377 | ||
|
|
58eec3db2c | ||
|
|
7078373fbb | ||
|
|
cfa97212f7 | ||
|
|
e1e6a2a7a6 | ||
|
|
df1db45a39 | ||
|
|
031f517073 | ||
|
|
3644ad1324 | ||
|
|
ab94531776 | ||
|
|
e4ae926f6e | ||
|
|
286c770d7c | ||
|
|
c6c1238cef | ||
|
|
e0c11e1dff | ||
|
|
433542010b | ||
|
|
397e2b53d1 | ||
|
|
c6c0da5b97 | ||
|
|
db1cfa9588 | ||
|
|
ab31ea3719 | ||
|
|
956f0a4ca6 | ||
|
|
e0353b217c | ||
|
|
c778aa8244 | ||
|
|
6adaa417f0 | ||
|
|
03e776d9c4 | ||
|
|
06fa4f4440 | ||
|
|
68f5826013 | ||
|
|
c40dbf1580 | ||
|
|
85012b287f | ||
|
|
840867bc02 | ||
|
|
9115fb7509 | ||
|
|
a43b141a43 | ||
|
|
aed3467fdf | ||
|
|
869b271f72 | ||
|
|
3033aa1d1a | ||
|
|
36d3a5fdeb | ||
|
|
392d9d1121 | ||
|
|
85f6c3b21f | ||
|
|
9c4d57e91c | ||
|
|
d3e2af58e9 | ||
|
|
315f95e390 | ||
|
|
ef9335697e | ||
|
|
bcb5910d43 | ||
|
|
d7813c09d9 | ||
|
|
1f73249d19 | ||
|
|
6d8f0db82f | ||
|
|
7036600fa7 | ||
|
|
20bd175588 | ||
|
|
da8476e426 | ||
|
|
d40f432132 | ||
|
|
8a9f677a76 | ||
|
|
6c1fc8e903 | ||
|
|
27ad1ebda0 | ||
|
|
f434bb9f20 | ||
|
|
672ca16428 | ||
|
|
c27cdcf849 | ||
|
|
2d548d1179 | ||
|
|
2617b424ce | ||
|
|
10d7bdf9a1 | ||
|
|
211f480027 | ||
|
|
30cb0ae96d | ||
|
|
dafdc1d642 | ||
|
|
10729e307e | ||
|
|
7fc0bab410 | ||
|
|
0f15ba34cd | ||
|
|
9b87566477 | ||
|
|
bce599a1fb | ||
|
|
111b3b9de7 | ||
|
|
9e1f393224 | ||
|
|
b7f48479f3 | ||
|
|
23b21c940c | ||
|
|
33d6899345 | ||
|
|
a58a74b39d | ||
|
|
7b1a6f0146 | ||
|
|
3305fdb08b | ||
|
|
705366ab8c | ||
|
|
a90cbe9476 | ||
|
|
2aff06f56e | ||
|
|
e747380057 | ||
|
|
eae38311b2 | ||
|
|
1b6b1a8621 | ||
|
|
46bcd13e05 | ||
|
|
80cf11135d | ||
|
|
9eb5af53e2 | ||
|
|
0637c2e74d | ||
|
|
1e386f7786 | ||
|
|
0744c86ac9 | ||
|
|
1d7c4d5d92 | ||
|
|
ebc2bb7c56 | ||
|
|
df84c48d73 | ||
|
|
9417470e93 | ||
|
|
5a6e981cb4 | ||
|
|
0a5adedbc1 | ||
|
|
b155d19934 | ||
|
|
dc75590916 | ||
|
|
de9f427364 | ||
|
|
159f1962a1 | ||
|
|
b0abbfacd4 | ||
|
|
b3c5bb899b | ||
|
|
83f0f1de72 | ||
|
|
9ddab82979 | ||
|
|
996d79847a | ||
|
|
15df3bc816 | ||
|
|
8247318399 | ||
|
|
4bb310ad3d | ||
|
|
39901b8d72 | ||
|
|
60788da1a3 | ||
|
|
9b780e0e60 | ||
|
|
95a2b8eb2f | ||
|
|
317430b6b1 | ||
|
|
1a403a37f9 | ||
|
|
883d8cecaa | ||
|
|
459f2f2334 | ||
|
|
7753fee9e1 | ||
|
|
0e69caee7c | ||
|
|
b14b2967ec | ||
|
|
bacddc5dfc | ||
|
|
a799672bd3 | ||
|
|
87882dd6a3 | ||
|
|
2039f1fcae | ||
|
|
f496d6d5bf | ||
|
|
ae048025e4 | ||
|
|
090fc808bb | ||
|
|
10e121a514 | ||
|
|
194aeac19e | ||
|
|
9746517ef7 | ||
|
|
40892ad087 | ||
|
|
d443787608 | ||
|
|
2995894055 | ||
|
|
c8ca48c79e | ||
|
|
08c164a851 | ||
|
|
0ad25f41ff | ||
|
|
0dee9d78a5 | ||
|
|
9e1d72122e | ||
|
|
82ddf8da99 | ||
|
|
b2e8f212e4 | ||
|
|
12a42499a7 | ||
|
|
8e58d31db3 | ||
|
|
8e279116ae | ||
|
|
28f00498a2 | ||
|
|
88bd3e41d0 | ||
|
|
bd0ceca351 | ||
|
|
a16dcb8a5f | ||
|
|
87287bd10b | ||
|
|
ac75174729 | ||
|
|
cf7d273052 | ||
|
|
4158a49297 | ||
|
|
2ef1191afa | ||
|
|
0317e39ef7 | ||
|
|
8c227f61dd | ||
|
|
0c3efaec9a | ||
|
|
3d2880ddfb | ||
|
|
addb6183b3 | ||
|
|
ef87da52f4 | ||
|
|
06e855c601 | ||
|
|
cb0f9022f9 | ||
|
|
516e38c82d | ||
|
|
c0a7437c20 | ||
|
|
d9f72ec0b6 | ||
|
|
f9cbdb8aa0 | ||
|
|
063b1d7f59 | ||
|
|
f74765658c | ||
|
|
2d579a8b73 | ||
|
|
68a73078c5 | ||
|
|
ad6ec9ed10 | ||
|
|
c52905fe4e | ||
|
|
37840b4121 | ||
|
|
5ac4702ae3 | ||
|
|
9793816b5f | ||
|
|
c4adac315e | ||
|
|
4553531e7e | ||
|
|
ba302b7dc0 | ||
|
|
85b489b3a7 | ||
|
|
940aaa0d1a | ||
|
|
4c4b9b96e7 | ||
|
|
9b3159ce64 | ||
|
|
80931222cd | ||
|
|
90776db423 | ||
|
|
e794234bc9 | ||
|
|
92500cf2d1 | ||
|
|
fc9ae78b56 | ||
|
|
aa78b21457 | ||
|
|
0adad257c0 | ||
|
|
a7740b5424 | ||
|
|
7a24f67caf | ||
|
|
a4b6690e4d | ||
|
|
75eab660c2 | ||
|
|
f550d63198 | ||
|
|
004e8edcb2 | ||
|
|
d24348de81 | ||
|
|
d3814ddae0 | ||
|
|
3278c5a306 | ||
|
|
6909e28764 | ||
|
|
c1ca4a0920 | ||
|
|
e0a1e6f5a6 | ||
|
|
cb25cb470d | ||
|
|
30800755d7 | ||
|
|
b72b6c6089 | ||
|
|
96a506ded3 | ||
|
|
615ccb0481 | ||
|
|
ccd88ba087 | ||
|
|
e6993ca964 | ||
|
|
85a81af1da | ||
|
|
dc9f77a509 | ||
|
|
db01bfc0fd | ||
|
|
515a8d2097 | ||
|
|
ab6ba952ac | ||
|
|
195234a7b5 | ||
|
|
ce3cc42e4a | ||
|
|
700d59be16 | ||
|
|
9673661177 | ||
|
|
794043f1b8 | ||
|
|
4c25a5e8bd | ||
|
|
ef470a1207 | ||
|
|
c405880a39 | ||
|
|
347f90ef73 | ||
|
|
7ed733d9bf | ||
|
|
1490d4f462 | ||
|
|
93c037a318 | ||
|
|
46e526c038 | ||
|
|
613c04d984 | ||
|
|
403c851461 | ||
|
|
1cf095a3e1 | ||
|
|
2deee7a709 | ||
|
|
50a2badd96 | ||
|
|
df3647f139 | ||
|
|
79cbf55986 | ||
|
|
6c1624f2f2 | ||
|
|
971f4bbb4d | ||
|
|
afe8e878a5 | ||
|
|
8e486c3f98 | ||
|
|
2ef743e5ee | ||
|
|
a605657ebe | ||
|
|
f214031f8b | ||
|
|
5fff0fb677 | ||
|
|
721670d57e | ||
|
|
74669e178c | ||
|
|
7bc016dbea | ||
|
|
90ada74daf | ||
|
|
efeb9cb1d5 | ||
|
|
b1627461a7 | ||
|
|
5f236f0224 | ||
|
|
20c4c2fcd3 | ||
|
|
a98942e0c8 | ||
|
|
88030330f1 | ||
|
|
64fa84fc60 | ||
|
|
72c9a6f437 | ||
|
|
8be55d8dcf | ||
|
|
107d8f6fb8 | ||
|
|
49076a8a06 | ||
|
|
1571df1c82 | ||
|
|
4efa0b215f | ||
|
|
b953ad3353 | ||
|
|
fe9d0189a0 | ||
|
|
5192f344b1 | ||
|
|
ef436b8fa7 | ||
|
|
e15d27b316 | ||
|
|
935f95fcde | ||
|
|
e39b6e3057 | ||
|
|
37a0957285 | ||
|
|
155d80b3fa | ||
|
|
ecf29d9409 | ||
|
|
04ee4d6137 | ||
|
|
2a4dcd1267 | ||
|
|
9a8ba41510 | ||
|
|
249cb4d169 | ||
|
|
0142bb04e4 | ||
|
|
6dca9c60f0 | ||
|
|
564d427be7 | ||
|
|
dbecdc4f14 | ||
|
|
3f037a05d0 | ||
|
|
e90f7b7e82 | ||
|
|
5741baed25 | ||
|
|
c964391c4f | ||
|
|
b48561d34f | ||
|
|
e7caa54e59 | ||
|
|
cea07479ec | ||
|
|
54c2e8fc8e | ||
|
|
5553cdf329 | ||
|
|
237bc51cd1 | ||
|
|
b4187c6150 | ||
|
|
212138b017 | ||
|
|
77ceff07d5 | ||
|
|
a3c4fac375 | ||
|
|
470ab22e2d | ||
|
|
cf5cbb1ff9 | ||
|
|
6590debbc6 | ||
|
|
63379f41b9 | ||
|
|
1ddbed74d3 | ||
|
|
9ac0d2c756 | ||
|
|
bd96d29966 | ||
|
|
c3cc9f20f5 | ||
|
|
46769046da | ||
|
|
539f892c67 | ||
|
|
1dfdfd91bd | ||
|
|
f85def5f3f | ||
|
|
2f00845957 | ||
|
|
4a24775fd9 | ||
|
|
017e4bd84b | ||
|
|
9e5f88427d | ||
|
|
7aff5b2df3 | ||
|
|
938632a884 | ||
|
|
3628dfd3f0 | ||
|
|
606fd8b51b | ||
|
|
b4742373f3 | ||
|
|
730c4e8e3a | ||
|
|
3755aec974 | ||
|
|
c9dd1573ca | ||
|
|
66277f7def | ||
|
|
0b628cf102 | ||
|
|
1c393d0044 | ||
|
|
22f6ac1e38 | ||
|
|
674bba1e15 | ||
|
|
96f8dab224 | ||
|
|
6774f28cff | ||
|
|
07887effcc | ||
|
|
a9c331edbf | ||
|
|
79c4b95824 | ||
|
|
3fd49628a2 | ||
|
|
122664433f | ||
|
|
1dcdd549d0 | ||
|
|
0a87baf99d | ||
|
|
65acbc51c6 | ||
|
|
1aa2efd2ce | ||
|
|
a57af54706 | ||
|
|
44a67ee383 | ||
|
|
88428b9835 | ||
|
|
72e4197db8 | ||
|
|
2c6fa9707b | ||
|
|
3f086578b0 | ||
|
|
446c4f991f | ||
|
|
73a05d35bd | ||
|
|
f4a11b8509 | ||
|
|
8f3c0be388 | ||
|
|
4f0c3bf4ff | ||
|
|
46b7f2356e | ||
|
|
574e848bf3 | ||
|
|
75b1d813f1 | ||
|
|
c7aab2530b | ||
|
|
7a72547133 | ||
|
|
dd17148ce6 | ||
|
|
a40d7474f4 | ||
|
|
10a8d06546 | ||
|
|
5a561b674f | ||
|
|
11648224c7 | ||
|
|
ae624658c9 | ||
|
|
e4997981ec | ||
|
|
9d0a96cf9a | ||
|
|
8c78084531 | ||
|
|
feefa2ece2 | ||
|
|
2d48797294 | ||
|
|
da1423d660 | ||
|
|
6747155dea | ||
|
|
1e41f7ad19 | ||
|
|
c0ffd980a1 | ||
|
|
2dfa6fd58e | ||
|
|
fa0d500d4a | ||
|
|
dec8795f7a | ||
|
|
0a13413c48 | ||
|
|
1d5d7751f7 | ||
|
|
8fa4079565 | ||
|
|
dc3d0abfef | ||
|
|
4ab524673d | ||
|
|
a947cdfa96 | ||
|
|
4da180324a | ||
|
|
a2cde39495 | ||
|
|
d627faf3f8 | ||
|
|
ed3ba39ffe | ||
|
|
fad1237dd0 | ||
|
|
c551063832 | ||
|
|
0cb9fef9da | ||
|
|
6874e782f2 | ||
|
|
607c840917 | ||
|
|
4d5607894c | ||
|
|
b8fb8b0460 | ||
|
|
9b7070b8e6 | ||
|
|
eb8d3be1c3 | ||
|
|
315609e375 | ||
|
|
6fcb021874 | ||
|
|
cd213eb43a | ||
|
|
5aff525eaa | ||
|
|
05ee3d26ab | ||
|
|
705c568609 | ||
|
|
f9af8a9f07 | ||
|
|
7b0a89a81f | ||
|
|
212e4de5e1 | ||
|
|
5e68c95d8e | ||
|
|
b873185c68 | ||
|
|
13aa157a66 | ||
|
|
7f9b58a10b | ||
|
|
e88948917a | ||
|
|
22620066d7 | ||
|
|
adc8efc691 | ||
|
|
c103565b3c | ||
|
|
d76ef0d366 | ||
|
|
b73e2fc27d | ||
|
|
89c0450c73 | ||
|
|
b25d8086dc | ||
|
|
cbc64dfd68 | ||
|
|
1200ae9c90 | ||
|
|
15e4f95c61 | ||
|
|
6d61d481dc | ||
|
|
3b37c52479 | ||
|
|
d44f0bd45d | ||
|
|
719822eb1e | ||
|
|
6535b36a87 | ||
|
|
0d89c1e5ef | ||
|
|
3f2611a752 | ||
|
|
d1287e564c | ||
|
|
2f60dfc575 | ||
|
|
6dfd745b04 | ||
|
|
56599776b5 | ||
|
|
a42400d6d6 | ||
|
|
3d1eca95dc | ||
|
|
b36b3f1e91 | ||
|
|
308078d2fc | ||
|
|
d5d7fe64f5 | ||
|
|
219ea134ca | ||
|
|
f8eb1d17f9 | ||
|
|
7a1c3b85b6 | ||
|
|
87d5527489 | ||
|
|
a761dac99f | ||
|
|
ee9d6afba8 | ||
|
|
66012c3e84 | ||
|
|
4719a6e310 | ||
|
|
15c4fb69b1 | ||
|
|
af8526a9b3 | ||
|
|
e17debcf4b | ||
|
|
e41885bf4e | ||
|
|
64ad740d39 | ||
|
|
c965963104 | ||
|
|
a5e46f3cf1 | ||
|
|
24a076a202 | ||
|
|
1ca09a00de | ||
|
|
44d741c061 | ||
|
|
d294c9087f | ||
|
|
057abdd240 | ||
|
|
0e82b884e8 | ||
|
|
aea3b67896 | ||
|
|
30df9abebd | ||
|
|
687ba9ed01 | ||
|
|
1f08913703 | ||
|
|
f7cc33688d | ||
|
|
231ff3a73d | ||
|
|
58c0eecbf8 | ||
|
|
f16f804637 | ||
|
|
819fea0521 | ||
|
|
c6e6ac18a2 | ||
|
|
b04b2baf4e | ||
|
|
444cf1f617 | ||
|
|
c055b4a20e | ||
|
|
9adcabb860 | ||
|
|
4b602d61c9 | ||
|
|
1b7b353f48 | ||
|
|
a76a33aeaf | ||
|
|
5192a7f448 | ||
|
|
5f4fa6b17a | ||
|
|
d806927196 | ||
|
|
1df5e08b48 | ||
|
|
b782d10333 | ||
|
|
23aabcc56c | ||
|
|
89b6715438 | ||
|
|
00668f8803 | ||
|
|
67164147a8 | ||
|
|
412a7554c7 | ||
|
|
c3c47f170c | ||
|
|
0eb8d3f4d1 | ||
|
|
e96059337e | ||
|
|
45cbfbf5d8 | ||
|
|
74bc3c1dab | ||
|
|
5dcf3e1eaf | ||
|
|
feedeabee3 | ||
|
|
edd97fc596 | ||
|
|
1b9ae1b32f | ||
|
|
0931fc9622 | ||
|
|
6c39127018 | ||
|
|
931ac30f6b | ||
|
|
d71d9b067e | ||
|
|
a1261254c9 | ||
|
|
f97f9825c4 | ||
|
|
e61a7313cd | ||
|
|
657fbee7b0 | ||
|
|
df7cca025a | ||
|
|
60b61dbf27 | ||
|
|
225ee474eb | ||
|
|
184613753f | ||
|
|
5873a04869 | ||
|
|
05a242d163 | ||
|
|
490140cd6d | ||
|
|
a53670a36e | ||
|
|
0fb0c2f384 | ||
|
|
c914d3d438 | ||
|
|
cfc4578406 | ||
|
|
342cf359b4 | ||
|
|
95e1067337 | ||
|
|
c370afd94e | ||
|
|
2dc89fb425 | ||
|
|
ad97f8a70e | ||
|
|
b7d556c2c7 | ||
|
|
d7558afb58 | ||
|
|
36c8af48fa | ||
|
|
73eecfcf52 | ||
|
|
386dcf1283 | ||
|
|
3d25198994 | ||
|
|
2d77341641 | ||
|
|
ac76143cdf | ||
|
|
78dace3656 | ||
|
|
62bd5009cd | ||
|
|
b10dc045ae | ||
|
|
71dcb0dd0d | ||
|
|
d5bce88176 | ||
|
|
fd32037f23 | ||
|
|
598ed0d198 | ||
|
|
e1faddb488 | ||
|
|
d3f9affe5a | ||
|
|
fac01903e7 | ||
|
|
6a8f69243f | ||
|
|
eea454dc8c | ||
|
|
724f575119 | ||
|
|
ec96496b04 | ||
|
|
8bc1bc2caf | ||
|
|
ac0daa2145 | ||
|
|
55338701ea | ||
|
|
68fc9fb9ad | ||
|
|
d9226c6865 | ||
|
|
12a7c28928 | ||
|
|
25b41bc605 | ||
|
|
424fd8da70 | ||
|
|
3acb7919f6 | ||
|
|
9cc90f090a | ||
|
|
fd9b14a75e | ||
|
|
1866ee812f | ||
|
|
e6305c0e59 | ||
|
|
ae8765c394 | ||
|
|
524a144d38 | ||
|
|
574691e1e3 | ||
|
|
b72eb61720 | ||
|
|
4de76c4c8e | ||
|
|
f8d21def86 | ||
|
|
a0e256d98b | ||
|
|
652d18107a | ||
|
|
f56e8d7489 | ||
|
|
429eb085ea | ||
|
|
bc34c13812 | ||
|
|
60dd660fec | ||
|
|
a97108710c | ||
|
|
5470c074d9 | ||
|
|
0f27481b6e | ||
|
|
b5fdeb127f | ||
|
|
b38d79dd85 | ||
|
|
6b39bb9de7 | ||
|
|
88de44f3f0 | ||
|
|
a77a975bf8 | ||
|
|
188492d320 | ||
|
|
854f5b5ef2 | ||
|
|
0841c96ae4 | ||
|
|
91b37e7268 | ||
|
|
98a71bd7df | ||
|
|
8480dbb726 | ||
|
|
d5cd770c84 | ||
|
|
43d8d7a477 | ||
|
|
a567b1d57f | ||
|
|
66c86697c1 | ||
|
|
6685ff0e79 | ||
|
|
1923e0cd34 | ||
|
|
7a2b60f276 | ||
|
|
e123b8bcc0 | ||
|
|
d4fc3ed354 | ||
|
|
53c8e08dde | ||
|
|
aeca4df693 | ||
|
|
cb9a8389ac | ||
|
|
54620a2eb8 | ||
|
|
e9863f0719 | ||
|
|
c82db4fc87 | ||
|
|
878c285faa | ||
|
|
d9289f063a | ||
|
|
8233016071 | ||
|
|
79157c0bf9 | ||
|
|
fd67e21d31 | ||
|
|
5319b34fd6 | ||
|
|
2d6a8d3d1e | ||
|
|
9c92045646 | ||
|
|
8b56a55906 | ||
|
|
9847942fd5 | ||
|
|
c2a956d589 | ||
|
|
42e3fd0282 | ||
|
|
c3995eea5e | ||
|
|
1c10292343 | ||
|
|
06d536afbc | ||
|
|
cc1a1e751b | ||
|
|
2042246ab6 | ||
|
|
3aa5b1c901 | ||
|
|
25ebe15a35 | ||
|
|
cfb1aefbc6 | ||
|
|
d8d064210d | ||
|
|
c29ef4bb5f | ||
|
|
848d41b971 | ||
|
|
484563477e | ||
|
|
c3af46dc27 | ||
|
|
1dc6a56273 | ||
|
|
1e5c738c32 | ||
|
|
942700ee3b | ||
|
|
99c9824e15 | ||
|
|
d6606afd72 | ||
|
|
e2ff2f5369 | ||
|
|
821dd4e5b0 | ||
|
|
c90430954b | ||
|
|
10fb3859fa | ||
|
|
88df5c33a9 | ||
|
|
da4a49fd31 | ||
|
|
a9f3f873a5 | ||
|
|
b677edbc58 | ||
|
|
4b12b711ee | ||
|
|
2504c062f1 | ||
|
|
9d356aa931 | ||
|
|
17f86b4c39 | ||
|
|
245d13875f | ||
|
|
e7cb419902 | ||
|
|
54b78a64b8 | ||
|
|
95a5a83868 | ||
|
|
90d63ff883 | ||
|
|
ba5e690a38 | ||
|
|
37faa1caa9 | ||
|
|
49dfa4ee6c | ||
|
|
e6e701f5e9 | ||
|
|
c04daeaa20 | ||
|
|
1cffed2336 | ||
|
|
714d03524c | ||
|
|
0609ebc430 | ||
|
|
858d71218c |
@@ -1,16 +1,8 @@
|
||||
# Copyright 2024 New Vector Ltd.
|
||||
# Copyright 2017 Aviral Dasgupta
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
# SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
# Please see LICENSE files in the repository root for full details.
|
||||
|
||||
root = true
|
||||
|
||||
@@ -21,3 +13,12 @@ insert_final_newline = true
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.{yml,yaml}]
|
||||
indent_size = 4
|
||||
|
||||
[package.json]
|
||||
indent_size = 2
|
||||
|
||||
[*.tsx.snap]
|
||||
trim_trailing_whitespace = false
|
||||
|
||||
@@ -1,2 +1,9 @@
|
||||
src/vector/modernizr.js
|
||||
test/end-to-end-tests/node_modules/
|
||||
test/end-to-end-tests/element/
|
||||
test/end-to-end-tests/synapse/
|
||||
test/end-to-end-tests/lib/
|
||||
# Legacy skinning file that some people might still have
|
||||
src/component-index.js
|
||||
# Auto-generated file
|
||||
src/modules.ts
|
||||
|
||||
60
.eslintrc-module_system.js
Normal file
60
.eslintrc-module_system.js
Normal file
@@ -0,0 +1,60 @@
|
||||
module.exports = {
|
||||
plugins: ["matrix-org"],
|
||||
extends: ["./.eslintrc.js"],
|
||||
parserOptions: {
|
||||
project: ["./tsconfig.module_system.json"],
|
||||
},
|
||||
overrides: [
|
||||
{
|
||||
files: ["module_system/**/*.{ts,tsx}"],
|
||||
extends: ["plugin:matrix-org/typescript", "plugin:matrix-org/react"],
|
||||
// NOTE: These rules are frozen and new rules should not be added here.
|
||||
// New changes belong in https://github.com/matrix-org/eslint-plugin-matrix-org/
|
||||
rules: {
|
||||
// Things we do that break the ideal style
|
||||
"prefer-promise-reject-errors": "off",
|
||||
"quotes": "off",
|
||||
|
||||
// We disable this while we're transitioning
|
||||
"@typescript-eslint/no-explicit-any": "off",
|
||||
// We're okay with assertion errors when we ask for them
|
||||
"@typescript-eslint/no-non-null-assertion": "off",
|
||||
|
||||
// Ban matrix-js-sdk/src imports in favour of matrix-js-sdk/src/matrix imports to prevent unleashing hell.
|
||||
"no-restricted-imports": [
|
||||
"error",
|
||||
{
|
||||
paths: [
|
||||
{
|
||||
name: "matrix-js-sdk",
|
||||
message: "Please use matrix-js-sdk/src/matrix instead",
|
||||
},
|
||||
{
|
||||
name: "matrix-js-sdk/",
|
||||
message: "Please use matrix-js-sdk/src/matrix instead",
|
||||
},
|
||||
{
|
||||
name: "matrix-js-sdk/src",
|
||||
message: "Please use matrix-js-sdk/src/matrix instead",
|
||||
},
|
||||
{
|
||||
name: "matrix-js-sdk/src/",
|
||||
message: "Please use matrix-js-sdk/src/matrix instead",
|
||||
},
|
||||
{
|
||||
name: "matrix-js-sdk/src/index",
|
||||
message: "Please use matrix-js-sdk/src/matrix instead",
|
||||
},
|
||||
],
|
||||
patterns: [
|
||||
{
|
||||
group: ["matrix-js-sdk/lib", "matrix-js-sdk/lib/", "matrix-js-sdk/lib/**"],
|
||||
message: "Please use matrix-js-sdk/src/* instead",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
296
.eslintrc.js
296
.eslintrc.js
@@ -1,30 +1,288 @@
|
||||
module.exports = {
|
||||
plugins: ["matrix-org"],
|
||||
extends: [
|
||||
"plugin:matrix-org/babel",
|
||||
"plugin:matrix-org/react",
|
||||
],
|
||||
extends: ["plugin:matrix-org/babel", "plugin:matrix-org/react", "plugin:matrix-org/a11y"],
|
||||
parserOptions: {
|
||||
project: ["./tsconfig.json"],
|
||||
},
|
||||
env: {
|
||||
browser: true,
|
||||
node: true,
|
||||
},
|
||||
globals: {
|
||||
LANGUAGES_FILE: "readonly",
|
||||
},
|
||||
rules: {
|
||||
// Things we do that break the ideal style
|
||||
"quotes": "off",
|
||||
},
|
||||
overrides: [{
|
||||
files: ["src/**/*.{ts,tsx}"],
|
||||
extends: [
|
||||
"plugin:matrix-org/typescript",
|
||||
"plugin:matrix-org/react",
|
||||
],
|
||||
rules: {
|
||||
// Things we do that break the ideal style
|
||||
"prefer-promise-reject-errors": "off",
|
||||
"quotes": "off",
|
||||
"no-constant-condition": "off",
|
||||
"prefer-promise-reject-errors": "off",
|
||||
"no-async-promise-executor": "off",
|
||||
"no-extra-boolean-cast": "off",
|
||||
|
||||
// We disable this while we're transitioning
|
||||
"@typescript-eslint/no-explicit-any": "off",
|
||||
// Bind or arrow functions in props causes performance issues (but we
|
||||
// currently use them in some places).
|
||||
// It's disabled here, but we should using it sparingly.
|
||||
"react/jsx-no-bind": "off",
|
||||
"react/jsx-key": ["error"],
|
||||
|
||||
"no-restricted-properties": [
|
||||
"error",
|
||||
...buildRestrictedPropertiesOptions(
|
||||
["window.innerHeight", "window.innerWidth", "window.visualViewport"],
|
||||
"Use UIStore to access window dimensions instead.",
|
||||
),
|
||||
...buildRestrictedPropertiesOptions(
|
||||
["*.mxcUrlToHttp", "*.getHttpUriForMxc"],
|
||||
"Use Media helper instead to centralise access for customisation.",
|
||||
),
|
||||
...buildRestrictedPropertiesOptions(["window.setImmediate"], "Use setTimeout instead."),
|
||||
],
|
||||
"no-restricted-globals": [
|
||||
"error",
|
||||
{
|
||||
name: "setImmediate",
|
||||
message: "Use setTimeout instead.",
|
||||
},
|
||||
],
|
||||
|
||||
"import/no-duplicates": ["error"],
|
||||
// Ban matrix-js-sdk/src imports in favour of matrix-js-sdk/src/matrix imports to prevent unleashing hell.
|
||||
// Ban compound-design-tokens raw svg imports in favour of their React component counterparts
|
||||
"no-restricted-imports": [
|
||||
"error",
|
||||
{
|
||||
paths: [
|
||||
{
|
||||
name: "@testing-library/react",
|
||||
message: "Please use jest-matrix-react instead",
|
||||
},
|
||||
{
|
||||
name: "matrix-js-sdk",
|
||||
message: "Please use matrix-js-sdk/src/matrix instead",
|
||||
},
|
||||
{
|
||||
name: "matrix-js-sdk/",
|
||||
message: "Please use matrix-js-sdk/src/matrix instead",
|
||||
},
|
||||
{
|
||||
name: "matrix-js-sdk/src",
|
||||
message: "Please use matrix-js-sdk/src/matrix instead",
|
||||
},
|
||||
{
|
||||
name: "matrix-js-sdk/src/",
|
||||
message: "Please use matrix-js-sdk/src/matrix instead",
|
||||
},
|
||||
{
|
||||
name: "matrix-js-sdk/src/index",
|
||||
message: "Please use matrix-js-sdk/src/matrix instead",
|
||||
},
|
||||
{
|
||||
name: "emojibase-regex",
|
||||
message:
|
||||
"This regex doesn't actually test for emoji. See the docs at https://emojibase.dev/docs/regex/ and prefer our own EMOJI_REGEX from HtmlUtils.",
|
||||
},
|
||||
],
|
||||
patterns: [
|
||||
{
|
||||
group: [
|
||||
"matrix-js-sdk/src/**",
|
||||
"!matrix-js-sdk/src/matrix",
|
||||
"!matrix-js-sdk/src/crypto-api",
|
||||
"!matrix-js-sdk/src/types",
|
||||
"!matrix-js-sdk/src/testing",
|
||||
"!matrix-js-sdk/src/utils/**",
|
||||
"matrix-js-sdk/src/utils/internal/**",
|
||||
"matrix-js-sdk/lib",
|
||||
"matrix-js-sdk/lib/",
|
||||
"matrix-js-sdk/lib/**",
|
||||
// XXX: Temporarily allow these as they are not available via the main export
|
||||
"!matrix-js-sdk/src/logger",
|
||||
"!matrix-js-sdk/src/errors",
|
||||
"!matrix-js-sdk/src/utils",
|
||||
"!matrix-js-sdk/src/version-support",
|
||||
"!matrix-js-sdk/src/randomstring",
|
||||
"!matrix-js-sdk/src/sliding-sync",
|
||||
"!matrix-js-sdk/src/browser-index",
|
||||
"!matrix-js-sdk/src/feature",
|
||||
"!matrix-js-sdk/src/NamespacedValue",
|
||||
"!matrix-js-sdk/src/ReEmitter",
|
||||
"!matrix-js-sdk/src/event-mapper",
|
||||
"!matrix-js-sdk/src/interactive-auth",
|
||||
"!matrix-js-sdk/src/secret-storage",
|
||||
"!matrix-js-sdk/src/room-hierarchy",
|
||||
"!matrix-js-sdk/src/rendezvous",
|
||||
"!matrix-js-sdk/src/indexeddb-worker",
|
||||
"!matrix-js-sdk/src/pushprocessor",
|
||||
"!matrix-js-sdk/src/extensible_events_v1",
|
||||
"!matrix-js-sdk/src/extensible_events_v1/PollStartEvent",
|
||||
"!matrix-js-sdk/src/extensible_events_v1/PollResponseEvent",
|
||||
"!matrix-js-sdk/src/extensible_events_v1/PollEndEvent",
|
||||
"!matrix-js-sdk/src/extensible_events_v1/InvalidEventError",
|
||||
"!matrix-js-sdk/src/crypto",
|
||||
"!matrix-js-sdk/src/crypto/keybackup",
|
||||
"!matrix-js-sdk/src/crypto/deviceinfo",
|
||||
"!matrix-js-sdk/src/crypto/dehydration",
|
||||
"!matrix-js-sdk/src/oidc",
|
||||
"!matrix-js-sdk/src/oidc/discovery",
|
||||
"!matrix-js-sdk/src/oidc/authorize",
|
||||
"!matrix-js-sdk/src/oidc/validate",
|
||||
"!matrix-js-sdk/src/oidc/error",
|
||||
"!matrix-js-sdk/src/oidc/register",
|
||||
"!matrix-js-sdk/src/webrtc",
|
||||
"!matrix-js-sdk/src/webrtc/call",
|
||||
"!matrix-js-sdk/src/webrtc/callFeed",
|
||||
"!matrix-js-sdk/src/webrtc/mediaHandler",
|
||||
"!matrix-js-sdk/src/webrtc/callEventTypes",
|
||||
"!matrix-js-sdk/src/webrtc/callEventHandler",
|
||||
"!matrix-js-sdk/src/webrtc/groupCallEventHandler",
|
||||
"!matrix-js-sdk/src/models",
|
||||
"!matrix-js-sdk/src/models/read-receipt",
|
||||
"!matrix-js-sdk/src/models/relations-container",
|
||||
"!matrix-js-sdk/src/models/related-relations",
|
||||
"!matrix-js-sdk/src/matrixrtc",
|
||||
],
|
||||
message: "Please use matrix-js-sdk/src/matrix instead",
|
||||
},
|
||||
{
|
||||
group: ["emojibase-regex/emoji*"],
|
||||
message:
|
||||
"This regex doesn't actually test for emoji. See the docs at https://emojibase.dev/docs/regex/ and prefer our own EMOJI_REGEX from HtmlUtils.",
|
||||
},
|
||||
{
|
||||
group: ["@vector-im/compound-design-tokens/icons/*"],
|
||||
message: "Please use @vector-im/compound-design-tokens/assets/web/icons/* instead",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
|
||||
// There are too many a11y violations to fix at once
|
||||
// Turn violated rules off until they are fixed
|
||||
"jsx-a11y/aria-activedescendant-has-tabindex": "off",
|
||||
"jsx-a11y/click-events-have-key-events": "off",
|
||||
"jsx-a11y/interactive-supports-focus": "off",
|
||||
"jsx-a11y/media-has-caption": "off",
|
||||
"jsx-a11y/mouse-events-have-key-events": "off",
|
||||
"jsx-a11y/no-autofocus": "off",
|
||||
"jsx-a11y/no-noninteractive-element-interactions": "off",
|
||||
"jsx-a11y/no-noninteractive-element-to-interactive-role": "off",
|
||||
"jsx-a11y/no-noninteractive-tabindex": "off",
|
||||
"jsx-a11y/no-static-element-interactions": "off",
|
||||
"jsx-a11y/role-supports-aria-props": "off",
|
||||
|
||||
"matrix-org/require-copyright-header": "error",
|
||||
},
|
||||
overrides: [
|
||||
{
|
||||
files: ["src/**/*.{ts,tsx}", "test/**/*.{ts,tsx}", "playwright/**/*.ts"],
|
||||
extends: ["plugin:matrix-org/typescript", "plugin:matrix-org/react"],
|
||||
rules: {
|
||||
"@typescript-eslint/explicit-function-return-type": [
|
||||
"error",
|
||||
{
|
||||
allowExpressions: true,
|
||||
},
|
||||
],
|
||||
|
||||
// Things we do that break the ideal style
|
||||
"prefer-promise-reject-errors": "off",
|
||||
"no-extra-boolean-cast": "off",
|
||||
|
||||
// Remove Babel things manually due to override limitations
|
||||
"@babel/no-invalid-this": ["off"],
|
||||
|
||||
// We're okay being explicit at the moment
|
||||
"@typescript-eslint/no-empty-interface": "off",
|
||||
// We disable this while we're transitioning
|
||||
"@typescript-eslint/no-explicit-any": "off",
|
||||
// We'd rather not do this but we do
|
||||
"@typescript-eslint/ban-ts-comment": "off",
|
||||
// We're okay with assertion errors when we ask for them
|
||||
"@typescript-eslint/no-non-null-assertion": "off",
|
||||
},
|
||||
},
|
||||
}],
|
||||
// temporary override for offending icon require files
|
||||
{
|
||||
files: [
|
||||
"src/SdkConfig.ts",
|
||||
"src/components/structures/FileDropTarget.tsx",
|
||||
"src/components/structures/RoomStatusBar.tsx",
|
||||
"src/components/structures/UserMenu.tsx",
|
||||
"src/components/views/avatars/WidgetAvatar.tsx",
|
||||
"src/components/views/dialogs/AddExistingToSpaceDialog.tsx",
|
||||
"src/components/views/dialogs/ForwardDialog.tsx",
|
||||
"src/components/views/dialogs/InviteDialog.tsx",
|
||||
"src/components/views/dialogs/ModalWidgetDialog.tsx",
|
||||
"src/components/views/dialogs/UploadConfirmDialog.tsx",
|
||||
"src/components/views/dialogs/security/SetupEncryptionDialog.tsx",
|
||||
"src/components/views/elements/AddressTile.tsx",
|
||||
"src/components/views/elements/AppWarning.tsx",
|
||||
"src/components/views/elements/SSOButtons.tsx",
|
||||
"src/components/views/messages/MAudioBody.tsx",
|
||||
"src/components/views/messages/MImageBody.tsx",
|
||||
"src/components/views/messages/MFileBody.tsx",
|
||||
"src/components/views/messages/MStickerBody.tsx",
|
||||
"src/components/views/messages/MVideoBody.tsx",
|
||||
"src/components/views/messages/MVoiceMessageBody.tsx",
|
||||
"src/components/views/right_panel/EncryptionPanel.tsx",
|
||||
"src/components/views/rooms/EntityTile.tsx",
|
||||
"src/components/views/rooms/LinkPreviewGroup.tsx",
|
||||
"src/components/views/rooms/MemberList.tsx",
|
||||
"src/components/views/rooms/MessageComposer.tsx",
|
||||
"src/components/views/rooms/ReplyPreview.tsx",
|
||||
"src/components/views/settings/tabs/room/SecurityRoomSettingsTab.tsx",
|
||||
"src/components/views/settings/tabs/user/GeneralUserSettingsTab.tsx",
|
||||
],
|
||||
rules: {
|
||||
"@typescript-eslint/no-var-requires": "off",
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ["test/**/*.{ts,tsx}", "playwright/**/*.ts"],
|
||||
extends: ["plugin:matrix-org/jest"],
|
||||
rules: {
|
||||
// We don't need super strict typing in test utilities
|
||||
"@typescript-eslint/explicit-function-return-type": "off",
|
||||
"@typescript-eslint/explicit-member-accessibility": "off",
|
||||
|
||||
// Jest/Playwright specific
|
||||
|
||||
// Disabled tests are a reality for now but as soon as all of the xits are
|
||||
// eliminated, we should enforce this.
|
||||
"jest/no-disabled-tests": "off",
|
||||
// Also treat "oldBackendOnly" as a test function.
|
||||
// Used in some crypto tests.
|
||||
"jest/no-standalone-expect": [
|
||||
"error",
|
||||
{
|
||||
additionalTestBlockFunctions: ["beforeAll", "beforeEach", "oldBackendOnly"],
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ["playwright/**/*.ts"],
|
||||
parserOptions: {
|
||||
project: ["./playwright/tsconfig.json"],
|
||||
},
|
||||
},
|
||||
],
|
||||
settings: {
|
||||
react: {
|
||||
version: "detect",
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
function buildRestrictedPropertiesOptions(properties, message) {
|
||||
return properties.map((prop) => {
|
||||
let [object, property] = prop.split(".");
|
||||
if (object === "*") {
|
||||
object = undefined;
|
||||
}
|
||||
return {
|
||||
object,
|
||||
property,
|
||||
message,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
3
.git-blame-ignore-revs
Normal file
3
.git-blame-ignore-revs
Normal file
@@ -0,0 +1,3 @@
|
||||
# prettier
|
||||
526645c79160ab1ad4b4c3845de27d51263a405e
|
||||
7921a6cbf86b035d2b0c1daecb4c24beaf5a5abc
|
||||
18
.github/CODEOWNERS
vendored
Normal file
18
.github/CODEOWNERS
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
* @element-hq/element-web-reviewers
|
||||
/.github/workflows/** @element-hq/element-web-team
|
||||
/package.json @element-hq/element-web-team
|
||||
/yarn.lock @element-hq/element-web-team
|
||||
|
||||
/src/SecurityManager.ts @element-hq/element-crypto-web-reviewers
|
||||
/test/SecurityManager-test.ts @element-hq/element-crypto-web-reviewers
|
||||
/src/async-components/views/dialogs/security/ @element-hq/element-crypto-web-reviewers
|
||||
/src/components/views/dialogs/security/ @element-hq/element-crypto-web-reviewers
|
||||
/test/components/views/dialogs/security/ @element-hq/element-crypto-web-reviewers
|
||||
/src/stores/SetupEncryptionStore.ts @element-hq/element-crypto-web-reviewers
|
||||
/test/stores/SetupEncryptionStore-test.ts @element-hq/element-crypto-web-reviewers
|
||||
|
||||
# Ignore translations as those will be updated by GHA for Localazy download
|
||||
/src/i18n/strings
|
||||
# Ignore the synapse plugin as this is updated by GHA for docker image updating
|
||||
/playwright/plugins/homeserver/synapse/index.ts
|
||||
|
||||
48
.github/ISSUE_TEMPLATE.md
vendored
48
.github/ISSUE_TEMPLATE.md
vendored
@@ -1,48 +0,0 @@
|
||||
<!-- A picture's worth a thousand words: PLEASE INCLUDE A SCREENSHOT :P -->
|
||||
|
||||
<!-- Please report security issues by email to security@matrix.org -->
|
||||
|
||||
<!-- This is a bug report template. By following the instructions below and
|
||||
filling out the sections with your information, you will help the us to get all
|
||||
the necessary data to fix your issue.
|
||||
|
||||
You can also preview your report before submitting it. You may remove sections
|
||||
that aren't relevant to your particular case.
|
||||
|
||||
Text between <!-- and --> marks will be invisible in the report.
|
||||
-->
|
||||
|
||||
#### Description
|
||||
|
||||
Describe here the problem that you are experiencing, or the feature you are requesting.
|
||||
|
||||
#### Steps to reproduce
|
||||
|
||||
- For bugs, list the steps
|
||||
- that reproduce the bug
|
||||
- using hyphens as bullet points
|
||||
|
||||
Describe how what happens differs from what you expected.
|
||||
|
||||
Log: sent/not sent? <!-- You can send us the app's logs via the 'Report bug'
|
||||
link on the 'Settings' page. Very important for hard-to-reproduce bugs. Please
|
||||
file a bug here too! -->
|
||||
|
||||
<!-- Include screenshots if possible: you can drag and drop images below. -->
|
||||
|
||||
#### Version information
|
||||
|
||||
<!-- IMPORTANT: please answer the following questions, to help us narrow down the problem -->
|
||||
|
||||
- **Platform**: web (in-browser) or desktop?
|
||||
|
||||
For the web app:
|
||||
|
||||
- **Browser**: Chrome, Firefox, Safari, Edge? which version?
|
||||
- **OS**: Windows, macOS, Ubuntu, Arch Linux, etc?
|
||||
- **URL**: develop.element.io / app.element.io / somewhere else? If a private server, what version of Element Web?
|
||||
|
||||
For the desktop app:
|
||||
|
||||
- **OS**: Windows, macOS, Ubuntu, Arch Linux, etc?
|
||||
- **Version**: 1.x.y <!-- check the user settings panel if unsure -->
|
||||
76
.github/ISSUE_TEMPLATE/bug-desktop.yml
vendored
Normal file
76
.github/ISSUE_TEMPLATE/bug-desktop.yml
vendored
Normal file
@@ -0,0 +1,76 @@
|
||||
name: Bug report for the Element desktop app (not in a browser)
|
||||
description: File a bug report if you are using the desktop Element application.
|
||||
labels: [T-Defect]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Thanks for taking the time to fill out this bug report!
|
||||
|
||||
Please report security issues by email to security@matrix.org
|
||||
- type: textarea
|
||||
id: reproduction-steps
|
||||
attributes:
|
||||
label: Steps to reproduce
|
||||
description: Please attach screenshots, videos or logs if you can.
|
||||
placeholder: Tell us what you see!
|
||||
value: |
|
||||
1. Where are you starting? What can you see?
|
||||
2. What do you click?
|
||||
3. More steps…
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: result
|
||||
attributes:
|
||||
label: Outcome
|
||||
placeholder: Tell us what went wrong
|
||||
value: |
|
||||
#### What did you expect?
|
||||
|
||||
#### What happened instead?
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: os
|
||||
attributes:
|
||||
label: Operating system
|
||||
placeholder: Windows, macOS, Ubuntu, Arch Linux…
|
||||
validations:
|
||||
required: false
|
||||
- type: input
|
||||
id: version
|
||||
attributes:
|
||||
label: Application version
|
||||
description: You can find the version information in Settings -> Help & About.
|
||||
placeholder: e.g. Element version 1.7.34, olm version 3.2.3
|
||||
validations:
|
||||
required: false
|
||||
- type: input
|
||||
id: source
|
||||
attributes:
|
||||
label: How did you install the app?
|
||||
description: Where did you install the app from? Please give a link or a description.
|
||||
placeholder: e.g. From https://element.io/get-started
|
||||
validations:
|
||||
required: false
|
||||
- type: input
|
||||
id: homeserver
|
||||
attributes:
|
||||
label: Homeserver
|
||||
description: |
|
||||
Which server is your account registered on? If it is a local or non-public homeserver, please tell us what is the homeserver implementation (ex: Synapse/Dendrite/etc.) and the version.
|
||||
placeholder: e.g. matrix.org or Synapse 1.50.0rc1
|
||||
validations:
|
||||
required: false
|
||||
- type: dropdown
|
||||
id: rageshake
|
||||
attributes:
|
||||
label: Will you send logs?
|
||||
description: |
|
||||
Did you know that you can send a /rageshake command from your application to submit logs for this issue? Trigger the defect, then type `/rageshake` into the message input area followed by a description of the problem and send the command. You will be able to add a link to this defect report and submit anonymous logs to the developers.
|
||||
options:
|
||||
- "Yes"
|
||||
- "No"
|
||||
validations:
|
||||
required: true
|
||||
84
.github/ISSUE_TEMPLATE/bug-web.yml
vendored
Normal file
84
.github/ISSUE_TEMPLATE/bug-web.yml
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
name: Bug report for Element Web (in browser)
|
||||
description: File a bug report if you are using Element in a web browser like Firefox, Chrome, Edge, and so on.
|
||||
labels: [T-Defect]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Thanks for taking the time to fill out this bug report!
|
||||
|
||||
Please report security issues by email to security@matrix.org
|
||||
- type: textarea
|
||||
id: reproduction-steps
|
||||
attributes:
|
||||
label: Steps to reproduce
|
||||
description: Please attach screenshots, videos or logs if you can.
|
||||
placeholder: Tell us what you see!
|
||||
value: |
|
||||
1. Where are you starting? What can you see?
|
||||
2. What do you click?
|
||||
3. More steps…
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: result
|
||||
attributes:
|
||||
label: Outcome
|
||||
placeholder: Tell us what went wrong
|
||||
value: |
|
||||
#### What did you expect?
|
||||
|
||||
#### What happened instead?
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: os
|
||||
attributes:
|
||||
label: Operating system
|
||||
placeholder: Windows, macOS, Ubuntu, Arch Linux…
|
||||
validations:
|
||||
required: false
|
||||
- type: input
|
||||
id: browser
|
||||
attributes:
|
||||
label: Browser information
|
||||
description: Which browser are you using? Which version?
|
||||
placeholder: e.g. Chromium Version 92.0.4515.131
|
||||
validations:
|
||||
required: false
|
||||
- type: input
|
||||
id: webapp-url
|
||||
attributes:
|
||||
label: URL for webapp
|
||||
description: Which URL are you using to access the webapp? If a private server, tell us what version of Element Web you are using.
|
||||
placeholder: e.g. develop.element.io, app.element.io
|
||||
validations:
|
||||
required: false
|
||||
- type: input
|
||||
id: version
|
||||
attributes:
|
||||
label: Application version
|
||||
description: You can find the version information in Settings -> Help & About.
|
||||
placeholder: e.g. Element version 1.7.34, olm version 3.2.3
|
||||
validations:
|
||||
required: false
|
||||
- type: input
|
||||
id: homeserver
|
||||
attributes:
|
||||
label: Homeserver
|
||||
description: |
|
||||
Which server is your account registered on? If it is a local or non-public homeserver, please tell us what is the homeserver implementation (ex: Synapse/Dendrite/etc.) and the version.
|
||||
placeholder: e.g. matrix.org or Synapse 1.50.0rc1
|
||||
validations:
|
||||
required: false
|
||||
- type: dropdown
|
||||
id: rageshake
|
||||
attributes:
|
||||
label: Will you send logs?
|
||||
description: |
|
||||
Did you know that you can send a /rageshake command from the web application to submit logs for this issue? Trigger the defect, then type `/rageshake` into the message input area followed by a description of the problem and send the command. You will be able to add a link to this defect report and submit anonymous logs to the developers.
|
||||
options:
|
||||
- "Yes"
|
||||
- "No"
|
||||
validations:
|
||||
required: true
|
||||
58
.github/ISSUE_TEMPLATE/bug_report.md
vendored
58
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -1,58 +0,0 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: ''
|
||||
labels: T-Defect
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
<!-- A picture's worth a thousand words: PLEASE INCLUDE A SCREENSHOT :P -->
|
||||
|
||||
<!-- Please report security issues by email to security@matrix.org -->
|
||||
|
||||
<!-- This is a bug report template. By following the instructions below and
|
||||
filling out the sections with your information, you will help the us to get all
|
||||
the necessary data to fix your issue.
|
||||
|
||||
You can also preview your report before submitting it. You may remove sections
|
||||
that aren't relevant to your particular case.
|
||||
|
||||
Text between <!-- and --> marks will be invisible in the report.
|
||||
-->
|
||||
|
||||
#### Description
|
||||
|
||||
Describe here the problem that you are experiencing, or the feature you are requesting.
|
||||
|
||||
#### Steps to reproduce
|
||||
|
||||
- For bugs, list the steps
|
||||
- that reproduce the bug
|
||||
- using hyphens as bullet points
|
||||
|
||||
Describe how what happens differs from what you expected.
|
||||
|
||||
<!-- Please send us logs for your bug report. They're very important for bugs
|
||||
which are hard to reproduce. To do this, create this issue then go to your
|
||||
account settings and click 'Submit Debug Logs' from the Help & About tab -->
|
||||
Logs being sent: yes/no
|
||||
|
||||
<!-- Include screenshots if possible: you can drag and drop images below. -->
|
||||
|
||||
#### Version information
|
||||
|
||||
<!-- IMPORTANT: please answer the following questions, to help us narrow down the problem -->
|
||||
|
||||
- **Platform**: web (in-browser) or desktop?
|
||||
|
||||
For the web app:
|
||||
|
||||
- **Browser**: Chrome, Firefox, Safari, Edge? which version?
|
||||
- **OS**: Windows, macOS, Ubuntu, Arch Linux, etc?
|
||||
- **URL**: develop.element.io / app.element.io / somewhere else? If a private server, what version of Element Web?
|
||||
|
||||
For the desktop app:
|
||||
|
||||
- **OS**: Windows, macOS, Ubuntu, Arch Linux, etc?
|
||||
- **Version**: 1.x.y <!-- check the user settings panel if unsure -->
|
||||
5
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
5
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: Questions & support
|
||||
url: https://matrix.to/#/#element-web:matrix.org
|
||||
about: Please ask and answer questions here.
|
||||
36
.github/ISSUE_TEMPLATE/enhancement.yml
vendored
Normal file
36
.github/ISSUE_TEMPLATE/enhancement.yml
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
name: Enhancement request
|
||||
description: Do you have a suggestion or feature request?
|
||||
labels: [T-Enhancement]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Thank you for taking the time to propose an enhancement to an existing feature. If you would like to propose a new feature or a major cross-platform change, please [start a discussion here](https://github.com/element-hq/element-meta/discussions/new?category=ideas).
|
||||
- type: textarea
|
||||
id: usecase
|
||||
attributes:
|
||||
label: Your use case
|
||||
description: What would you like to be able to do? Please feel welcome to include screenshots or mock ups.
|
||||
placeholder: Tell us what you would like to do!
|
||||
value: |
|
||||
#### What would you like to do?
|
||||
|
||||
#### Why would you like to do it?
|
||||
|
||||
#### How would you like to achieve it?
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: alternative
|
||||
attributes:
|
||||
label: Have you considered any alternatives?
|
||||
placeholder: A clear and concise description of any alternative solutions or features you've considered.
|
||||
validations:
|
||||
required: false
|
||||
- type: textarea
|
||||
id: additional-context
|
||||
attributes:
|
||||
label: Additional context
|
||||
placeholder: Is there anything else you'd like to add?
|
||||
validations:
|
||||
required: false
|
||||
@@ -1,20 +0,0 @@
|
||||
---
|
||||
name: Suggestion or Feature request
|
||||
about: Suggest an idea for this project
|
||||
title: ''
|
||||
labels: T-Enhancement
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
#### Is your suggestion related to a problem? Please describe.
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
#### Describe the solution you'd like.
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
#### Describe alternatives you've considered.
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
|
||||
#### Additional context
|
||||
Add any other context or screenshots about the feature request here.
|
||||
15
.github/PULL_REQUEST_TEMPLATE.md
vendored
15
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -1,11 +1,8 @@
|
||||
<!-- Please read https://github.com/matrix-org/matrix-js-sdk/blob/develop/CONTRIBUTING.md before submitting your pull request -->
|
||||
<!-- Thanks for submitting a PR! Please ensure the following requirements are met in order for us to review your PR -->
|
||||
|
||||
<!-- Include a Sign-Off as described in https://github.com/matrix-org/matrix-js-sdk/blob/develop/CONTRIBUTING.md#sign-off -->
|
||||
## Checklist
|
||||
|
||||
<!-- To specify text for the changelog entry (otherwise the PR title will be used):
|
||||
Notes:
|
||||
|
||||
Changelog entries will also appear in element-desktop. For PRs that *only* affect the desktop version:
|
||||
Notes: none
|
||||
element-desktop notes: <notes>
|
||||
-->
|
||||
- [ ] Tests written for new code (and old code if feasible).
|
||||
- [ ] New or updated `public`/`exported` symbols have accurate [TSDoc](https://tsdoc.org/) documentation.
|
||||
- [ ] Linter and other CI checks pass.
|
||||
- [ ] I have licensed the changes to Element by completing the [Contributor License Agreement (CLA)](https://cla-assistant.io/element-hq/element-web)
|
||||
|
||||
16
.github/cfp_headers
vendored
Normal file
16
.github/cfp_headers
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
! Access-Control-Allow-Origin
|
||||
X-XSS-Protection: 1; mode=block
|
||||
X-Content-Type-Options: nosniff
|
||||
X-Frame-Options: SAMEORIGIN
|
||||
Content-Security-Policy: frame-ancestors 'self'
|
||||
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
|
||||
|
||||
/version
|
||||
Content-Type: text/plain
|
||||
|
||||
/apple-app-site-association
|
||||
Content-Type: application/json
|
||||
|
||||
/.well-known/assetlinks.json
|
||||
Content-Type: application/json
|
||||
266
.github/labels.yml
vendored
Normal file
266
.github/labels.yml
vendored
Normal file
@@ -0,0 +1,266 @@
|
||||
- name: "A-Aliases"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Authentication"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Autocomplete"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Breadcrumbs"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Bridge"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Broadcast"
|
||||
description: "Broadcast-style voice messages"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Create-Room"
|
||||
description: "Create room flow, user suggestions, etc."
|
||||
color: "bfd4f2"
|
||||
- name: "A-DevTools"
|
||||
description: "/devtools, show hidden events, etc."
|
||||
color: "bfd4f2"
|
||||
- name: "A-Dialogs"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Disambiguation"
|
||||
color: "bfd4f2"
|
||||
- name: "A-DM-Start"
|
||||
description: "Creating a DM with another user"
|
||||
color: "bfd4f2"
|
||||
- name: "A-E2EE-Dehydration"
|
||||
color: "8CC59A"
|
||||
- name: "A-Electron"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Element-Call"
|
||||
description: "Group calls via Element Call"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Element-R"
|
||||
description: "Issues affecting the port of Element's crypto layer to Rust"
|
||||
color: "bfd4f2"
|
||||
- name: "A-ELS"
|
||||
description: "Event List Summary (and Membership ELS, MELS)"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Emotes"
|
||||
color: "bfd4f2"
|
||||
- name: "A-EMS"
|
||||
description: "Issues related to EMS"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Error-Message"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Federation"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Feedback-Reporting"
|
||||
description: "Reporting process for bugs, debug logs (rageshakes), suggestions"
|
||||
color: "bfd4f2"
|
||||
- name: "A-File-Download"
|
||||
color: "bfd4f2"
|
||||
- name: "A-File-Panel"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Identity-Server"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Indexing"
|
||||
description: "Indexing messages via Seshat"
|
||||
color: "bfd4f2"
|
||||
- name: "A-IRC-Layout"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Jump-To-Date"
|
||||
description: "Jump to date headers or slash command"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Lazy-Loading"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Light-Box"
|
||||
description: "UI when viewing an image"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Location-Sharing"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Logout"
|
||||
description: "Logout, sign out, etc."
|
||||
color: "bfd4f2"
|
||||
- name: "A-Maths"
|
||||
description: "Render LaTeX maths in messages"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Memory"
|
||||
description: "Memory leaks, leak hunting tools"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Message-Forwarding"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Message-Pinning"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Message-Previews"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Message-Starring"
|
||||
description: "Saving favourite messages for later"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Modules"
|
||||
description: "Module system related"
|
||||
color: "bfd4f2"
|
||||
- name: "A-New-Search-Experience"
|
||||
description: "The new search dialog available in Labs"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Packaging"
|
||||
description: "Packaging, signing, releasing"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Peeking"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Picture-in-Picture"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Power-Levels"
|
||||
description: "The permissions that users have in rooms and spaces"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Replies"
|
||||
description: "reply"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Session-Mgmt"
|
||||
description: "Session / device names, management UI, etc."
|
||||
color: "bfd4f2"
|
||||
- name: "A-Share"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Shortcuts"
|
||||
description: "Keyboard shortcuts"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Sliding-Sync"
|
||||
description: "Also known as Sync v3 - https://github.com/matrix-org/sliding-sync"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Soft-Logout"
|
||||
description: "https://github.com/element-hq/element-web/issues/10224"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Spaces-Settings"
|
||||
color: "bfd4f2"
|
||||
- name: "A-SSO"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Status-Bar"
|
||||
description: "Unsent messages warning and 'Connectivity to the server has been lost'"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Storage"
|
||||
description: "Storage layer of the app, including IndexedDB, local storage, etc."
|
||||
color: "bfd4f2"
|
||||
- name: "A-Technical-Debt"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Testing"
|
||||
description: "Testing, code coverage, etc."
|
||||
color: "bfd4f2"
|
||||
- name: "A-Themes-Custom"
|
||||
description: "Custom theme variables or support"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Themes-Official"
|
||||
description: "Official themes (light, dark)"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Theming"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Timeline-Jumpy-Scroll"
|
||||
description: "Stable timeline dream ✨"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Timesheet-1"
|
||||
description: "Log any time spent on this into the A-Timesheet-1 project"
|
||||
color: "5319E7"
|
||||
- name: "A-Toast"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Tooltips"
|
||||
description: "Anything related to tooltips"
|
||||
color: "bfd4f2"
|
||||
- name: "A-UI-Customisation"
|
||||
description: "UIFeatures etc. for customising entire parts of the UI"
|
||||
color: "bfd4f2"
|
||||
- name: "A-URL-Previews"
|
||||
color: "bfd4f2"
|
||||
- name: "A-User-Menu"
|
||||
description: "The top left main menu with the user's name and avatar"
|
||||
color: "bfd4f2"
|
||||
- name: "A-User-Search"
|
||||
description: "The start DM or invite to room dialogs (things dealing with `/user_directory/search`)"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Video-Rooms"
|
||||
description: "Persistent group calls"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Voice-Messages"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Welcome-Page"
|
||||
color: "bfd4f2"
|
||||
- name: "backport staging"
|
||||
description: "Label to automatically backport PR to staging branch"
|
||||
color: "B60205"
|
||||
- name: "Dependencies"
|
||||
description: "Pull requests that update a dependency file"
|
||||
color: "0366d6"
|
||||
- name: "Hacktoberfest"
|
||||
description: "Issues which are suitable for Hacktoberfest PRs: https://hacktoberfest.digitalocean.com/"
|
||||
color: "ff7518"
|
||||
- name: "P4"
|
||||
description: "[OBSOLETE LABEL] Interesting — Not yet scheduled, will accept patches"
|
||||
color: "d1e5f0"
|
||||
- name: "spam"
|
||||
color: "B60205"
|
||||
- name: "Sponsored"
|
||||
color: "ffc8f4"
|
||||
- name: "T-Deprecation"
|
||||
description: "A pull request that makes something deprecated"
|
||||
color: "98e6ae"
|
||||
- name: "T-Other"
|
||||
description: "Questions, user support, anything else"
|
||||
color: "98e6ae"
|
||||
- name: "Team: App"
|
||||
color: "FFA500"
|
||||
- name: "X-Blocked"
|
||||
color: "ff7979"
|
||||
- name: "X-Cannot-Reproduce"
|
||||
color: "ff7979"
|
||||
- name: "X-Command"
|
||||
description: "Created using the !github command"
|
||||
color: "ff7979"
|
||||
- name: "X-Community-Supported-Platform"
|
||||
description: "This issue occurs in a platform not directly supported by us, but by a community project elsewhere"
|
||||
color: "ff7979"
|
||||
- name: "X-Upcoming-Release-Blocker"
|
||||
description: "This does not affect the current release cycle but will affect the next one"
|
||||
color: "e99695"
|
||||
- name: "Z-Actions"
|
||||
color: "ededed"
|
||||
- name: "Z-Cache-Confusion"
|
||||
description: "Related to internal cache (clearing helps / causes the issue)"
|
||||
color: "ededed"
|
||||
- name: "Z-Community-PR"
|
||||
description: "Issue is solved by a community member's PR"
|
||||
color: "ededed"
|
||||
- name: "Z-Element-R-Blocker"
|
||||
description: "A blocker for enabling Element R by default"
|
||||
color: "ededed"
|
||||
- name: "Z-Experimental"
|
||||
color: "ededed"
|
||||
- name: "Z-Fixed by Element Call"
|
||||
description: "Issues which can be closed when we move to Element Call"
|
||||
color: "ededed"
|
||||
- name: "Z-Fixed-By-OIDC"
|
||||
description: "Issues which can be closed when we move to OIDC"
|
||||
color: "ededed"
|
||||
- name: "Z-Flaky-Test"
|
||||
description: "A test is raising false alarms"
|
||||
color: "ededed"
|
||||
- name: "Z-FOSDEM"
|
||||
description: "Issues in chat.fosdem.org"
|
||||
color: "ededed"
|
||||
- name: "Z-Gitter"
|
||||
description: "Issues relating to or coming out of the Gitter migration, feature parity, etc"
|
||||
color: "ededed"
|
||||
- name: "Z-Legacy-Crypto"
|
||||
description: "Issues affecting the legacy crypto stack"
|
||||
color: "EEEEEE"
|
||||
- name: "Z-Maximised-Widgets"
|
||||
color: "ededed"
|
||||
- name: "Z-Papercuts"
|
||||
description: "Visible. Impactful. Predictable to action."
|
||||
color: "ededed"
|
||||
- name: "Z-Power-Users"
|
||||
color: "ededed"
|
||||
- name: "Z-Rageshake"
|
||||
description: "Has attached rageshake (not for log submission process)"
|
||||
color: "ededed"
|
||||
- name: "Z-RICE"
|
||||
color: "ededed"
|
||||
- name: "Z-Soft-Crash"
|
||||
description: "React soft crash caught by an error boundary"
|
||||
color: "ededed"
|
||||
- name: "Z-Spec-Compliance"
|
||||
description: "An area where Element doesn't correctly implement the spec"
|
||||
color: "ededed"
|
||||
- name: "Z-t3chguy"
|
||||
color: "ededed"
|
||||
- name: "Z-Flaky-Test-Disabled"
|
||||
description: "The flaking test has been disabled"
|
||||
color: "ededed"
|
||||
3
.github/release-drafter.yml
vendored
Normal file
3
.github/release-drafter.yml
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
_extends: matrix-org/matrix-js-sdk
|
||||
version-resolver:
|
||||
default: patch
|
||||
4
.github/renovate.json
vendored
Normal file
4
.github/renovate.json
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
|
||||
"extends": ["github>matrix-org/renovate-config-element-web"]
|
||||
}
|
||||
30
.github/workflows/backport.yml
vendored
Normal file
30
.github/workflows/backport.yml
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
name: Backport
|
||||
on:
|
||||
pull_request_target:
|
||||
types:
|
||||
- closed
|
||||
- labeled
|
||||
branches:
|
||||
- develop
|
||||
|
||||
jobs:
|
||||
backport:
|
||||
name: Backport
|
||||
runs-on: ubuntu-latest
|
||||
# Only react to merged PRs for security reasons.
|
||||
# See https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request_target.
|
||||
if: >
|
||||
github.event.pull_request.merged
|
||||
&& (
|
||||
github.event.action == 'closed'
|
||||
|| (
|
||||
github.event.action == 'labeled'
|
||||
&& contains(github.event.label.name, 'backport')
|
||||
)
|
||||
)
|
||||
steps:
|
||||
- uses: tibdex/backport@9565281eda0731b1d20c4025c43339fb0a23812e # v2
|
||||
with:
|
||||
labels_template: "<%= JSON.stringify([...labels, 'X-Release-Blocker']) %>"
|
||||
# We can't use GITHUB_TOKEN here or CI won't run on the new PR
|
||||
github_token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
49
.github/workflows/build.yml
vendored
Normal file
49
.github/workflows/build.yml
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
name: Build
|
||||
on:
|
||||
pull_request: {}
|
||||
push:
|
||||
branches: [develop, master]
|
||||
merge_group:
|
||||
types: [checks_requested]
|
||||
# develop pushes and repository_dispatch handled in build_develop.yaml
|
||||
env:
|
||||
# These must be set for fetchdep.sh to get the right branch
|
||||
REPOSITORY: ${{ github.repository }}
|
||||
PR_NUMBER: ${{ github.event.pull_request.number }}
|
||||
jobs:
|
||||
build:
|
||||
name: "Build on ${{ matrix.image }}"
|
||||
# We build on all 3 platforms to ensure we don't have any OS-specific build incompatibilities
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
image:
|
||||
- ubuntu-latest
|
||||
- windows-latest
|
||||
- macos-latest
|
||||
isDevelop:
|
||||
- ${{ github.event_name == 'push' && github.ref_name == 'develop' }}
|
||||
# Skip the ubuntu-latest build for the develop branch as the dedicated CD build_develop workflow handles that
|
||||
exclude:
|
||||
- isDevelop: true
|
||||
image: ubuntu-latest
|
||||
runs-on: ${{ matrix.image }}
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
cache: "yarn"
|
||||
node-version: "lts/*"
|
||||
|
||||
# Workaround for yarn install timeouts, especially on Windows
|
||||
- run: yarn config set network-timeout 300000
|
||||
|
||||
- name: Install Dependencies
|
||||
run: "./scripts/layered.sh"
|
||||
|
||||
- name: Build
|
||||
run: "yarn build"
|
||||
78
.github/workflows/build_debian.yaml
vendored
Normal file
78
.github/workflows/build_debian.yaml
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
name: Build Debian package
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
concurrency: ${{ github.workflow }}
|
||||
jobs:
|
||||
build:
|
||||
name: Build package
|
||||
environment: packages.element.io
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
R2_INCOMING_BUCKET: ${{ vars.R2_INCOMING_BUCKET }}
|
||||
R2_URL: ${{ vars.CF_R2_S3_API }}
|
||||
VERSION: ${{ github.ref_name }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Download package
|
||||
run: |
|
||||
wget "https://github.com/element-hq/element-web/releases/download/$VERSION/element-$VERSION.tar.gz"
|
||||
wget "https://github.com/element-hq/element-web/releases/download/$VERSION/element-$VERSION.tar.gz.asc"
|
||||
|
||||
- name: Check GPG signature
|
||||
run: |
|
||||
wget "https://packages.element.io/element-release-key.gpg"
|
||||
gpg --import element-release-key.gpg
|
||||
gpg --fingerprint "$FINGERPRINT"
|
||||
gpg --verify "element-$VERSION.tar.gz.asc" "element-$VERSION.tar.gz"
|
||||
env:
|
||||
FINGERPRINT: ${{ vars.GPG_FINGERPRINT }}
|
||||
|
||||
- name: Prepare
|
||||
run: |
|
||||
mkdir -p debian/tmp/DEBIAN
|
||||
find debian -maxdepth 1 -type f -exec cp "{}" debian/tmp/DEBIAN/ \;
|
||||
mkdir -p debian/tmp/usr/share/element-web/ debian/tmp/etc/element-web/
|
||||
|
||||
tar -xf "element-$VERSION.tar.gz" -C debian/tmp/usr/share/element-web --strip-components=1 --no-same-owner --no-same-permissions
|
||||
mv debian/tmp/usr/share/element-web/config.sample.json debian/tmp/etc/element-web/config.json
|
||||
ln -s /etc/element-web/config.json debian/tmp/usr/share/element-web/config.json
|
||||
|
||||
- name: Write changelog
|
||||
run: |
|
||||
VERSION=$(cat package.json | jq -r .version)
|
||||
TIME=$(date -d "$PUBLISHED_AT" -R)
|
||||
{
|
||||
echo "element-web ($VERSION) default; urgency=medium"
|
||||
echo "$BODY" | sed 's/^##/\n */g;s/^\*/ */g' | perl -pe 's/\[.+?]\((.+?)\)/\1/g'
|
||||
echo ""
|
||||
echo " -- $ACTOR <support@element.io> $TIME"
|
||||
} > debian/tmp/DEBIAN/changelog
|
||||
env:
|
||||
ACTOR: ${{ github.actor }}
|
||||
VERSION: ${{ github.event.release.tag_name }}
|
||||
BODY: ${{ github.event.release.body }}
|
||||
PUBLISHED_AT: ${{ github.event.release.published_at }}
|
||||
|
||||
- name: Build deb package
|
||||
run: |
|
||||
VERSION=$(cat package.json | jq -r .version)
|
||||
dpkg-gencontrol -v"$VERSION" -ldebian/tmp/DEBIAN/changelog
|
||||
dpkg-deb -Zxz --root-owner-group --build debian/tmp element-web.deb
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: element-web.deb
|
||||
path: element-web.deb
|
||||
retention-days: 14
|
||||
|
||||
- name: Publish to packages.element.io
|
||||
if: github.event.release.prerelease == false
|
||||
uses: element-hq/packages.element.io@master
|
||||
with:
|
||||
file: element-web.deb
|
||||
github-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
bucket-api: ${{ vars.CF_R2_S3_API }}
|
||||
bucket-key-id: ${{ secrets.CF_R2_ACCESS_KEY_ID }}
|
||||
bucket-access-key: ${{ secrets.CF_R2_TOKEN }}
|
||||
126
.github/workflows/build_develop.yml
vendored
Normal file
126
.github/workflows/build_develop.yml
vendored
Normal file
@@ -0,0 +1,126 @@
|
||||
# Separate to the main build workflow for access to develop
|
||||
# environment secrets, largely similar to build.yaml.
|
||||
name: Build and Deploy develop
|
||||
on:
|
||||
push:
|
||||
branches: [develop]
|
||||
repository_dispatch:
|
||||
types: [element-web-notify]
|
||||
concurrency:
|
||||
group: ${{ github.repository_owner }}-${{ github.workflow }}-${{ github.ref_name }}
|
||||
cancel-in-progress: true
|
||||
jobs:
|
||||
build:
|
||||
name: "Build & Deploy develop.element.io"
|
||||
# Only respect triggers from our develop branch, ignore that of forks
|
||||
if: github.repository == 'element-hq/element-web'
|
||||
runs-on: ubuntu-latest
|
||||
environment: develop
|
||||
env:
|
||||
R2_BUCKET: "element-web-develop"
|
||||
R2_URL: ${{ vars.CF_R2_S3_API }}
|
||||
R2_PUBLIC_URL: "https://element-web-develop.element.io"
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
cache: "yarn"
|
||||
node-version: "lts/*"
|
||||
|
||||
- name: Install Dependencies
|
||||
run: "./scripts/layered.sh"
|
||||
|
||||
- name: Build, Package & Upload sourcemaps
|
||||
run: "./scripts/ci_package.sh"
|
||||
env:
|
||||
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
|
||||
SENTRY_DSN: ${{ secrets.SENTRY_DSN }}
|
||||
SENTRY_URL: ${{ secrets.SENTRY_URL }}
|
||||
SENTRY_ORG: element
|
||||
SENTRY_PROJECT: riot-web
|
||||
# We only deploy the latest bundles to Cloudflare Pages and use _redirects to fallback to R2 for
|
||||
# older ones. This redirect means that 'self' is insufficient in the CSP,
|
||||
# and we have to add the R2 URL.
|
||||
# Once Cloudflare redirects support proxying mode we will be able to ditch this.
|
||||
# See Proxying in support table at https://developers.cloudflare.com/pages/platform/redirects
|
||||
CSP_EXTRA_SOURCE: ${{ env.R2_PUBLIC_URL }}
|
||||
|
||||
- run: mv dist/element-*.tar.gz dist/develop.tar.gz
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: webapp
|
||||
path: dist/develop.tar.gz
|
||||
retention-days: 1
|
||||
|
||||
- name: Extract webapp
|
||||
run: |
|
||||
mkdir _deploy
|
||||
tar xf dist/develop.tar.gz -C _deploy --strip-components=1
|
||||
|
||||
- name: Copy config
|
||||
run: cp element.io/develop/config.json _deploy/config.json
|
||||
|
||||
- name: Populate 404.html
|
||||
run: echo "404 Not Found" > _deploy/404.html
|
||||
|
||||
- name: Populate _headers
|
||||
run: cp .github/cfp_headers _deploy/_headers
|
||||
|
||||
# Redirect requests for the develop tarball and the historical bundles to R2
|
||||
# We find the latest 100 bundle.css files and add their bundles to the redirects file
|
||||
# S3 has no sane way to get the age of a directory as they don't really exist
|
||||
- name: Populate _redirects
|
||||
run: |
|
||||
{
|
||||
echo "/develop.tar.gz $R2_PUBLIC_URL/develop.tar.gz 301"
|
||||
aws s3api --region auto --endpoint-url $R2_URL list-objects-v2 --bucket $R2_BUCKET \
|
||||
--query "sort_by(Contents[?ends_with(Key, '/bundle.css')], &LastModified)[-100:].Key" \
|
||||
--prefix "bundles/" | jq -r '.[]' | grep -oE '[^\"].*\/\s*' | while read -r path ; do
|
||||
echo "/${path}* $R2_PUBLIC_URL/${path}:splat 301"
|
||||
done
|
||||
} | tee _deploy/_redirects
|
||||
env:
|
||||
AWS_ACCESS_KEY_ID: ${{ secrets.CF_R2_ACCESS_KEY_ID }}
|
||||
AWS_SECRET_ACCESS_KEY: ${{ secrets.CF_R2_TOKEN }}
|
||||
|
||||
# We may be trying to deploy the same webapp bundles again, we need to ensure that the live bundles
|
||||
# are not present in the _redirects file and instead accessed directly from Cloudflare Pages.
|
||||
- name: Trim _redirects
|
||||
working-directory: _deploy
|
||||
run: |
|
||||
find bundles -type d -mindepth 1 -maxdepth 1 -exec sed -i "\:{}:d" _redirects \;
|
||||
|
||||
- name: Wait for other steps to succeed
|
||||
uses: t3chguy/wait-on-check-action@18541021811b56544d90e0f073401c2b99e249d6 # fork
|
||||
with:
|
||||
ref: ${{ github.sha }}
|
||||
running-workflow-name: "Build & Deploy develop.element.io"
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
wait-interval: 10
|
||||
check-regexp: ^((?!SonarCloud|SonarQube|issue|board|label|Release|prepare|GitHub Pages).)*$
|
||||
|
||||
# We keep the latest develop.tar.gz on R2 instead of relying on the github artifact uploaded earlier
|
||||
# as the expires after 24h and requires auth to download.
|
||||
# Element Desktop's fetch script uses this tarball to fetch latest develop to build Nightlies.
|
||||
- name: Deploy to R2
|
||||
run: |
|
||||
aws s3 cp dist/develop.tar.gz s3://$R2_BUCKET/develop.tar.gz --endpoint-url $R2_URL --region=auto
|
||||
aws s3 cp _deploy/ s3://$R2_BUCKET/ --recursive --endpoint-url $R2_URL --region=auto
|
||||
env:
|
||||
AWS_ACCESS_KEY_ID: ${{ secrets.CF_R2_ACCESS_KEY_ID }}
|
||||
AWS_SECRET_ACCESS_KEY: ${{ secrets.CF_R2_TOKEN }}
|
||||
|
||||
- name: Deploy to Cloudflare Pages
|
||||
id: cfp
|
||||
uses: cloudflare/pages-action@f0a1cd58cd66095dee69bfa18fa5efd1dde93bca # v1
|
||||
with:
|
||||
apiToken: ${{ secrets.CF_PAGES_TOKEN }}
|
||||
accountId: ${{ secrets.CF_PAGES_ACCOUNT_ID }}
|
||||
projectName: element-web-develop
|
||||
directory: _deploy
|
||||
gitHubToken: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- run: |
|
||||
echo "Deployed to ${{ steps.cfp.outputs.url }}" >> $GITHUB_STEP_SUMMARY
|
||||
94
.github/workflows/dockerhub.yaml
vendored
Normal file
94
.github/workflows/dockerhub.yaml
vendored
Normal file
@@ -0,0 +1,94 @@
|
||||
name: Dockerhub
|
||||
on:
|
||||
workflow_dispatch: {}
|
||||
push:
|
||||
tags: [v*]
|
||||
schedule:
|
||||
# This job can take a while, and we have usage limits, so just publish develop only twice a day
|
||||
- cron: "0 7/12 * * *"
|
||||
concurrency: ${{ github.workflow }}-${{ github.ref_name }}
|
||||
|
||||
permissions:
|
||||
id-token: write # needed for signing the images with GitHub OIDC Token
|
||||
jobs:
|
||||
buildx:
|
||||
name: Docker Buildx
|
||||
runs-on: ubuntu-latest
|
||||
environment: dockerhub
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- variant: vanilla
|
||||
# Variant we ship to aid ESS in providing a build on the OpenCoDE platform including specific modules
|
||||
- variant: opendesk
|
||||
flavor: suffix=-opendesk,onlatest=true
|
||||
prepare: mv variants/openDesk/* .
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0 # needed for docker-package to be able to calculate the version
|
||||
|
||||
- name: Install Cosign
|
||||
uses: sigstore/cosign-installer@4959ce089c160fddf62f7b42464195ba1a56d382 # v3
|
||||
|
||||
- name: Prepare
|
||||
if: matrix.prepare
|
||||
run: ${{ matrix.prepare }}
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@49b3bc8e6bdd4a60e6116a5414239cba5943d3cf # v3
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@988b5a0280414f521da01fcc63a27aeeb4b104db # v3
|
||||
with:
|
||||
install: true
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
- name: Docker meta
|
||||
id: meta
|
||||
uses: docker/metadata-action@8e5442c4ef9f78752691e2d8f8d19755c6f78e81 # v5
|
||||
with:
|
||||
images: |
|
||||
vectorim/element-web
|
||||
tags: |
|
||||
type=ref,event=branch
|
||||
type=ref,event=tag
|
||||
flavor: |
|
||||
latest=${{ contains(github.ref_name, '-rc.') && 'false' || 'auto' }}
|
||||
${{ matrix.flavor }}
|
||||
|
||||
- name: Build and push
|
||||
id: build-and-push
|
||||
uses: docker/build-push-action@4f58ea79222b3b9dc2c8bbdd6debcef730109a75 # v6
|
||||
with:
|
||||
context: .
|
||||
push: true
|
||||
platforms: linux/amd64,linux/arm64
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
|
||||
- name: Sign the images with GitHub OIDC Token
|
||||
env:
|
||||
DIGEST: ${{ steps.build-and-push.outputs.digest }}
|
||||
TAGS: ${{ steps.meta.outputs.tags }}
|
||||
run: |
|
||||
images=""
|
||||
for tag in ${TAGS}; do
|
||||
images+="${tag}@${DIGEST} "
|
||||
done
|
||||
cosign sign --yes ${images}
|
||||
|
||||
- name: Update repo description
|
||||
if: matrix.variant == 'vanilla'
|
||||
uses: peter-evans/dockerhub-description@e98e4d1628a5f3be2be7c231e50981aee98723ae # v4
|
||||
continue-on-error: true
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
repository: vectorim/element-web
|
||||
107
.github/workflows/docs.yml
vendored
Normal file
107
.github/workflows/docs.yml
vendored
Normal file
@@ -0,0 +1,107 @@
|
||||
name: Deploy documentation
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [develop]
|
||||
workflow_dispatch: {}
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
pages: write
|
||||
id-token: write
|
||||
|
||||
concurrency:
|
||||
group: "pages"
|
||||
cancel-in-progress: false
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: GitHub Pages
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Fetch element-desktop
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: element-hq/element-desktop
|
||||
path: element-desktop
|
||||
|
||||
- name: Fetch element-web
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
path: element-web
|
||||
|
||||
- name: Fetch matrix-js-sdk
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: matrix-org/matrix-js-sdk
|
||||
path: matrix-js-sdk
|
||||
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
cache: "yarn"
|
||||
cache-dependency-path: element-web/yarn.lock
|
||||
node-version: "lts/*"
|
||||
|
||||
- name: Generate automations docs
|
||||
working-directory: element-web
|
||||
run: |
|
||||
yarn install --frozen-lockfile
|
||||
yarn ts-node ./scripts/gen-workflow-mermaid.ts ../element-desktop ../element-web ../matrix-js-sdk > docs/automations.md
|
||||
echo "- [Automations](automations.md)" >> docs/SUMMARY.md
|
||||
|
||||
- name: Setup mdBook
|
||||
uses: peaceiris/actions-mdbook@v2
|
||||
with:
|
||||
mdbook-version: "0.4.10"
|
||||
|
||||
- name: Install mdbook extensions
|
||||
run: cargo install mdbook-combiner mdbook-mermaid
|
||||
|
||||
- name: Prepare docs
|
||||
run: |
|
||||
mkdir docs
|
||||
|
||||
mv element-desktop/README.md element-desktop/docs/
|
||||
mv element-desktop/docs "docs/Element Desktop"
|
||||
|
||||
mv element-web/README.md element-web/docs/
|
||||
mv element-web/docs/lib docs/
|
||||
mv element-web/docs "docs/Element Web"
|
||||
|
||||
mv matrix-js-sdk/README.md matrix-js-sdk/docs/
|
||||
mv matrix-js-sdk/docs "docs/Matrix JS SDK"
|
||||
|
||||
sed -i -e 's/\.\.\/README.md/README.md/' docs/**/SUMMARY.md
|
||||
|
||||
mdbook-combiner -m docs
|
||||
sed -i -E 's/^\t# (.+)$/- [\1]()/gm;t' SUMMARY.md
|
||||
sed -i -E 's/^- \[(.+)]\(<>\)$/---\n# \1/gm;t' SUMMARY.md
|
||||
sed -i -E 's/\t- \[Introduction]/- [Introduction]/gm;t' SUMMARY.md
|
||||
|
||||
cat <<EOF > docs/SUMMARY.md
|
||||
# Summary
|
||||
- [Introduction](<Element Web/README.md>)
|
||||
|
||||
EOF
|
||||
cat SUMMARY.md >> docs/SUMMARY.md
|
||||
|
||||
mv element-web/book.toml .
|
||||
|
||||
- name: Build docs
|
||||
run: mdbook build
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-pages-artifact@v3
|
||||
with:
|
||||
path: ./book
|
||||
|
||||
deploy:
|
||||
environment:
|
||||
name: github-pages
|
||||
url: ${{ steps.deployment.outputs.page_url }}
|
||||
runs-on: ubuntu-latest
|
||||
needs: build
|
||||
steps:
|
||||
- name: Deploy to GitHub Pages
|
||||
id: deployment
|
||||
uses: actions/deploy-pages@v4
|
||||
43
.github/workflows/end-to-end-tests-netlify.yaml
vendored
Normal file
43
.github/workflows/end-to-end-tests-netlify.yaml
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
# Triggers after the playwright tests have finished,
|
||||
# taking the artifact and uploading it to Netlify for easier viewing
|
||||
name: Upload End to End Test report to Netlify
|
||||
on:
|
||||
workflow_run:
|
||||
workflows: ["End to End Tests"]
|
||||
types:
|
||||
- completed
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.workflow_run.head_branch || github.run_id }}
|
||||
cancel-in-progress: ${{ github.event.workflow_run.event == 'pull_request' }}
|
||||
|
||||
jobs:
|
||||
report:
|
||||
if: github.event.workflow_run.conclusion != 'cancelled'
|
||||
name: Report results
|
||||
runs-on: ubuntu-22.04
|
||||
environment: Netlify
|
||||
permissions:
|
||||
statuses: write
|
||||
deployments: write
|
||||
steps:
|
||||
- name: Download HTML report
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
github-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
run-id: ${{ github.event.workflow_run.id }}
|
||||
name: html-report
|
||||
path: playwright-report
|
||||
|
||||
- name: 📤 Deploy to Netlify
|
||||
uses: matrix-org/netlify-pr-preview@v3
|
||||
with:
|
||||
path: playwright-report
|
||||
owner: ${{ github.event.workflow_run.head_repository.owner.login }}
|
||||
branch: ${{ github.event.workflow_run.head_branch }}
|
||||
revision: ${{ github.event.workflow_run.head_sha }}
|
||||
token: ${{ secrets.NETLIFY_AUTH_TOKEN }}
|
||||
site_id: ${{ vars.NETLIFY_SITE_ID }}
|
||||
desc: Playwright Report
|
||||
deployment_env: EndToEndTests
|
||||
prefix: "e2e-"
|
||||
190
.github/workflows/end-to-end-tests.yaml
vendored
Normal file
190
.github/workflows/end-to-end-tests.yaml
vendored
Normal file
@@ -0,0 +1,190 @@
|
||||
# Produce a build of element-web with this version of react-sdk
|
||||
# and any matching branches of element-web and js-sdk, output it
|
||||
# as an artifact and run end-to-end tests.
|
||||
name: End to End Tests
|
||||
on:
|
||||
pull_request: {}
|
||||
merge_group:
|
||||
types: [checks_requested]
|
||||
push:
|
||||
branches: [develop, master]
|
||||
repository_dispatch:
|
||||
types: [element-web-notify]
|
||||
|
||||
# support triggering from other workflows
|
||||
workflow_call:
|
||||
inputs:
|
||||
skip:
|
||||
type: boolean
|
||||
required: false
|
||||
default: false
|
||||
description: "A boolean to skip the playwright check itself while still creating the passing check. Useful when only running in Merge Queues."
|
||||
|
||||
matrix-js-sdk-sha:
|
||||
type: string
|
||||
required: false
|
||||
description: "The Git SHA of matrix-js-sdk to build against. By default, will use a matching branch name if it exists, or develop."
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event_name }}
|
||||
cancel-in-progress: true
|
||||
|
||||
env:
|
||||
# fetchdep.sh needs to know our PR number
|
||||
PR_NUMBER: ${{ github.event.pull_request.number }}
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: "Build Element-Web"
|
||||
runs-on: ubuntu-22.04
|
||||
if: inputs.skip != true
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: element-hq/element-web
|
||||
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
cache: "yarn"
|
||||
node-version: "lts/*"
|
||||
|
||||
- name: Fetch layered build
|
||||
id: layered_build
|
||||
env:
|
||||
# tell layered.sh to check out the right sha of the JS-SDK & EW, if they were given one
|
||||
JS_SDK_GITHUB_BASE_REF: ${{ inputs.matrix-js-sdk-sha }}
|
||||
run: |
|
||||
scripts/layered.sh
|
||||
JSSDK_SHA=$(git -C matrix-js-sdk rev-parse --short=12 HEAD)
|
||||
VECTOR_SHA=$(git rev-parse --short=12 HEAD)
|
||||
echo "VERSION=$VECTOR_SHA--js-$JSSDK_SHA" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Copy config
|
||||
run: cp element.io/develop/config.json config.json
|
||||
|
||||
- name: Build
|
||||
env:
|
||||
CI_PACKAGE: true
|
||||
VERSION: "${{ steps.layered_build.outputs.VERSION }}"
|
||||
run: |
|
||||
yarn build
|
||||
echo $VERSION > webapp/version
|
||||
|
||||
- name: Upload Artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: webapp
|
||||
path: webapp
|
||||
retention-days: 1
|
||||
|
||||
playwright:
|
||||
name: "Run Tests ${{ matrix.runner }}/${{ strategy.job-total }}"
|
||||
needs: build
|
||||
if: inputs.skip != true
|
||||
runs-on: ubuntu-22.04
|
||||
permissions:
|
||||
actions: read
|
||||
issues: read
|
||||
pull-requests: read
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
# Run multiple instances in parallel to speed up the tests
|
||||
runner: [1, 2, 3, 4, 5, 6]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
repository: element-hq/element-web
|
||||
|
||||
- name: 📥 Download artifact
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: webapp
|
||||
path: webapp
|
||||
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
cache: "yarn"
|
||||
cache-dependency-path: yarn.lock
|
||||
node-version: "lts/*"
|
||||
|
||||
- name: Install dependencies
|
||||
run: yarn install --frozen-lockfile
|
||||
|
||||
- name: Get installed Playwright version
|
||||
id: playwright
|
||||
run: echo "version=$(yarn list --pattern @playwright/test --depth=0 --json --non-interactive --no-progress | jq -r '.data.trees[].name')" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Cache playwright binaries
|
||||
uses: actions/cache@v4
|
||||
id: playwright-cache
|
||||
with:
|
||||
path: |
|
||||
~/.cache/ms-playwright
|
||||
key: ${{ runner.os }}-playwright-${{ steps.playwright.outputs.version }}
|
||||
|
||||
- name: Install Playwright browsers
|
||||
if: steps.playwright-cache.outputs.cache-hit != 'true'
|
||||
run: yarn playwright install --with-deps
|
||||
|
||||
- name: Run Playwright tests
|
||||
run: yarn playwright test --shard ${{ matrix.runner }}/${{ strategy.job-total }}
|
||||
|
||||
- name: Upload blob report to GitHub Actions Artifacts
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: all-blob-reports-${{ matrix.runner }}
|
||||
path: blob-report
|
||||
retention-days: 1
|
||||
|
||||
complete:
|
||||
name: end-to-end-tests
|
||||
needs: playwright
|
||||
if: always()
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
if: inputs.skip != true
|
||||
with:
|
||||
persist-credentials: false
|
||||
repository: element-hq/element-web
|
||||
|
||||
- uses: actions/setup-node@v4
|
||||
if: inputs.skip != true
|
||||
with:
|
||||
cache: "yarn"
|
||||
node-version: "lts/*"
|
||||
|
||||
- name: Install dependencies
|
||||
if: inputs.skip != true
|
||||
run: yarn install --frozen-lockfile
|
||||
|
||||
- name: Download blob reports from GitHub Actions Artifacts
|
||||
if: inputs.skip != true
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
pattern: all-blob-reports-*
|
||||
path: all-blob-reports
|
||||
merge-multiple: true
|
||||
|
||||
- name: Merge into HTML Report
|
||||
if: inputs.skip != true
|
||||
run: yarn playwright merge-reports --reporter=html,./playwright/flaky-reporter.ts,./playwright/stale-screenshot-reporter.ts ./all-blob-reports
|
||||
env:
|
||||
# Only pass creds to the flaky-reporter on main branch runs
|
||||
GITHUB_TOKEN: ${{ github.ref_name == 'develop' && secrets.ELEMENT_BOT_TOKEN || '' }}
|
||||
|
||||
# Upload the HTML report even if one of our reporters fails, this can happen when stale screenshots are detected
|
||||
- name: Upload HTML report
|
||||
if: always() && inputs.skip != true
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: html-report
|
||||
path: playwright-report
|
||||
retention-days: 14
|
||||
|
||||
- if: needs.playwright.result != 'skipped' && needs.playwright.result != 'success'
|
||||
run: exit 1
|
||||
156
.github/workflows/issue_closed.yml
vendored
Normal file
156
.github/workflows/issue_closed.yml
vendored
Normal file
@@ -0,0 +1,156 @@
|
||||
# For duplicate issues, ensure the close type is right (not planned), update it if not
|
||||
# For all closed (completed) issues, cascade the closure onto any referenced rageshakes
|
||||
# For all closed (not planned) issues, comment on rageshakes to move them into the canonical issue if one exists
|
||||
on:
|
||||
issues:
|
||||
types: [closed]
|
||||
jobs:
|
||||
tidy:
|
||||
name: Tidy closed issues
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/github-script@v7
|
||||
id: main
|
||||
with:
|
||||
# PAT needed as the GITHUB_TOKEN won't be able to see cross-references from other orgs (matrix-org)
|
||||
github-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
script: |
|
||||
const variables = {
|
||||
owner: context.repo.owner,
|
||||
name: context.repo.repo,
|
||||
number: context.issue.number,
|
||||
};
|
||||
|
||||
const query = `query($owner:String!, $name:String!, $number:Int!) {
|
||||
repository(owner: $owner, name: $name) {
|
||||
issue(number: $number) {
|
||||
stateReason,
|
||||
timelineItems(first: 100, itemTypes: [MARKED_AS_DUPLICATE_EVENT, UNMARKED_AS_DUPLICATE_EVENT, CROSS_REFERENCED_EVENT]) {
|
||||
edges {
|
||||
node {
|
||||
__typename
|
||||
... on MarkedAsDuplicateEvent {
|
||||
canonical {
|
||||
... on Issue {
|
||||
repository {
|
||||
nameWithOwner
|
||||
}
|
||||
number
|
||||
}
|
||||
... on PullRequest {
|
||||
repository {
|
||||
nameWithOwner
|
||||
}
|
||||
number
|
||||
}
|
||||
}
|
||||
}
|
||||
... on UnmarkedAsDuplicateEvent {
|
||||
canonical {
|
||||
... on Issue {
|
||||
repository {
|
||||
nameWithOwner
|
||||
}
|
||||
number
|
||||
}
|
||||
... on PullRequest {
|
||||
repository {
|
||||
nameWithOwner
|
||||
}
|
||||
number
|
||||
}
|
||||
}
|
||||
}
|
||||
... on CrossReferencedEvent {
|
||||
source {
|
||||
... on Issue {
|
||||
repository {
|
||||
nameWithOwner
|
||||
}
|
||||
number
|
||||
}
|
||||
... on PullRequest {
|
||||
repository {
|
||||
nameWithOwner
|
||||
}
|
||||
number
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}`;
|
||||
|
||||
const result = await github.graphql(query, variables);
|
||||
const { stateReason, timelineItems: { edges } } = result.repository.issue;
|
||||
|
||||
const RAGESHAKE_OWNER = "matrix-org";
|
||||
const RAGESHAKE_REPO = "element-web-rageshakes";
|
||||
const rageshakes = new Set();
|
||||
const duplicateOf = new Set();
|
||||
|
||||
console.log("Edges: ", JSON.stringify(edges));
|
||||
|
||||
for (const { node } of edges) {
|
||||
switch(node.__typename) {
|
||||
case "MarkedAsDuplicateEvent":
|
||||
duplicateOf.add(node.canonical.repository.nameWithOwner + "#" + node.canonical.number);
|
||||
break;
|
||||
case "UnmarkedAsDuplicateEvent":
|
||||
duplicateOf.remove(node.canonical.repository.nameWithOwner + "#" + node.canonical.number);
|
||||
break;
|
||||
case "CrossReferencedEvent":
|
||||
if (node.source.repository.nameWithOwner === (RAGESHAKE_OWNER + "/" + RAGESHAKE_REPO)) {
|
||||
rageshakes.add(node.source.number);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
console.log("Duplicate of: ", duplicateOf);
|
||||
console.log("Found rageshakes: ", rageshakes);
|
||||
|
||||
if (duplicateOf.size) {
|
||||
const body = Array.from(duplicateOf).join("\n");
|
||||
|
||||
// Comment on all rageshakes to create relationship to the issue this was closed as duplicate of
|
||||
for (const rageshake of rageshakes) {
|
||||
github.rest.issues.createComment({
|
||||
owner: RAGESHAKE_OWNER,
|
||||
repo: RAGESHAKE_REPO,
|
||||
issue_number: rageshake,
|
||||
body,
|
||||
});
|
||||
}
|
||||
|
||||
// Duplicate was closed with wrong reason, fix it
|
||||
if (stateReason === "COMPLETED") {
|
||||
core.setOutput("closeAsNotPlanned", "true");
|
||||
}
|
||||
} else {
|
||||
// This issue was closed, close all related rageshakes
|
||||
for (const rageshake of rageshakes) {
|
||||
github.rest.issues.update({
|
||||
owner: RAGESHAKE_OWNER,
|
||||
repo: RAGESHAKE_REPO,
|
||||
issue_number: rageshake,
|
||||
state: "closed",
|
||||
});
|
||||
}
|
||||
}
|
||||
- uses: actions/github-script@v7
|
||||
name: Close duplicate as Not Planned
|
||||
if: steps.main.outputs.closeAsNotPlanned
|
||||
with:
|
||||
# We do this step separately, and with the default token so as to not re-trigger this workflow when re-closing
|
||||
script: |
|
||||
await github.graphql(`mutation($id:ID!) {
|
||||
closeIssue(input: { issueId:$id, stateReason:NOT_PLANNED }) {
|
||||
clientMutationId
|
||||
}
|
||||
}`, {
|
||||
id: context.payload.issue.node_id,
|
||||
});
|
||||
10
.github/workflows/localazy_download.yaml
vendored
Normal file
10
.github/workflows/localazy_download.yaml
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
name: Localazy Download
|
||||
on:
|
||||
workflow_dispatch: {}
|
||||
schedule:
|
||||
- cron: "0 6 * * 1,3,5" # Every Monday, Wednesday and Friday at 6am UTC
|
||||
jobs:
|
||||
download:
|
||||
uses: matrix-org/matrix-web-i18n/.github/workflows/localazy_download.yaml@main
|
||||
secrets:
|
||||
ELEMENT_BOT_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
11
.github/workflows/localazy_upload.yaml
vendored
Normal file
11
.github/workflows/localazy_upload.yaml
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
name: Localazy Upload
|
||||
on:
|
||||
push:
|
||||
branches: [develop]
|
||||
paths:
|
||||
- "src/i18n/strings/en_EN.json"
|
||||
jobs:
|
||||
upload:
|
||||
uses: matrix-org/matrix-web-i18n/.github/workflows/localazy_upload.yaml@main
|
||||
secrets:
|
||||
LOCALAZY_WRITE_KEY: ${{ secrets.LOCALAZY_WRITE_KEY }}
|
||||
48
.github/workflows/netlify.yaml
vendored
Normal file
48
.github/workflows/netlify.yaml
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
# Triggers after the layered build has finished, taking the artifact
|
||||
# and uploading it to netlify
|
||||
name: Upload Preview Build to Netlify
|
||||
on:
|
||||
workflow_run:
|
||||
workflows: ["End to End Tests"]
|
||||
types:
|
||||
- completed
|
||||
jobs:
|
||||
deploy:
|
||||
if: github.event.workflow_run.conclusion != 'cancelled' && github.event.workflow_run.event == 'pull_request'
|
||||
runs-on: ubuntu-22.04
|
||||
environment: Netlify
|
||||
steps:
|
||||
- name: 📝 Create Deployment
|
||||
uses: bobheadxi/deployments@648679e8e4915b27893bd7dbc35cb504dc915bc8 # v1
|
||||
id: deployment
|
||||
with:
|
||||
step: start
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
env: Netlify
|
||||
ref: ${{ github.event.workflow_run.head_sha }}
|
||||
desc: |
|
||||
Do you trust the author of this PR? Maybe this build will steal your keys or give you malware.
|
||||
Exercise caution. Use test accounts.
|
||||
|
||||
- name: 📥 Download artifact
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
github-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
run-id: ${{ github.event.workflow_run.id }}
|
||||
name: webapp
|
||||
path: webapp
|
||||
|
||||
- name: 📤 Deploy to Netlify
|
||||
uses: matrix-org/netlify-pr-preview@v3
|
||||
with:
|
||||
path: webapp
|
||||
owner: ${{ github.event.workflow_run.head_repository.owner.login }}
|
||||
branch: ${{ github.event.workflow_run.head_branch }}
|
||||
revision: ${{ github.event.workflow_run.head_sha }}
|
||||
token: ${{ secrets.NETLIFY_AUTH_TOKEN }}
|
||||
site_id: ${{ vars.NETLIFY_SITE_ID }}
|
||||
deployment_env: ${{ steps.deployment.outputs.env }}
|
||||
deployment_id: ${{ steps.deployment.outputs.deployment_id }}
|
||||
desc: |
|
||||
Do you trust the author of this PR? Maybe this build will steal your keys or give you malware.
|
||||
Exercise caution. Use test accounts.
|
||||
91
.github/workflows/pending-reviews.yaml
vendored
Normal file
91
.github/workflows/pending-reviews.yaml
vendored
Normal file
@@ -0,0 +1,91 @@
|
||||
name: Pending reviews automation
|
||||
on:
|
||||
# The bot exceeded its API rate limit. Disabling for now (adding workflow dispatch so the workflow file stays valid & we can test to see if it starts working again)
|
||||
workflow_dispatch: {}
|
||||
# We run it on a schedule instead of on pull_request_* events to not create confusing messaging in the PR
|
||||
#schedule:
|
||||
# - cron: "*/10 * * * *"
|
||||
concurrency: ${{ github.workflow }}
|
||||
jobs:
|
||||
bot:
|
||||
name: Pending reviews bot
|
||||
runs-on: ubuntu-latest
|
||||
environment: Matrix
|
||||
env:
|
||||
URL: "https://github.com/pulls?q=is%3Apr+is%3Aopen+repo%3Amatrix-org%2Fmatrix-js-sdk+repo%3Amatrix-org%2Fmatrix-react-sdk+repo%3Aelement-hq%2Felement-web+repo%3Aelement-hq%2Felement-desktop+review-requested%3A%40me+sort%3Aupdated-desc+"
|
||||
RELEASE_BLOCKERS_URL: "https://github.com/pulls?q=is%3Aopen+repo%3Amatrix-org%2Fmatrix-js-sdk+repo%3Amatrix-org%2Fmatrix-react-sdk+repo%3Aelement-hq%2Felement-web+repo%3Aelement-hq%2Felement-desktop+sort%3Aupdated-desc+label%3AX-Release-Blocker+"
|
||||
steps:
|
||||
- uses: actions/github-script@v7
|
||||
env:
|
||||
HS_URL: ${{ secrets.BETABOT_HS_URL }}
|
||||
ROOM_ID: ${{ secrets.ROOM_ID }}
|
||||
TOKEN: ${{ secrets.BETABOT_ACCESS_TOKEN }}
|
||||
with:
|
||||
# PAT needed as the GITHUB_TOKEN won't be able to see cross-references from other orgs (matrix-org)
|
||||
github-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
script: |
|
||||
const { HS_URL, ROOM_ID, TOKEN, URL, RELEASE_BLOCKERS_URL } = process.env;
|
||||
|
||||
async function updateCounter(counter, link, severity, title, value, clearOnZero) {
|
||||
const apiUrl = `${HS_URL}/_matrix/client/v3/rooms/${ROOM_ID}/state/re.jki.counter/${counter}`;
|
||||
const headers = {
|
||||
"Content-Type": "application/json",
|
||||
"Authorization": `Bearer ${TOKEN}`,
|
||||
};
|
||||
const res = await fetch(apiUrl, {
|
||||
method: "GET",
|
||||
headers,
|
||||
});
|
||||
|
||||
const data = await res.json();
|
||||
|
||||
if (data.value === issueCount) {
|
||||
console.log("Pending review count already correct");
|
||||
return;
|
||||
}
|
||||
|
||||
let body = {};
|
||||
if (issueCount || !clearOnZero) {
|
||||
body = JSON.stringify({
|
||||
link,
|
||||
severity,
|
||||
title,
|
||||
value,
|
||||
});
|
||||
}
|
||||
|
||||
await fetch(apiUrl, {
|
||||
method: "PUT",
|
||||
body,
|
||||
headers,
|
||||
});
|
||||
}
|
||||
|
||||
const repos = [
|
||||
"element-hq/element-desktop",
|
||||
"element-hq/element-web",
|
||||
"matrix-org/matrix-js-sdk",
|
||||
];
|
||||
const teams = [
|
||||
"matrix-org/element-web-team",
|
||||
"matrix-org/element-web-reviewers",
|
||||
"element-hq/element-web-team",
|
||||
"element-hq/element-web-reviewers",
|
||||
];
|
||||
|
||||
let issueCount = 0;
|
||||
for (const team of teams) {
|
||||
const org = team.split("/", 2)[0];
|
||||
const reposInOrg = repos.filter(repo => repo.startsWith(org + "/"));
|
||||
const { data } = await github.rest.search.issuesAndPullRequests({
|
||||
q: `is:pr is:open review:required ${reposInOrg.map(r => `repo:${r}`).join(" ")} team-review-requested:${team}`,
|
||||
});
|
||||
issueCount += data.total_count;
|
||||
}
|
||||
await updateCounter("gh_reviews", URL, "warning", "Pending reviews", issueCount);
|
||||
|
||||
const { data } = await github.rest.search.issuesAndPullRequests({
|
||||
q: `is:open ${repos.map(repo => `repo:${repo}`).join(" ")} label:X-Release-Blocker`,
|
||||
});
|
||||
const blockerCount = data.total_count;
|
||||
await updateCounter("release_blockers", RELEASE_BLOCKERS_URL, "alert", "Release Blockers", blockerCount, true);
|
||||
45
.github/workflows/playwright-image-updates.yaml
vendored
Normal file
45
.github/workflows/playwright-image-updates.yaml
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
name: Update Playwright docker images
|
||||
on:
|
||||
workflow_dispatch: {}
|
||||
schedule:
|
||||
- cron: "0 6 * * *" # Every day at 6am UTC
|
||||
jobs:
|
||||
update:
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Update synapse image
|
||||
run: |
|
||||
docker pull "$IMAGE"
|
||||
INSPECT=$(docker inspect --format='{{index .RepoDigests 0}}' "$IMAGE")
|
||||
DIGEST=${INSPECT#*@}
|
||||
sed -i "s/const DOCKER_TAG.*/const DOCKER_TAG = \"develop@$DIGEST\";/" playwright/plugins/homeserver/synapse/index.ts
|
||||
env:
|
||||
IMAGE: ghcr.io/element-hq/synapse:develop
|
||||
|
||||
- name: Create Pull Request
|
||||
id: cpr
|
||||
uses: peter-evans/create-pull-request@5e914681df9dc83aa4e4905692ca88beb2f9e91f # v7
|
||||
with:
|
||||
token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
branch: actions/playwright-image-updates
|
||||
delete-branch: true
|
||||
title: Playwright Docker image updates
|
||||
labels: |
|
||||
T-Task
|
||||
|
||||
- name: Enable automerge
|
||||
run: gh pr merge --merge --auto "$PR_NUMBER"
|
||||
if: steps.cpr.outputs.pull-request-operation == 'created'
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
PR_NUMBER: ${{ steps.cpr.outputs.pull-request-number }}
|
||||
|
||||
- name: Enable autoapprove
|
||||
run: |
|
||||
gh pr review --approve "$PR_NUMBER"
|
||||
if: steps.cpr.outputs.pull-request-operation == 'created'
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
PR_NUMBER: ${{ steps.cpr.outputs.pull-request-number }}
|
||||
11
.github/workflows/pull_request.yaml
vendored
Normal file
11
.github/workflows/pull_request.yaml
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
name: Pull Request
|
||||
on:
|
||||
pull_request_target:
|
||||
types: [opened, edited, labeled, unlabeled, synchronize]
|
||||
merge_group:
|
||||
types: [checks_requested]
|
||||
jobs:
|
||||
action:
|
||||
uses: matrix-org/matrix-js-sdk/.github/workflows/pull_request.yaml@develop
|
||||
secrets:
|
||||
ELEMENT_BOT_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
16
.github/workflows/pull_request_base_branch.yaml
vendored
Normal file
16
.github/workflows/pull_request_base_branch.yaml
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
name: Pull Request Base Branch
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, edited, synchronize]
|
||||
jobs:
|
||||
check_base_branch:
|
||||
name: Check PR base branch
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
const baseBranch = context.payload.pull_request.base.ref;
|
||||
if (!['develop', 'staging'].includes(baseBranch) && !baseBranch.startsWith('feat/')) {
|
||||
core.setFailed(`Invalid base branch: ${baseBranch}`);
|
||||
}
|
||||
9
.github/workflows/release-drafter.yml
vendored
Normal file
9
.github/workflows/release-drafter.yml
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
name: Release Drafter
|
||||
on:
|
||||
push:
|
||||
branches: [staging]
|
||||
workflow_dispatch: {}
|
||||
concurrency: ${{ github.workflow }}
|
||||
jobs:
|
||||
draft:
|
||||
uses: matrix-org/matrix-js-sdk/.github/workflows/release-drafter-workflow.yml@develop
|
||||
14
.github/workflows/release-gitflow.yml
vendored
Normal file
14
.github/workflows/release-gitflow.yml
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
# Gitflow merge-back master->develop
|
||||
name: Merge master -> develop
|
||||
on:
|
||||
push:
|
||||
branches: [master]
|
||||
concurrency: ${{ github.repository }}-${{ github.workflow }}
|
||||
jobs:
|
||||
merge:
|
||||
uses: matrix-org/matrix-js-sdk/.github/workflows/release-gitflow.yml@develop
|
||||
secrets:
|
||||
ELEMENT_BOT_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
with:
|
||||
dependencies: |
|
||||
matrix-js-sdk
|
||||
62
.github/workflows/release.yml
vendored
Normal file
62
.github/workflows/release.yml
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
name: Release Process
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
mode:
|
||||
description: What type of release
|
||||
required: true
|
||||
default: rc
|
||||
type: choice
|
||||
options:
|
||||
- rc
|
||||
- final
|
||||
concurrency: ${{ github.workflow }}
|
||||
jobs:
|
||||
release:
|
||||
uses: matrix-org/matrix-js-sdk/.github/workflows/release-make.yml@develop
|
||||
secrets:
|
||||
ELEMENT_BOT_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }}
|
||||
GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
|
||||
with:
|
||||
final: ${{ inputs.mode == 'final' }}
|
||||
gpg-fingerprint: ${{ vars.GPG_FINGERPRINT }}
|
||||
asset-path: dist/*.tar.gz
|
||||
expected-asset-count: 3
|
||||
|
||||
notify-downstream:
|
||||
name: Trigger release drafter downstream
|
||||
needs: release
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Notify element-desktop repo that element-web release has completed to re-trigger release-drafter
|
||||
uses: benc-uk/workflow-dispatch@e2e5e9a103e331dad343f381a29e654aea3cf8fc # v1
|
||||
with:
|
||||
workflow: release-drafter.yml
|
||||
repo: element-hq/element-desktop
|
||||
ref: staging
|
||||
# Required when using the `repo` option. Either a PAT or a token generated from the GitHub app or CLI
|
||||
token: "${{ secrets.ELEMENT_BOT_TOKEN }}"
|
||||
|
||||
check:
|
||||
name: Post release checks
|
||||
needs: release
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Wait for dockerhub
|
||||
uses: t3chguy/wait-on-check-action@18541021811b56544d90e0f073401c2b99e249d6 # fork
|
||||
with:
|
||||
ref: master
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
wait-interval: 10
|
||||
check-name: "Docker Buildx (vanilla)"
|
||||
allowed-conclusions: success
|
||||
|
||||
- name: Wait for debian package
|
||||
uses: t3chguy/wait-on-check-action@18541021811b56544d90e0f073401c2b99e249d6 # fork
|
||||
with:
|
||||
ref: master
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
wait-interval: 10
|
||||
check-name: Build package
|
||||
allowed-conclusions: success
|
||||
107
.github/workflows/release_prepare.yml
vendored
Normal file
107
.github/workflows/release_prepare.yml
vendored
Normal file
@@ -0,0 +1,107 @@
|
||||
name: Cut branches
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
element-desktop:
|
||||
description: Prepare element-desktop
|
||||
required: true
|
||||
type: boolean
|
||||
default: true
|
||||
element-web:
|
||||
description: Prepare element-web
|
||||
required: true
|
||||
type: boolean
|
||||
default: true
|
||||
matrix-js-sdk:
|
||||
description: Prepare matrix-js-sdk
|
||||
required: true
|
||||
type: boolean
|
||||
default: true
|
||||
jobs:
|
||||
prepare:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout Element Desktop
|
||||
uses: actions/checkout@v4
|
||||
if: inputs.element-desktop
|
||||
with:
|
||||
repository: element-hq/element-desktop
|
||||
path: element-desktop
|
||||
ref: staging
|
||||
fetch-depth: 0
|
||||
fetch-tags: true
|
||||
token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
- name: Checkout Element Web
|
||||
uses: actions/checkout@v4
|
||||
if: inputs.element-web
|
||||
with:
|
||||
repository: element-hq/element-web
|
||||
path: element-web
|
||||
ref: staging
|
||||
fetch-depth: 0
|
||||
fetch-tags: true
|
||||
token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
- name: Checkout Matrix JS SDK
|
||||
uses: actions/checkout@v4
|
||||
if: inputs.matrix-js-sdk
|
||||
with:
|
||||
repository: matrix-org/matrix-js-sdk
|
||||
path: matrix-js-sdk
|
||||
ref: staging
|
||||
fetch-depth: 0
|
||||
fetch-tags: true
|
||||
token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
|
||||
- name: Prepare Git
|
||||
run: |
|
||||
git config --global user.email "releases@riot.im"
|
||||
git config --global user.name "RiotRobot"
|
||||
|
||||
- name: Merge Element Desktop
|
||||
if: inputs.element-desktop
|
||||
run: |
|
||||
git -C "element-desktop" merge origin/develop
|
||||
- name: Merge Element Web
|
||||
if: inputs.element-web
|
||||
run: |
|
||||
git -C "element-web" merge origin/develop
|
||||
- name: Merge JS SDK
|
||||
if: inputs.matrix-js-sdk
|
||||
run: |
|
||||
git -C "matrix-js-sdk" merge origin/develop
|
||||
|
||||
- name: Push staging
|
||||
run: for REPO in $REPOS; do [ -d "$REPO" ] && git -C "$REPO" push origin staging; done
|
||||
|
||||
- name: Wait for matrix-js-sdk draft
|
||||
if: inputs.matrix-js-sdk
|
||||
uses: t3chguy/wait-on-check-action@18541021811b56544d90e0f073401c2b99e249d6 # fork
|
||||
with:
|
||||
ref: staging
|
||||
repo: matrix-org/matrix-js-sdk
|
||||
repo-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
wait-interval: 10
|
||||
check-name: draft
|
||||
allowed-conclusions: success
|
||||
|
||||
- name: Wait for element-web draft
|
||||
if: inputs.element-web
|
||||
uses: t3chguy/wait-on-check-action@18541021811b56544d90e0f073401c2b99e249d6 # fork
|
||||
with:
|
||||
ref: staging
|
||||
repo: element-hq/element-web
|
||||
repo-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
wait-interval: 10
|
||||
check-name: draft
|
||||
allowed-conclusions: success
|
||||
|
||||
- name: Wait for element-desktop draft
|
||||
if: inputs.element-desktop
|
||||
uses: t3chguy/wait-on-check-action@18541021811b56544d90e0f073401c2b99e249d6 # fork
|
||||
with:
|
||||
ref: staging
|
||||
repo: element-hq/element-desktop
|
||||
repo-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
wait-interval: 10
|
||||
check-name: draft
|
||||
allowed-conclusions: success
|
||||
19
.github/workflows/sonarqube.yml
vendored
Normal file
19
.github/workflows/sonarqube.yml
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
name: SonarQube
|
||||
on:
|
||||
workflow_run:
|
||||
workflows: ["Tests"]
|
||||
types:
|
||||
- completed
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.workflow_run.head_branch }}
|
||||
cancel-in-progress: true
|
||||
jobs:
|
||||
sonarqube:
|
||||
name: 🩻 SonarQube
|
||||
if: github.event.workflow_run.conclusion == 'success' && github.event.workflow_run.event != 'merge_group'
|
||||
uses: matrix-org/matrix-js-sdk/.github/workflows/sonarcloud.yml@develop
|
||||
secrets:
|
||||
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
||||
ELEMENT_BOT_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
with:
|
||||
sharded: true
|
||||
151
.github/workflows/static_analysis.yaml
vendored
Normal file
151
.github/workflows/static_analysis.yaml
vendored
Normal file
@@ -0,0 +1,151 @@
|
||||
name: Static Analysis
|
||||
on:
|
||||
pull_request: {}
|
||||
push:
|
||||
branches: [develop, master]
|
||||
merge_group:
|
||||
types: [checks_requested]
|
||||
repository_dispatch:
|
||||
types: [element-web-notify]
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event_name }}
|
||||
cancel-in-progress: true
|
||||
|
||||
env:
|
||||
# These must be set for fetchdep.sh to get the right branch
|
||||
REPOSITORY: ${{ github.repository }}
|
||||
PR_NUMBER: ${{ github.event.pull_request.number }}
|
||||
|
||||
jobs:
|
||||
ts_lint:
|
||||
name: "Typescript Syntax Check"
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
cache: "yarn"
|
||||
node-version: "lts/*"
|
||||
|
||||
- name: Install Dependencies
|
||||
run: "./scripts/layered.sh"
|
||||
|
||||
- name: Typecheck
|
||||
run: "yarn run lint:types"
|
||||
|
||||
- name: Switch js-sdk to release mode
|
||||
working-directory: node_modules/matrix-js-sdk
|
||||
run: |
|
||||
scripts/switch_package_to_release.cjs
|
||||
yarn install
|
||||
yarn run build:compile
|
||||
yarn run build:types
|
||||
|
||||
- name: Typecheck (release mode)
|
||||
run: "yarn run lint:types"
|
||||
|
||||
# Temporary while we directly import matrix-js-sdk/src/* which means we need
|
||||
# certain @types/* packages to make sense of matrix-js-sdk types.
|
||||
#- name: Typecheck (release mode; no yarn link)
|
||||
# if: github.event_name != 'pull_request' && github.ref_name != 'master'
|
||||
# run: |
|
||||
# yarn unlink matrix-js-sdk
|
||||
# yarn add github:matrix-org/matrix-js-sdk#develop
|
||||
# yarn install --force
|
||||
# yarn run lint:types
|
||||
|
||||
i18n_lint:
|
||||
name: "i18n Check"
|
||||
uses: matrix-org/matrix-web-i18n/.github/workflows/i18n_check.yml@main
|
||||
with:
|
||||
hardcoded-words: "Element"
|
||||
allowed-hardcoded-keys: |
|
||||
console_dev_note
|
||||
labs|element_call_video_rooms
|
||||
labs|feature_disable_call_per_sender_encryption
|
||||
voip|element_call
|
||||
error|invalid_json
|
||||
error|misconfigured
|
||||
welcome_to_element
|
||||
|
||||
rethemendex_lint:
|
||||
name: "Rethemendex Check"
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- run: ./res/css/rethemendex.sh
|
||||
|
||||
- run: git diff --exit-code
|
||||
|
||||
js_lint:
|
||||
name: "ESLint"
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
cache: "yarn"
|
||||
node-version: "lts/*"
|
||||
|
||||
# Does not need branch matching as only analyses this layer
|
||||
- name: Install Deps
|
||||
run: "yarn install --frozen-lockfile"
|
||||
|
||||
- name: Run Linter
|
||||
run: "yarn run lint:js"
|
||||
|
||||
style_lint:
|
||||
name: "Style Lint"
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
cache: "yarn"
|
||||
node-version: "lts/*"
|
||||
|
||||
# Does not need branch matching as only analyses this layer
|
||||
- name: Install Deps
|
||||
run: "yarn install"
|
||||
|
||||
- name: Run Linter
|
||||
run: "yarn run lint:style"
|
||||
|
||||
workflow_lint:
|
||||
name: "Workflow Lint"
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
cache: "yarn"
|
||||
node-version: "lts/*"
|
||||
|
||||
# Does not need branch matching as only analyses this layer
|
||||
- name: Install Deps
|
||||
run: "yarn install --frozen-lockfile"
|
||||
|
||||
- name: Run Linter
|
||||
run: "yarn lint:workflows"
|
||||
|
||||
analyse_dead_code:
|
||||
name: "Analyse Dead Code"
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
cache: "yarn"
|
||||
node-version: "lts/*"
|
||||
|
||||
- name: Install Deps
|
||||
run: "scripts/layered.sh"
|
||||
|
||||
- name: Dead Code Analysis
|
||||
run: "yarn run analyse:unused-exports"
|
||||
21
.github/workflows/sync-labels.yml
vendored
Normal file
21
.github/workflows/sync-labels.yml
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
name: Sync labels
|
||||
on:
|
||||
workflow_dispatch: {}
|
||||
schedule:
|
||||
- cron: "0 1 * * *" # 1am every day
|
||||
push:
|
||||
branches:
|
||||
- develop
|
||||
paths:
|
||||
- .github/labels.yml
|
||||
jobs:
|
||||
sync-labels:
|
||||
uses: element-hq/element-meta/.github/workflows/sync-labels.yml@develop
|
||||
with:
|
||||
LABELS: |
|
||||
element-hq/element-meta
|
||||
.github/labels.yml
|
||||
DELETE: true
|
||||
WET: true
|
||||
secrets:
|
||||
ELEMENT_BOT_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
110
.github/workflows/tests.yml
vendored
Normal file
110
.github/workflows/tests.yml
vendored
Normal file
@@ -0,0 +1,110 @@
|
||||
name: Tests
|
||||
on:
|
||||
pull_request: {}
|
||||
merge_group:
|
||||
types: [checks_requested]
|
||||
push:
|
||||
branches: [develop, master]
|
||||
repository_dispatch:
|
||||
types: [element-web-notify]
|
||||
workflow_call:
|
||||
inputs:
|
||||
disable_coverage:
|
||||
type: boolean
|
||||
required: false
|
||||
description: "Specify true to skip generating and uploading coverage for tests"
|
||||
matrix-js-sdk-sha:
|
||||
type: string
|
||||
required: false
|
||||
description: "The matrix-js-sdk SHA to use"
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event_name }}
|
||||
cancel-in-progress: true
|
||||
|
||||
env:
|
||||
ENABLE_COVERAGE: ${{ github.event_name != 'merge_group' && inputs.disable_coverage != 'true' }}
|
||||
# fetchdep.sh needs to know our PR number
|
||||
PR_NUMBER: ${{ github.event.pull_request.number }}
|
||||
|
||||
jobs:
|
||||
jest:
|
||||
name: Jest
|
||||
runs-on: ubuntu-22.04
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
# Run multiple instances in parallel to speed up the tests
|
||||
runner: [1, 2]
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: ${{ inputs.matrix-js-sdk-sha && 'element-hq/element-web' || github.repository }}
|
||||
|
||||
- name: Yarn cache
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: "lts/*"
|
||||
cache: "yarn"
|
||||
|
||||
- name: Install Deps
|
||||
run: "./scripts/layered.sh"
|
||||
env:
|
||||
JS_SDK_GITHUB_BASE_REF: ${{ inputs.matrix-js-sdk-sha }}
|
||||
|
||||
- name: Jest Cache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: /tmp/jest_cache
|
||||
key: ${{ hashFiles('**/yarn.lock') }}
|
||||
|
||||
- name: Get number of CPU cores
|
||||
id: cpu-cores
|
||||
uses: SimenB/github-actions-cpu-cores@97ba232459a8e02ff6121db9362b09661c875ab8 # v2
|
||||
|
||||
- name: Run tests
|
||||
run: |
|
||||
yarn test \
|
||||
--coverage=${{ env.ENABLE_COVERAGE }} \
|
||||
--ci \
|
||||
--max-workers ${{ steps.cpu-cores.outputs.count }} \
|
||||
--shard ${{ matrix.runner }}/${{ strategy.job-total }} \
|
||||
--cacheDirectory /tmp/jest_cache
|
||||
env:
|
||||
JEST_SONAR_UNIQUE_OUTPUT_NAME: true
|
||||
|
||||
# tell jest to use coloured output
|
||||
FORCE_COLOR: true
|
||||
|
||||
- name: Move coverage files into place
|
||||
if: env.ENABLE_COVERAGE == 'true'
|
||||
run: mv coverage/lcov.info coverage/${{ steps.setupNode.outputs.node-version }}-${{ matrix.runner }}.lcov.info
|
||||
|
||||
- name: Upload Artifact
|
||||
if: env.ENABLE_COVERAGE == 'true'
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: coverage-${{ matrix.runner }}
|
||||
path: |
|
||||
coverage
|
||||
!coverage/lcov-report
|
||||
|
||||
complete:
|
||||
name: jest-tests
|
||||
needs: jest
|
||||
if: always()
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- if: needs.jest.result != 'skipped' && needs.jest.result != 'success'
|
||||
run: exit 1
|
||||
|
||||
- name: Skip SonarCloud in merge queue
|
||||
if: github.event_name == 'merge_group' || inputs.disable_coverage == 'true'
|
||||
uses: Sibz/github-status-action@faaa4d96fecf273bd762985e0e7f9f933c774918 # v1
|
||||
with:
|
||||
authToken: ${{ secrets.GITHUB_TOKEN }}
|
||||
state: success
|
||||
description: SonarCloud skipped
|
||||
context: SonarCloud Code Analysis
|
||||
sha: ${{ github.sha }}
|
||||
target_url: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}
|
||||
18
.github/workflows/triage-assigned.yml
vendored
Normal file
18
.github/workflows/triage-assigned.yml
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
name: Move issued assigned to specific team members to their boards
|
||||
|
||||
on:
|
||||
issues:
|
||||
types: [assigned]
|
||||
|
||||
jobs:
|
||||
web-app-team:
|
||||
runs-on: ubuntu-latest
|
||||
if: |
|
||||
contains(github.event.issue.assignees.*.login, 't3chguy') ||
|
||||
contains(github.event.issue.assignees.*.login, 'andybalaam') ||
|
||||
contains(github.event.issue.assignees.*.login, 'MidhunSureshR')
|
||||
steps:
|
||||
- uses: actions/add-to-project@main
|
||||
with:
|
||||
project-url: https://github.com/orgs/element-hq/projects/67
|
||||
github-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
14
.github/workflows/triage-incoming.yml
vendored
Normal file
14
.github/workflows/triage-incoming.yml
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
name: Move new issues into Issue triage board
|
||||
|
||||
on:
|
||||
issues:
|
||||
types: [opened]
|
||||
|
||||
jobs:
|
||||
automate-project-columns:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/add-to-project@main
|
||||
with:
|
||||
project-url: https://github.com/orgs/element-hq/projects/120
|
||||
github-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
176
.github/workflows/triage-labelled.yml
vendored
Normal file
176
.github/workflows/triage-labelled.yml
vendored
Normal file
@@ -0,0 +1,176 @@
|
||||
name: Move labelled issues to correct projects
|
||||
|
||||
on:
|
||||
issues:
|
||||
types: [labeled]
|
||||
workflow_call:
|
||||
secrets:
|
||||
ELEMENT_BOT_TOKEN:
|
||||
required: true
|
||||
|
||||
jobs:
|
||||
apply_Z-Labs_label:
|
||||
name: Add Z-Labs label for features behind labs flags
|
||||
runs-on: ubuntu-latest
|
||||
if: >
|
||||
contains(github.event.issue.labels.*.name, 'A-Maths') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-Location-Sharing') ||
|
||||
contains(github.event.issue.labels.*.name, 'Z-IA') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-Jump-To-Date ') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-Themes-Custom') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-E2EE-Dehydration') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-Tags') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-Video-Rooms') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-Message-Starring') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-Rich-Text-Editor') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-Element-Call')
|
||||
steps:
|
||||
- uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
github.rest.issues.addLabels({
|
||||
issue_number: context.issue.number,
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
labels: ['Z-Labs']
|
||||
})
|
||||
|
||||
apply_Help-Wanted_label:
|
||||
name: Add "Help Wanted" label to all "good first issue" and Hacktoberfest
|
||||
runs-on: ubuntu-latest
|
||||
if: >
|
||||
contains(github.event.issue.labels.*.name, 'good first issue') ||
|
||||
contains(github.event.issue.labels.*.name, 'Hacktoberfest')
|
||||
steps:
|
||||
- uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
github.rest.issues.addLabels({
|
||||
issue_number: context.issue.number,
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
labels: ['Help Wanted']
|
||||
})
|
||||
|
||||
move_needs_info_issues:
|
||||
name: X-Needs-Info issues to Need info column on triage board
|
||||
runs-on: ubuntu-latest
|
||||
if: >
|
||||
contains(github.event.issue.labels.*.name, 'X-Needs-Info')
|
||||
steps:
|
||||
- id: add_to_project
|
||||
uses: actions/add-to-project@v1.0.2
|
||||
with:
|
||||
project-url: ${{ env.PROJECT_URL }}
|
||||
github-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
|
||||
- id: set_fields
|
||||
uses: titoportas/update-project-fields@421a54430b3cdc9eefd8f14f9ce0142ab7678751 # v0.1.0
|
||||
with:
|
||||
project-url: ${{ env.PROJECT_URL }}
|
||||
github-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
item-id: ${{ steps.add_to_project.outputs.itemId }} # Use the item-id output of the previous step
|
||||
field-keys: Status
|
||||
field-values: "Needs info"
|
||||
env:
|
||||
PROJECT_URL: https://github.com/orgs/element-hq/projects/120
|
||||
|
||||
move_flakey_test_issues:
|
||||
name: Z-Flaky-Test issues to Sized for maintainer column on triage board
|
||||
runs-on: ubuntu-latest
|
||||
if: >
|
||||
contains(github.event.issue.labels.*.name, 'Z-Flaky-Test')
|
||||
steps:
|
||||
- id: add_to_project
|
||||
uses: actions/add-to-project@v1.0.2
|
||||
with:
|
||||
project-url: ${{ env.PROJECT_URL }}
|
||||
github-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
|
||||
- id: set_fields
|
||||
uses: titoportas/update-project-fields@421a54430b3cdc9eefd8f14f9ce0142ab7678751 # v0.1.0
|
||||
with:
|
||||
project-url: ${{ env.PROJECT_URL }}
|
||||
github-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
item-id: ${{ steps.add_to_project.outputs.itemId }} # Use the item-id output of the previous step
|
||||
field-keys: Status
|
||||
field-values: "Sized for maintainer"
|
||||
env:
|
||||
PROJECT_URL: https://github.com/orgs/element-hq/projects/120
|
||||
|
||||
add_priority_design_issues_to_project:
|
||||
name: P1 X-Needs-Design to Design project board
|
||||
runs-on: ubuntu-latest
|
||||
if: >
|
||||
contains(github.event.issue.labels.*.name, 'X-Needs-Design') &&
|
||||
(contains(github.event.issue.labels.*.name, 'S-Critical') &&
|
||||
(contains(github.event.issue.labels.*.name, 'O-Frequent') ||
|
||||
contains(github.event.issue.labels.*.name, 'O-Occasional')) ||
|
||||
contains(github.event.issue.labels.*.name, 'S-Major') &&
|
||||
contains(github.event.issue.labels.*.name, 'O-Frequent') ||
|
||||
contains(github.event.issue.labels.*.name, 'A11y'))
|
||||
steps:
|
||||
- uses: actions/add-to-project@main
|
||||
with:
|
||||
project-url: https://github.com/orgs/element-hq/projects/18
|
||||
github-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
|
||||
add_product_issues:
|
||||
name: X-Needs-Product to product project board
|
||||
runs-on: ubuntu-latest
|
||||
if: >
|
||||
contains(github.event.issue.labels.*.name, 'X-Needs-Product')
|
||||
steps:
|
||||
- uses: actions/add-to-project@main
|
||||
with:
|
||||
project-url: https://github.com/orgs/element-hq/projects/28
|
||||
github-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
|
||||
Search_issues_to_board:
|
||||
name: Search issues to project board
|
||||
runs-on: ubuntu-latest
|
||||
if: >
|
||||
contains(github.event.issue.labels.*.name, 'A-New-Search-Experience')
|
||||
steps:
|
||||
- uses: actions/add-to-project@main
|
||||
with:
|
||||
project-url: https://github.com/orgs/element-hq/projects/48
|
||||
github-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
|
||||
voip:
|
||||
name: Add labelled issues to VoIP project board
|
||||
runs-on: ubuntu-latest
|
||||
if: >
|
||||
contains(github.event.issue.labels.*.name, 'Team: VoIP')
|
||||
steps:
|
||||
- uses: actions/add-to-project@main
|
||||
with:
|
||||
project-url: https://github.com/orgs/element-hq/projects/41
|
||||
github-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
|
||||
verticals_feature:
|
||||
name: Add labelled issues to Verticals Feature project
|
||||
runs-on: ubuntu-latest
|
||||
if: >
|
||||
contains(github.event.issue.labels.*.name, 'Team: Verticals Feature')
|
||||
steps:
|
||||
- uses: actions/add-to-project@main
|
||||
with:
|
||||
project-url: https://github.com/orgs/element-hq/projects/57
|
||||
github-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
|
||||
tech_debt:
|
||||
name: Add labelled issues to tech debt project
|
||||
runs-on: ubuntu-latest
|
||||
if: >
|
||||
contains(github.event.issue.labels.*.name, 'A-Developer-Experience') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-Documentation') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-Packaging') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-Technical-Debt') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-Testing') ||
|
||||
contains(github.event.issue.labels.*.name, 'Z-Flaky-Test')
|
||||
steps:
|
||||
- uses: actions/add-to-project@main
|
||||
with:
|
||||
project-url: https://github.com/orgs/element-hq/projects/101
|
||||
github-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
139
.github/workflows/triage-move-review-requests.yml
vendored
Normal file
139
.github/workflows/triage-move-review-requests.yml
vendored
Normal file
@@ -0,0 +1,139 @@
|
||||
name: Move pull requests asking for review to the relevant project
|
||||
on:
|
||||
pull_request_target:
|
||||
types: [review_requested]
|
||||
|
||||
jobs:
|
||||
add_design_pr_to_project:
|
||||
name: Move PRs asking for design review to the design board
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: octokit/graphql-action@v2.x
|
||||
id: find_team_members
|
||||
with:
|
||||
headers: '{"GraphQL-Features": "projects_next_graphql"}'
|
||||
query: |
|
||||
query find_team_members($team: String!) {
|
||||
organization(login: "element-hq") {
|
||||
team(slug: $team) {
|
||||
members {
|
||||
nodes {
|
||||
login
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
team: ${{ env.TEAM }}
|
||||
env:
|
||||
TEAM: "design"
|
||||
GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
- id: any_matching_reviewers
|
||||
run: |
|
||||
# Fetch requested reviewers, and people who are on the team
|
||||
echo '${{ tojson(fromjson(steps.find_team_members.outputs.data).organization.team.members.nodes[*].login) }}' | tee /tmp/team_members.json
|
||||
echo '${{ tojson(github.event.pull_request.requested_reviewers[*].login) }}' | tee /tmp/reviewers.json
|
||||
jq --raw-output .[] < /tmp/team_members.json | sort | tee /tmp/team_members.txt
|
||||
jq --raw-output .[] < /tmp/reviewers.json | sort | tee /tmp/reviewers.txt
|
||||
|
||||
# Fetch requested team reviewers, and the name of the team
|
||||
echo '${{ tojson(github.event.pull_request.requested_teams[*].slug) }}' | tee /tmp/team_reviewers.json
|
||||
jq --raw-output .[] < /tmp/team_reviewers.json | sort | tee /tmp/team_reviewers.txt
|
||||
echo '${{ env.TEAM }}' | tee /tmp/team.txt
|
||||
|
||||
# If either a reviewer matches a team member, or a team matches our team, say "true"
|
||||
if [ $(join /tmp/team_members.txt /tmp/reviewers.txt | wc -l) != 0 ]; then
|
||||
echo "match=true" >> $GITHUB_OUTPUT
|
||||
elif [ $(join /tmp/team.txt /tmp/team_reviewers.txt | wc -l) != 0 ]; then
|
||||
echo "match=true" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "match=false" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
env:
|
||||
TEAM: "design"
|
||||
- uses: octokit/graphql-action@v2.x
|
||||
id: add_to_project
|
||||
if: steps.any_matching_reviewers.outputs.match == 'true'
|
||||
with:
|
||||
headers: '{"GraphQL-Features": "projects_next_graphql"}'
|
||||
query: |
|
||||
mutation add_to_project($projectid:ID!, $contentid:ID!) {
|
||||
addProjectV2ItemById(input: {projectId: $projectid contentId: $contentid}) {
|
||||
item {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
projectid: ${{ env.PROJECT_ID }}
|
||||
contentid: ${{ github.event.pull_request.node_id }}
|
||||
env:
|
||||
PROJECT_ID: "PVT_kwDOAM0swc0sUA"
|
||||
TEAM: "design"
|
||||
GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
|
||||
add_product_pr_to_project:
|
||||
name: Move PRs asking for design review to the design board
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: octokit/graphql-action@v2.x
|
||||
id: find_team_members
|
||||
with:
|
||||
headers: '{"GraphQL-Features": "projects_next_graphql"}'
|
||||
query: |
|
||||
query find_team_members($team: String!) {
|
||||
organization(login: "element-hq") {
|
||||
team(slug: $team) {
|
||||
members {
|
||||
nodes {
|
||||
login
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
team: ${{ env.TEAM }}
|
||||
env:
|
||||
TEAM: "product"
|
||||
GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
- id: any_matching_reviewers
|
||||
run: |
|
||||
# Fetch requested reviewers, and people who are on the team
|
||||
echo '${{ tojson(fromjson(steps.find_team_members.outputs.data).organization.team.members.nodes[*].login) }}' | tee /tmp/team_members.json
|
||||
echo '${{ tojson(github.event.pull_request.requested_reviewers[*].login) }}' | tee /tmp/reviewers.json
|
||||
jq --raw-output .[] < /tmp/team_members.json | sort | tee /tmp/team_members.txt
|
||||
jq --raw-output .[] < /tmp/reviewers.json | sort | tee /tmp/reviewers.txt
|
||||
|
||||
# Fetch requested team reviewers, and the name of the team
|
||||
echo '${{ tojson(github.event.pull_request.requested_teams[*].slug) }}' | tee /tmp/team_reviewers.json
|
||||
jq --raw-output .[] < /tmp/team_reviewers.json | sort | tee /tmp/team_reviewers.txt
|
||||
echo '${{ env.TEAM }}' | tee /tmp/team.txt
|
||||
|
||||
# If either a reviewer matches a team member, or a team matches our team, say "true"
|
||||
if [ $(join /tmp/team_members.txt /tmp/reviewers.txt | wc -l) != 0 ]; then
|
||||
echo "match=true" >> $GITHUB_OUTPUT
|
||||
elif [ $(join /tmp/team.txt /tmp/team_reviewers.txt | wc -l) != 0 ]; then
|
||||
echo "match=true" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "match=false" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
env:
|
||||
TEAM: "product"
|
||||
- uses: octokit/graphql-action@v2.x
|
||||
id: add_to_project
|
||||
if: steps.any_matching_reviewers.outputs.match == 'true'
|
||||
with:
|
||||
headers: '{"GraphQL-Features": "projects_next_graphql"}'
|
||||
query: |
|
||||
mutation add_to_project($projectid:ID!, $contentid:ID!) {
|
||||
addProjectV2ItemById(input: {projectId: $projectid contentId: $contentid}) {
|
||||
item {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
projectid: ${{ env.PROJECT_ID }}
|
||||
contentid: ${{ github.event.pull_request.node_id }}
|
||||
env:
|
||||
PROJECT_ID: "PVT_kwDOAM0swc4AAg6N"
|
||||
TEAM: "product"
|
||||
GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
18
.github/workflows/triage-stale-flaky-tests.yml
vendored
Normal file
18
.github/workflows/triage-stale-flaky-tests.yml
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
name: Close stale flaky issues
|
||||
on:
|
||||
schedule:
|
||||
- cron: "30 1 * * *"
|
||||
jobs:
|
||||
close:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
actions: write
|
||||
issues: write
|
||||
steps:
|
||||
- uses: actions/stale@v9
|
||||
with:
|
||||
only-labels: "Z-Flaky-Test"
|
||||
days-before-stale: 14
|
||||
days-before-close: 0
|
||||
close-issue-message: "This flaky test issue has not been updated in 14 days. It is being closed as presumed resolved."
|
||||
exempt-issue-labels: "Z-Flaky-Test-Disabled"
|
||||
71
.github/workflows/triage-unlabelled.yml
vendored
Normal file
71
.github/workflows/triage-unlabelled.yml
vendored
Normal file
@@ -0,0 +1,71 @@
|
||||
name: Move unlabelled from needs info columns to triaged
|
||||
|
||||
on:
|
||||
issues:
|
||||
types: [unlabeled]
|
||||
|
||||
jobs:
|
||||
Move_Unabeled_Issue_On_Project_Board:
|
||||
name: Move no longer X-Needs-Info issues to Triaged
|
||||
runs-on: ubuntu-latest
|
||||
if: >
|
||||
${{
|
||||
!contains(github.event.issue.labels.*.name, 'X-Needs-Info') }}
|
||||
env:
|
||||
BOARD_NAME: "Issue triage"
|
||||
OWNER: ${{ github.repository_owner }}
|
||||
REPO: ${{ github.event.repository.name }}
|
||||
ISSUE: ${{ github.event.issue.number }}
|
||||
steps:
|
||||
- name: Check if issue is already in "${{ env.BOARD_NAME }}"
|
||||
run: |
|
||||
json=$(curl -s -H 'Content-Type: application/json' -H "Authorization: bearer ${{ secrets.GITHUB_TOKEN }}" -X POST -d '{"query": "query($issue: Int!, $owner: String!, $repo: String!) { repository(owner: $owner, name: $repo) { issue(number: $issue) { projectCards { nodes { project { name } isArchived } } } } } ", "variables" : "{ \"issue\": '${ISSUE}', \"owner\": \"'${OWNER}'\", \"repo\": \"'${REPO}'\" }" }' https://api.github.com/graphql)
|
||||
if echo $json | jq '.data.repository.issue.projectCards.nodes | length'; then
|
||||
if [[ $(echo $json | jq '.data.repository.issue.projectCards.nodes[0].project.name') =~ "${BOARD_NAME}" ]]; then
|
||||
if [[ $(echo $json | jq '.data.repository.issue.projectCards.nodes[0].isArchived') == 'true' ]]; then
|
||||
echo "Issue is already in Project '$BOARD_NAME', but is archived - skipping workflow";
|
||||
echo "SKIP_ACTION=true" >> $GITHUB_ENV
|
||||
else
|
||||
echo "Issue is already in Project '$BOARD_NAME', proceeding";
|
||||
echo "ALREADY_IN_BOARD=true" >> $GITHUB_ENV
|
||||
fi
|
||||
else
|
||||
echo "Issue is not in project '$BOARD_NAME', cancelling this workflow"
|
||||
echo "ALREADY_IN_BOARD=false" >> $GITHUB_ENV
|
||||
fi
|
||||
fi
|
||||
- name: Move issue
|
||||
uses: alex-page/github-project-automation-plus@303f24a24c67ce7adf565a07e96720faf126fe36
|
||||
if: ${{ env.ALREADY_IN_BOARD == 'true' && env.SKIP_ACTION != 'true' }}
|
||||
with:
|
||||
project: Issue triage
|
||||
column: Triaged
|
||||
repo-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
|
||||
remove_Z-Labs_label:
|
||||
name: Remove Z-Labs label when features behind labs flags are removed
|
||||
runs-on: ubuntu-latest
|
||||
if: >
|
||||
!(contains(github.event.issue.labels.*.name, 'A-Maths') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-Message-Pinning') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-Location-Sharing') ||
|
||||
contains(github.event.issue.labels.*.name, 'Z-IA') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-Jump-To-Date') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-Themes-Custom') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-E2EE-Dehydration') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-Tags') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-Video-Rooms') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-Message-Starring') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-Rich-Text-Editor') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-Element-Call')) &&
|
||||
contains(github.event.issue.labels.*.name, 'Z-Labs')
|
||||
steps:
|
||||
- uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
github.rest.issues.removeLabel({
|
||||
issue_number: context.issue.number,
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
name: ['Z-Labs']
|
||||
})
|
||||
32
.github/workflows/update-jitsi.yml
vendored
Normal file
32
.github/workflows/update-jitsi.yml
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
# Re-fetches the Jitsi SDK and opens a PR to update it if it's different from what's in the repository
|
||||
name: Update Jitsi
|
||||
on:
|
||||
workflow_dispatch: {}
|
||||
schedule:
|
||||
- cron: "0 3 * * 0" # 3am every Sunday
|
||||
jobs:
|
||||
update:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
cache: "yarn"
|
||||
node-version: "lts/*"
|
||||
|
||||
- name: Install Deps
|
||||
run: "yarn install --frozen-lockfile"
|
||||
|
||||
- name: Fetch Jitsi
|
||||
run: "yarn update:jitsi"
|
||||
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@5e914681df9dc83aa4e4905692ca88beb2f9e91f # v7
|
||||
with:
|
||||
token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
branch: actions/jitsi-update
|
||||
delete-branch: true
|
||||
title: Jitsi Update
|
||||
labels: |
|
||||
T-Task
|
||||
102
.github/workflows/update-topics.yaml
vendored
Normal file
102
.github/workflows/update-topics.yaml
vendored
Normal file
@@ -0,0 +1,102 @@
|
||||
name: Update release topics
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
expected_status:
|
||||
description: What type of release is the next expected release
|
||||
required: true
|
||||
default: RC
|
||||
type: choice
|
||||
options:
|
||||
- RC
|
||||
- Release
|
||||
expected_date:
|
||||
description: Expected release date e.g. July 11th
|
||||
required: true
|
||||
type: string
|
||||
concurrency: ${{ github.workflow }}
|
||||
jobs:
|
||||
bot:
|
||||
name: Release topic update
|
||||
runs-on: ubuntu-latest
|
||||
environment: Matrix
|
||||
steps:
|
||||
- uses: actions/github-script@v7
|
||||
env:
|
||||
HS_URL: ${{ secrets.BETABOT_HS_URL }}
|
||||
LOBBY_ROOM_ID: ${{ secrets.ROOM_ID }}
|
||||
PUBLIC_ROOM_ID: "!YTvKGNlinIzlkMTVRl:matrix.org"
|
||||
ANNOUNCEMENT_ROOM_ID: "!bijaLdadorKgNGtHdA:matrix.org"
|
||||
TOKEN: ${{ secrets.BETABOT_ACCESS_TOKEN }}
|
||||
RELEASE_STATUS: "Release status: ${{ inputs.expected_status }} expected ${{ inputs.expected_date }}"
|
||||
with:
|
||||
script: |
|
||||
const { HS_URL, TOKEN, RELEASE_STATUS, LOBBY_ROOM_ID, PUBLIC_ROOM_ID, ANNOUNCEMENT_ROOM_ID } = process.env;
|
||||
|
||||
const repo = context.repo;
|
||||
const { data } = await github.rest.repos.getLatestRelease({
|
||||
owner: repo.owner,
|
||||
repo: repo.repo,
|
||||
});
|
||||
console.log("Found latest version: " + data.tag_name);
|
||||
|
||||
const releaseTopic = `Stable: ${data.tag_name} | ${RELEASE_STATUS}`;
|
||||
console.log("Release topic: " + releaseTopic);
|
||||
|
||||
const regex = /Stable: v(.+) \| Release status: (\w+) expected (\w+ \d+\w\w)/gm;
|
||||
|
||||
async function updateReleaseInTopic(roomId) {
|
||||
const apiUrl = `${HS_URL}/_matrix/client/v3/rooms/${roomId}/state/m.room.topic/`;
|
||||
const headers = {
|
||||
"Content-Type": "application/json",
|
||||
"Authorization": `Bearer ${TOKEN}`,
|
||||
};
|
||||
await fetch(`${HS_URL}/_matrix/client/v3/rooms/${roomId}/join`, {
|
||||
method: "POST",
|
||||
headers,
|
||||
body: "{}",
|
||||
});
|
||||
|
||||
let res = await fetch(apiUrl, {
|
||||
method: "GET",
|
||||
headers,
|
||||
});
|
||||
|
||||
if (!res.ok) {
|
||||
console.log(roomId, "failed to fetch", await res.text());
|
||||
return;
|
||||
}
|
||||
|
||||
const data = await res.json();
|
||||
console.log(roomId, "got event", data);
|
||||
|
||||
const topic = data.topic.replace(regex, releaseTopic);
|
||||
if (topic === data.topic) {
|
||||
console.log(roomId, "nothing to do");
|
||||
return;
|
||||
}
|
||||
if (data["org.matrix.msc3765.topic"]) {
|
||||
data["org.matrix.msc3765.topic"].forEach(d => {
|
||||
d.body = d.body.replace(regex, releaseTopic);
|
||||
});
|
||||
}
|
||||
|
||||
res = await fetch(apiUrl, {
|
||||
method: "PUT",
|
||||
body: JSON.stringify({
|
||||
...data,
|
||||
topic,
|
||||
}),
|
||||
headers,
|
||||
});
|
||||
|
||||
if (res.ok) {
|
||||
console.log(roomId, "topic updated:", topic);
|
||||
} else {
|
||||
console.log(roomId, await res.text());
|
||||
}
|
||||
}
|
||||
|
||||
await updateReleaseInTopic(LOBBY_ROOM_ID);
|
||||
await updateReleaseInTopic(PUBLIC_ROOM_ID);
|
||||
await updateReleaseInTopic(ANNOUNCEMENT_ROOM_ID);
|
||||
10
.gitignore
vendored
10
.gitignore
vendored
@@ -16,8 +16,18 @@ electron/pub
|
||||
/config.json
|
||||
/config.json.*
|
||||
/config.local*.json
|
||||
# Legacy skinning file that some people might still have
|
||||
/src/component-index.js
|
||||
/.tmp
|
||||
/webpack-stats.json
|
||||
.vscode
|
||||
.vscode/
|
||||
.env
|
||||
/coverage
|
||||
# Auto-generated file
|
||||
/src/modules.ts
|
||||
/build_config.yaml
|
||||
/book
|
||||
/index.html
|
||||
# version file and tarball created by `npm pack` / `yarn pack`
|
||||
/git-revision.txt
|
||||
|
||||
4
.husky/pre-commit
Executable file
4
.husky/pre-commit
Executable file
@@ -0,0 +1,4 @@
|
||||
#!/usr/bin/env sh
|
||||
. "$(dirname "$0")/_/husky.sh"
|
||||
|
||||
npx lint-staged --concurrent false
|
||||
7
.lintstagedrc
Normal file
7
.lintstagedrc
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"*": "prettier --write",
|
||||
"src/**/*.(ts|tsx)": ["eslint --fix"],
|
||||
"scripts/**/*.(ts|tsx)": ["eslint --fix"],
|
||||
"module_system/**/*.(ts|tsx)": ["eslint --fix --config .eslintrc-module_system.js module_system"],
|
||||
"*.pcss": ["stylelint --fix"]
|
||||
}
|
||||
@@ -1,35 +1,37 @@
|
||||
{
|
||||
"minify": true,
|
||||
"enableClasses": false,
|
||||
"feature-detects": [
|
||||
"test/css/animations",
|
||||
"test/css/displaytable",
|
||||
"test/css/filters",
|
||||
"test/css/flexbox",
|
||||
"test/css/objectfit",
|
||||
"minify": false,
|
||||
"enableClasses": false,
|
||||
"feature-detects": [
|
||||
"test/css/animations",
|
||||
"test/css/displaytable",
|
||||
"test/css/filters",
|
||||
"test/css/flexbox",
|
||||
"test/css/objectfit",
|
||||
|
||||
"test/es5/date",
|
||||
"test/es5/function",
|
||||
"test/es5/object",
|
||||
"test/es5/undefined",
|
||||
"test/es5/date",
|
||||
"test/es5/function",
|
||||
"test/es5/object",
|
||||
"test/es5/undefined",
|
||||
|
||||
"test/es6/array",
|
||||
"test/es6/collections",
|
||||
"test/es6/promises",
|
||||
"test/es6/string",
|
||||
"test/es6/array",
|
||||
"test/es6/collections",
|
||||
"test/es6/promises",
|
||||
"test/es6/string",
|
||||
|
||||
"test/svg",
|
||||
"test/svg/asimg",
|
||||
"test/svg/filters",
|
||||
"test/svg",
|
||||
"test/svg/asimg",
|
||||
"test/svg/filters",
|
||||
|
||||
"test/url/parser",
|
||||
"test/url/urlsearchparams",
|
||||
"test/url/parser",
|
||||
"test/url/urlsearchparams",
|
||||
|
||||
"test/cors",
|
||||
"test/crypto",
|
||||
"test/iframe/sandbox",
|
||||
"test/json",
|
||||
"test/network/fetch",
|
||||
"test/storage/localstorage"
|
||||
]
|
||||
"test/cors",
|
||||
"test/crypto",
|
||||
"test/iframe/sandbox",
|
||||
"test/json",
|
||||
"test/network/fetch",
|
||||
"test/storage/localstorage",
|
||||
"test/window/resizeobserver",
|
||||
"test/audio/webaudio"
|
||||
]
|
||||
}
|
||||
|
||||
1
.node-version
Normal file
1
.node-version
Normal file
@@ -0,0 +1 @@
|
||||
20
|
||||
41
.prettierignore
Normal file
41
.prettierignore
Normal file
@@ -0,0 +1,41 @@
|
||||
/build
|
||||
/dist
|
||||
/lib
|
||||
/node_modules
|
||||
/packages/
|
||||
/webapp
|
||||
/*.log
|
||||
yarn.lock
|
||||
electron/dist
|
||||
electron/pub
|
||||
**/.idea
|
||||
/.tmp
|
||||
/webpack-stats.json
|
||||
.vscode
|
||||
.vscode/
|
||||
.env
|
||||
/coverage
|
||||
# Auto-generated file
|
||||
/src/modules.ts
|
||||
/src/i18n/strings
|
||||
/build_config.yaml
|
||||
# Raises an error because it contains a template var breaking the script tag
|
||||
src/vector/index.html
|
||||
src/vector/modernizr.js
|
||||
/docs/lib
|
||||
/book
|
||||
/debian/tmp
|
||||
/.npmrc
|
||||
package-lock.json
|
||||
|
||||
# This file is owned, parsed, and generated by allchange, which doesn't comply with prettier
|
||||
/CHANGELOG.md
|
||||
/docs/changelogs
|
||||
|
||||
# Legacy skinning file that some people might still have
|
||||
/src/component-index.js
|
||||
|
||||
# Downloaded and already minified
|
||||
res/jitsi_external_api.min.js
|
||||
# This file is also machine-generated
|
||||
/playwright/e2e/crypto/test_indexeddb_cryptostore_dump/dump.json
|
||||
1
.prettierrc.cjs
Normal file
1
.prettierrc.cjs
Normal file
@@ -0,0 +1 @@
|
||||
module.exports = require("eslint-plugin-matrix-org/.prettierrc.js");
|
||||
1
.prettierrc.js
Normal file
1
.prettierrc.js
Normal file
@@ -0,0 +1 @@
|
||||
module.exports = require("eslint-plugin-matrix-org/.prettierrc.js");
|
||||
@@ -1,26 +1,50 @@
|
||||
// Copied from react-sdk
|
||||
// TODO: Only keep one copy of this for synchronization purposes
|
||||
module.exports = {
|
||||
"extends": "stylelint-config-standard",
|
||||
"plugins": [
|
||||
"stylelint-scss",
|
||||
],
|
||||
"rules": {
|
||||
"indentation": 4,
|
||||
extends: ["stylelint-config-standard"],
|
||||
customSyntax: require("postcss-scss"),
|
||||
plugins: ["stylelint-scss"],
|
||||
rules: {
|
||||
"comment-empty-line-before": null,
|
||||
"declaration-empty-line-before": null,
|
||||
"length-zero-no-unit": null,
|
||||
"rule-empty-line-before": null,
|
||||
"color-hex-length": null,
|
||||
"max-empty-lines": null,
|
||||
"number-no-trailing-zeros": null,
|
||||
"number-leading-zero": null,
|
||||
"selector-list-comma-newline-after": null,
|
||||
"at-rule-no-unknown": null,
|
||||
"no-descending-specificity": null,
|
||||
"scss/at-rule-no-unknown": [true, {
|
||||
// https://github.com/vector-im/element-web/issues/10544
|
||||
"ignoreAtRules": ["define-mixin"],
|
||||
}],
|
||||
}
|
||||
"scss/at-rule-no-unknown": [
|
||||
true,
|
||||
{
|
||||
// https://github.com/vector-im/element-web/issues/10544
|
||||
ignoreAtRules: ["define-mixin"],
|
||||
},
|
||||
],
|
||||
// Disable `&_kind`-style selectors while our unused CSS approach is "Find & Replace All"
|
||||
// rather than a CI thing. Shorthand selectors are harder to detect when searching for a
|
||||
// class name. This regex is trying to *allow* anything except `&words`, such as `&::before`,
|
||||
// `&.mx_Class`, etc.
|
||||
"selector-nested-pattern": "^((&[ :.\\[,])|([^&]))",
|
||||
// Disable some defaults
|
||||
"selector-class-pattern": null,
|
||||
"custom-property-pattern": null,
|
||||
"selector-id-pattern": null,
|
||||
"keyframes-name-pattern": null,
|
||||
"alpha-value-notation": null,
|
||||
"color-function-notation": null,
|
||||
"selector-not-notation": null,
|
||||
"import-notation": null,
|
||||
"value-keyword-case": null,
|
||||
"declaration-block-no-redundant-longhand-properties": null,
|
||||
"declaration-block-no-duplicate-properties": [
|
||||
true,
|
||||
// useful for fallbacks
|
||||
{ ignore: ["consecutive-duplicates-with-different-values"] },
|
||||
],
|
||||
"shorthand-property-no-redundant-values": null,
|
||||
"property-no-vendor-prefix": null,
|
||||
"value-no-vendor-prefix": null,
|
||||
"selector-no-vendor-prefix": null,
|
||||
"media-feature-name-no-vendor-prefix": null,
|
||||
"number-max-precision": null,
|
||||
"no-invalid-double-slash-comments": true,
|
||||
"media-feature-range-notation": null,
|
||||
},
|
||||
};
|
||||
|
||||
5634
CHANGELOG.md
5634
CHANGELOG.md
File diff suppressed because it is too large
Load Diff
301
CONTRIBUTING.md
301
CONTRIBUTING.md
@@ -1,4 +1,299 @@
|
||||
Contributing code to Element
|
||||
============================
|
||||
# Contributing code to Element Web
|
||||
|
||||
Element follows the same pattern as https://github.com/matrix-org/matrix-js-sdk/blob/master/CONTRIBUTING.rst.
|
||||
Everyone is welcome to contribute code to Element Web, provided that they are willing to license their contributions to Element under a [Contributor License Agreement](https://cla-assistant.io/element-hq/element-web) (CLA). This ensures that their contribution will be made available under an OSI-approved open-source license, currently licensed under Affero General Public License v3 (AGPLv3) or General Public License v3 (GPLv3) at your choice.
|
||||
|
||||
## How to contribute
|
||||
|
||||
The preferred and easiest way to contribute changes to the project is to fork
|
||||
it on github, and then create a pull request to ask us to pull your changes
|
||||
into our repo (https://help.github.com/articles/using-pull-requests/)
|
||||
|
||||
We use GitHub's pull request workflow to review the contribution, and either
|
||||
ask you to make any refinements needed or merge it and make them ourselves.
|
||||
|
||||
Your PR should have a title that describes what change is being made. This
|
||||
is used for the text in the Changelog entry by default (see below), so a good
|
||||
title will tell a user succinctly what change is being made. "Fix bug where
|
||||
cows had five legs" and, "Add support for miniature horses" are examples of good
|
||||
titles. Don't include an issue number here: that belongs in the description.
|
||||
Definitely don't use the GitHub default of "Update file.ts".
|
||||
|
||||
As for your PR description, it should include these things:
|
||||
|
||||
- References to any bugs fixed by the change (in GitHub's `Fixes` notation)
|
||||
- Describe the why and what is changing in the PR description so it's easy for
|
||||
onlookers and reviewers to onboard and context switch. This information is
|
||||
also helpful when we come back to look at this in 6 months and ask "why did
|
||||
we do it like that?" we have a chance of finding out.
|
||||
- Why didn't it work before? Why does it work now? What use cases does it
|
||||
unlock?
|
||||
- If you find yourself adding information on how the code works or why you
|
||||
chose to do it the way you did, make sure this information is instead
|
||||
written as comments in the code itself.
|
||||
- Sometimes a PR can change considerably as it is developed. In this case,
|
||||
the description should be updated to reflect the most recent state of
|
||||
the PR. (It can be helpful to retain the old content under a suitable
|
||||
heading, for additional context.)
|
||||
- Include both **before** and **after** screenshots to easily compare and discuss
|
||||
what's changing.
|
||||
- Include a step-by-step testing strategy so that a reviewer can check out the
|
||||
code locally and easily get to the point of testing your change.
|
||||
- Add comments to the diff for the reviewer that might help them to understand
|
||||
why the change is necessary or how they might better understand and review it.
|
||||
|
||||
### Changelogs
|
||||
|
||||
There's no need to manually add Changelog entries: we use information in the
|
||||
pull request to populate the information that goes into the changelogs our
|
||||
users see, both for Element Web itself and other projects on which it is based.
|
||||
This is picked up from both labels on the pull request and the `Notes:`
|
||||
annotation in the description. By default, the PR title will be used for the
|
||||
changelog entry, but you can specify more options, as follows.
|
||||
|
||||
To add a longer, more detailed description of the change for the changelog:
|
||||
|
||||
_Fix llama herding bug_
|
||||
|
||||
```
|
||||
Notes: Fix a bug (https://github.com/matrix-org/notaproject/issues/123) where the 'Herd' button would not herd more than 8 Llamas if the moon was in the waxing gibbous phase
|
||||
```
|
||||
|
||||
For some PRs, it's not useful to have an entry in the user-facing changelog (this is
|
||||
the default for PRs labelled with `T-Task`):
|
||||
|
||||
_Remove outdated comment from `Ungulates.ts`_
|
||||
|
||||
```
|
||||
Notes: none
|
||||
```
|
||||
|
||||
Sometimes, you're fixing a bug in a downstream project, in which case you want
|
||||
an entry in that project's changelog. You can do that too:
|
||||
|
||||
_Fix another herding bug_
|
||||
|
||||
```
|
||||
Notes: Fix a bug where the `herd()` function would only work on Tuesdays
|
||||
element-web notes: Fix a bug where the 'Herd' button only worked on Tuesdays
|
||||
```
|
||||
|
||||
This example is for Element Web. You can specify:
|
||||
|
||||
- element-web
|
||||
- element-desktop
|
||||
|
||||
If your PR introduces a breaking change, use the `Notes` section in the same
|
||||
way, additionally adding the `X-Breaking-Change` label (see below). There's no need
|
||||
to specify in the notes that it's a breaking change - this will be added
|
||||
automatically based on the label - but remember to tell the developer how to
|
||||
migrate:
|
||||
|
||||
_Remove legacy class_
|
||||
|
||||
```
|
||||
Notes: Remove legacy `Camelopard` class. `Giraffe` should be used instead.
|
||||
```
|
||||
|
||||
Other metadata can be added using labels.
|
||||
|
||||
- `X-Breaking-Change`: A breaking change - adding this label will mean the change causes a _major_ version bump.
|
||||
- `T-Enhancement`: A new feature - adding this label will mean the change causes a _minor_ version bump.
|
||||
- `T-Defect`: A bug fix (in either code or docs).
|
||||
- `T-Task`: No user-facing changes, eg. code comments, CI fixes, refactors or tests. Won't have a changelog entry unless you specify one.
|
||||
|
||||
If you don't have permission to add labels, your PR reviewer(s) can work with you
|
||||
to add them: ask in the PR description or comments.
|
||||
|
||||
We use continuous integration, and all pull requests get automatically tested:
|
||||
if your change breaks the build, then the PR will show that there are failed
|
||||
checks, so please check back after a few minutes.
|
||||
|
||||
## Tests
|
||||
|
||||
Your PR should include tests.
|
||||
|
||||
For new user facing features in `matrix-js-sdk` or `element-web`, you must include:
|
||||
|
||||
1. Comprehensive unit tests written in Jest. These are located in `/test`.
|
||||
2. "happy path" end-to-end tests.
|
||||
These are located in `/playwright/e2e`, and are run using `element-web`.
|
||||
Ideally, you would also include tests for edge and error cases.
|
||||
|
||||
Unit tests are expected even when the feature is in labs. It's good practice
|
||||
to write tests alongside the code as it ensures the code is testable from
|
||||
the start, and gives you a fast feedback loop while you're developing the
|
||||
functionality. End-to-end tests should be added prior to the feature
|
||||
leaving labs, but don't have to be present from the start (although it might
|
||||
be beneficial to have some running early, so you can test things faster).
|
||||
|
||||
For bugs in those repos, your change must include at least one unit test or
|
||||
end-to-end test; which is best depends on what sort of test most concisely
|
||||
exercises the area.
|
||||
|
||||
Changes to must be accompanied by unit tests written in Jest.
|
||||
These are located in `/spec/` in `matrix-js-sdk` or `/test/` in `element-web`.
|
||||
|
||||
When writing unit tests, please aim for a high level of test coverage
|
||||
for new code - 80% or greater. If you cannot achieve that, please document
|
||||
why it's not possible in your PR.
|
||||
|
||||
Some sections of code are not sensible to add coverage for, such as those
|
||||
which explicitly inhibit noisy logging for tests. Which can be hidden using
|
||||
an istanbul magic comment as [documented here][1]. See example:
|
||||
|
||||
```javascript
|
||||
/* istanbul ignore if */
|
||||
if (process.env.NODE_ENV !== "test") {
|
||||
logger.error("Log line that is noisy enough in tests to want to skip");
|
||||
}
|
||||
```
|
||||
|
||||
Tests validate that your change works as intended and also document
|
||||
concisely what is being changed. Ideally, your new tests fail
|
||||
prior to your change, and succeed once it has been applied. You may
|
||||
find this simpler to achieve if you write the tests first.
|
||||
|
||||
If you're spiking some code that's experimental and not being used to support
|
||||
production features, exceptions can be made to requirements for tests.
|
||||
Note that tests will still be required in order to ship the feature, and it's
|
||||
strongly encouraged to think about tests early in the process, as adding
|
||||
tests later will become progressively more difficult.
|
||||
|
||||
If you're not sure how to approach writing tests for your change, ask for help
|
||||
in [#element-dev](https://matrix.to/#/#element-dev:matrix.org).
|
||||
|
||||
## Code style
|
||||
|
||||
Element Web aims to target TypeScript/ES6. All new files should be written in
|
||||
TypeScript and existing files should use ES6 principles where possible.
|
||||
|
||||
Members should not be exported as a default export in general - it causes problems
|
||||
with the architecture of the SDK (index file becomes less clear) and could
|
||||
introduce naming problems (as default exports get aliased upon import). In
|
||||
general, avoid using `export default`.
|
||||
|
||||
The remaining code style is documented in [code_style.md](./code_style.md).
|
||||
Contributors are encouraged to it and follow the principles set out there.
|
||||
|
||||
Please ensure your changes match the cosmetic style of the existing project,
|
||||
and **_never_** mix cosmetic and functional changes in the same commit, as it
|
||||
makes it horribly hard to review otherwise.
|
||||
|
||||
## Attribution
|
||||
|
||||
Everyone who contributes anything to Matrix is welcome to be listed in the
|
||||
AUTHORS.rst file for the project in question. Please feel free to include a
|
||||
change to AUTHORS.rst in your pull request to list yourself and a short
|
||||
description of the area(s) you've worked on. Also, we sometimes have swag to
|
||||
give away to contributors - if you feel that Matrix-branded apparel is missing
|
||||
from your life, please mail us your shipping address to matrix at matrix.org
|
||||
and we'll try to fix it :)
|
||||
|
||||
## Sign off
|
||||
|
||||
In order to have a concrete record that your contribution is intentional
|
||||
and you agree to license it under the same terms as the project's license, we've
|
||||
adopted the same lightweight approach that the Linux Kernel
|
||||
(https://www.kernel.org/doc/html/latest/process/submitting-patches.html), Docker
|
||||
(https://github.com/docker/docker/blob/master/CONTRIBUTING.md), and many other
|
||||
projects use: the DCO (Developer Certificate of Origin:
|
||||
http://developercertificate.org/). This is a simple declaration that you wrote
|
||||
the contribution or otherwise have the right to contribute it to Matrix:
|
||||
|
||||
```
|
||||
Developer Certificate of Origin
|
||||
Version 1.1
|
||||
|
||||
Copyright (C) 2004, 2006 The Linux Foundation and its contributors.
|
||||
660 York Street, Suite 102,
|
||||
San Francisco, CA 94110 USA
|
||||
|
||||
Everyone is permitted to copy and distribute verbatim copies of this
|
||||
license document, but changing it is not allowed.
|
||||
|
||||
Developer's Certificate of Origin 1.1
|
||||
|
||||
By making a contribution to this project, I certify that:
|
||||
|
||||
(a) The contribution was created in whole or in part by me and I
|
||||
have the right to submit it under the open source license
|
||||
indicated in the file; or
|
||||
|
||||
(b) The contribution is based upon previous work that, to the best
|
||||
of my knowledge, is covered under an appropriate open source
|
||||
license and I have the right under that license to submit that
|
||||
work with modifications, whether created in whole or in part
|
||||
by me, under the same open source license (unless I am
|
||||
permitted to submit under a different license), as indicated
|
||||
in the file; or
|
||||
|
||||
(c) The contribution was provided directly to me by some other
|
||||
person who certified (a), (b) or (c) and I have not modified
|
||||
it.
|
||||
|
||||
(d) I understand and agree that this project and the contribution
|
||||
are public and that a record of the contribution (including all
|
||||
personal information I submit with it, including my sign-off) is
|
||||
maintained indefinitely and may be redistributed consistent with
|
||||
this project or the open source license(s) involved.
|
||||
```
|
||||
|
||||
If you agree to this for your contribution, then all that's needed is to
|
||||
include the line in your commit or pull request comment:
|
||||
|
||||
```
|
||||
Signed-off-by: Your Name <your@email.example.org>
|
||||
```
|
||||
|
||||
We accept contributions under a legally identifiable name, such as your name on
|
||||
government documentation or common-law names (names claimed by legitimate usage
|
||||
or repute). Unfortunately, we cannot accept anonymous contributions at this
|
||||
time.
|
||||
|
||||
Git allows you to add this signoff automatically when using the `-s` flag to
|
||||
`git commit`, which uses the name and email set in your `user.name` and
|
||||
`user.email` git configs.
|
||||
|
||||
If you forgot to sign off your commits before making your pull request and are
|
||||
on Git 2.17+ you can mass signoff using rebase:
|
||||
|
||||
```
|
||||
git rebase --signoff origin/develop
|
||||
```
|
||||
|
||||
## Private sign off
|
||||
|
||||
If you would like to provide your legal name privately to the Matrix.org
|
||||
Foundation (instead of in a public commit or comment), you can do so by emailing
|
||||
your legal name and a link to the pull request to dco@matrix.org. It helps to
|
||||
include "sign off" or similar in the subject line. You will then be instructed
|
||||
further.
|
||||
|
||||
Once private sign off is complete, doing so for future contributions will not
|
||||
be required.
|
||||
|
||||
# Review expectations
|
||||
|
||||
See https://github.com/element-hq/element-meta/wiki/Review-process
|
||||
|
||||
# Merge Strategy
|
||||
|
||||
The preferred method for merging pull requests is squash merging to keep the
|
||||
commit history trim, but it is up to the discretion of the team member merging
|
||||
the change. We do not support rebase merges due to `allchange` being unable to
|
||||
handle them. When merging make sure to leave the default commit title, or
|
||||
at least leave the PR number at the end in brackets like by default.
|
||||
When stacking pull requests, you may wish to do the following:
|
||||
|
||||
1. Branch from develop to your branch (branch1), push commits onto it and open a pull request
|
||||
2. Branch from your base branch (branch1) to your work branch (branch2), push commits and open a pull request configuring the base to be branch1, saying in the description that it is based on your other PR.
|
||||
3. Merge the first PR using a merge commit otherwise your stacked PR will need a rebase. Github will automatically adjust the base branch of your other PR to be develop.
|
||||
|
||||
[1]: https://github.com/gotwarlost/istanbul/blob/master/ignoring-code-for-coverage.md
|
||||
|
||||
# Decoding Stack Traces
|
||||
|
||||
Element Web has crashed and given you an obfuscated stack trace? Don't panic:
|
||||
use the [Decoder Ring](https://app.element.io/decoder-ring/) (or /decoder-ring/
|
||||
on any Element Web deploy). It is somewhat of a manual process, but it should
|
||||
tell you what lines the stack trace corresponds to from the source maps.
|
||||
|
||||
22
Dockerfile
22
Dockerfile
@@ -1,11 +1,8 @@
|
||||
# Builder
|
||||
FROM node:14-buster as builder
|
||||
FROM --platform=$BUILDPLATFORM node:20-bullseye as builder
|
||||
|
||||
# Support custom branches of the react-sdk and js-sdk. This also helps us build
|
||||
# images of element-web develop.
|
||||
# Support custom branch of the js-sdk. This also helps us build images of element-web develop.
|
||||
ARG USE_CUSTOM_SDKS=false
|
||||
ARG REACT_SDK_REPO="https://github.com/matrix-org/matrix-react-sdk.git"
|
||||
ARG REACT_SDK_BRANCH="master"
|
||||
ARG JS_SDK_REPO="https://github.com/matrix-org/matrix-js-sdk.git"
|
||||
ARG JS_SDK_BRANCH="master"
|
||||
|
||||
@@ -15,23 +12,20 @@ WORKDIR /src
|
||||
|
||||
COPY . /src
|
||||
RUN dos2unix /src/scripts/docker-link-repos.sh && bash /src/scripts/docker-link-repos.sh
|
||||
RUN yarn --network-timeout=100000 install
|
||||
RUN yarn build
|
||||
RUN yarn --network-timeout=200000 install
|
||||
|
||||
RUN dos2unix /src/scripts/docker-package.sh /src/scripts/get-version-from-git.sh /src/scripts/normalize-version.sh && bash /src/scripts/docker-package.sh
|
||||
|
||||
# Copy the config now so that we don't create another layer in the app image
|
||||
RUN cp /src/config.sample.json /src/webapp/config.json
|
||||
|
||||
# Ensure we populate the version file
|
||||
RUN dos2unix /src/scripts/docker-write-version.sh && bash /src/scripts/docker-write-version.sh
|
||||
|
||||
|
||||
# App
|
||||
FROM nginx:alpine
|
||||
FROM nginx:alpine-slim
|
||||
|
||||
COPY --from=builder /src/webapp /app
|
||||
|
||||
# Insert wasm type into Nginx mime.types file so they load correctly.
|
||||
RUN sed -i '3i\ \ \ \ application/wasm wasm\;' /etc/nginx/mime.types
|
||||
# Override default nginx config
|
||||
COPY /nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf
|
||||
|
||||
RUN rm -rf /usr/share/nginx/html \
|
||||
&& ln -s /app /usr/share/nginx/html
|
||||
|
||||
661
LICENSE-AGPL-3.0
Normal file
661
LICENSE-AGPL-3.0
Normal file
@@ -0,0 +1,661 @@
|
||||
GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
Version 3, 19 November 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU Affero General Public License is a free, copyleft license for
|
||||
software and other kinds of works, specifically designed to ensure
|
||||
cooperation with the community in the case of network server software.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
our General Public Licenses are intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
Developers that use our General Public Licenses protect your rights
|
||||
with two steps: (1) assert copyright on the software, and (2) offer
|
||||
you this License which gives you legal permission to copy, distribute
|
||||
and/or modify the software.
|
||||
|
||||
A secondary benefit of defending all users' freedom is that
|
||||
improvements made in alternate versions of the program, if they
|
||||
receive widespread use, become available for other developers to
|
||||
incorporate. Many developers of free software are heartened and
|
||||
encouraged by the resulting cooperation. However, in the case of
|
||||
software used on network servers, this result may fail to come about.
|
||||
The GNU General Public License permits making a modified version and
|
||||
letting the public access it on a server without ever releasing its
|
||||
source code to the public.
|
||||
|
||||
The GNU Affero General Public License is designed specifically to
|
||||
ensure that, in such cases, the modified source code becomes available
|
||||
to the community. It requires the operator of a network server to
|
||||
provide the source code of the modified version running there to the
|
||||
users of that server. Therefore, public use of a modified version, on
|
||||
a publicly accessible server, gives the public access to the source
|
||||
code of the modified version.
|
||||
|
||||
An older license, called the Affero General Public License and
|
||||
published by Affero, was designed to accomplish similar goals. This is
|
||||
a different license, not a version of the Affero GPL, but Affero has
|
||||
released a new version of the Affero GPL which permits relicensing under
|
||||
this license.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU Affero General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Remote Network Interaction; Use with the GNU General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, if you modify the
|
||||
Program, your modified version must prominently offer all users
|
||||
interacting with it remotely through a computer network (if your version
|
||||
supports such interaction) an opportunity to receive the Corresponding
|
||||
Source of your version by providing access to the Corresponding Source
|
||||
from a network server at no charge, through some standard or customary
|
||||
means of facilitating copying of software. This Corresponding Source
|
||||
shall include the Corresponding Source for any work covered by version 3
|
||||
of the GNU General Public License that is incorporated pursuant to the
|
||||
following paragraph.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the work with which it is combined will remain governed by version
|
||||
3 of the GNU General Public License.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU Affero General Public License from time to time. Such new versions
|
||||
will be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU Affero General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU Affero General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU Affero General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If your software can interact with users remotely through a computer
|
||||
network, you should also make sure that it provides a way for users to
|
||||
get its source. For example, if your program is a web application, its
|
||||
interface could display a "Source" link that leads users to an archive
|
||||
of the code. There are many ways you could offer source, and different
|
||||
solutions will be better for different programs; see section 13 for the
|
||||
specific requirements.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU AGPL, see
|
||||
<https://www.gnu.org/licenses/>.
|
||||
674
LICENSE-GPL-3.0
Normal file
674
LICENSE-GPL-3.0
Normal file
@@ -0,0 +1,674 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. You must make sure that they, too, receive
|
||||
or can get the source code. And you must show them these terms so they
|
||||
know their rights.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Use with the GNU Affero General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
<program> Copyright (C) <year> <name of author>
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, your program's commands
|
||||
might be different; for a GUI interface, you would use an "about box".
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU GPL, see
|
||||
<https://www.gnu.org/licenses/>.
|
||||
|
||||
The GNU General Public License does not permit incorporating your program
|
||||
into proprietary programs. If your program is a subroutine library, you
|
||||
may consider it more useful to permit linking proprietary applications with
|
||||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
<https://www.gnu.org/licenses/why-not-lgpl.html>.
|
||||
408
README.md
408
README.md
@@ -1,104 +1,93 @@
|
||||
Element
|
||||
=======
|
||||
[](https://matrix.to/#/#element-web:matrix.org)
|
||||

|
||||

|
||||
[](https://localazy.com/p/element-web)
|
||||
[](https://sonarcloud.io/summary/new_code?id=element-web)
|
||||
[](https://sonarcloud.io/summary/new_code?id=element-web)
|
||||
[](https://sonarcloud.io/summary/new_code?id=element-web)
|
||||
[](https://sonarcloud.io/summary/new_code?id=element-web)
|
||||
|
||||
# Element
|
||||
|
||||
Element (formerly known as Vector and Riot) is a Matrix web client built using the [Matrix
|
||||
React SDK](https://github.com/matrix-org/matrix-react-sdk).
|
||||
JS SDK](https://github.com/matrix-org/matrix-js-sdk).
|
||||
|
||||
Supported Environments
|
||||
======================
|
||||
# Supported Environments
|
||||
|
||||
Element has several tiers of support for different environments:
|
||||
|
||||
* Supported
|
||||
* Definition: Issues **actively triaged**, regressions **block** the release
|
||||
* Last 2 major versions of Chrome, Firefox, Safari, and Edge on desktop OSes
|
||||
* Latest release of official Element Desktop app on desktop OSes
|
||||
* Desktop OSes means macOS, Windows, and Linux versions for desktop devices
|
||||
that are actively supported by the OS vendor and receive security updates
|
||||
* Experimental
|
||||
* Definition: Issues **accepted**, regressions **do not block** the release
|
||||
* Element as an installed PWA via current stable version of Chrome, Firefox, and Safari
|
||||
* Mobile web for current stable version of Chrome, Firefox, and Safari on Android, iOS, and iPadOS
|
||||
* Not supported
|
||||
* Definition: Issues only affecting unsupported environments are **closed**
|
||||
* Everything else
|
||||
- Supported
|
||||
- Definition:
|
||||
- Issues **actively triaged**, regressions **block** the release
|
||||
- Last 2 major versions of Chrome, Firefox, and Edge on desktop OSes
|
||||
- Last 2 versions of Safari
|
||||
- Latest release of official Element Desktop app on desktop OSes
|
||||
- Desktop OSes means macOS, Windows, and Linux versions for desktop devices
|
||||
that are actively supported by the OS vendor and receive security updates
|
||||
- Best effort
|
||||
- Definition:
|
||||
- Issues **accepted**, regressions **do not block** the release
|
||||
- The wider Element Products(including Element Call and the Enterprise Server Suite) do still not officially support these browsers.
|
||||
- The element web project and its contributors should keep the client functioning and gracefully degrade where other sibling features (E.g. Element Call) may not function.
|
||||
- Last major release of Firefox ESR and Chrome/Edge Extended Stable
|
||||
- Community Supported
|
||||
- Definition:
|
||||
- Issues **accepted**, regressions **do not block** the release
|
||||
- Community contributions are welcome to support these issues
|
||||
- Mobile web for current stable version of Chrome, Firefox, and Safari on Android, iOS, and iPadOS
|
||||
- Not supported
|
||||
- Definition: Issues only affecting unsupported environments are **closed**
|
||||
- Everything else
|
||||
|
||||
The period of support for these tiers should last until the releases specified above, plus 1 app release cycle(2 weeks). In the case of Firefox ESR this is extended further to allow it land in Debian Stable.
|
||||
|
||||
For accessing Element on an Android or iOS device, we currently recommend the
|
||||
native apps [element-android](https://github.com/vector-im/element-android)
|
||||
and [element-ios](https://github.com/vector-im/element-ios).
|
||||
native apps [element-android](https://github.com/element-hq/element-android)
|
||||
and [element-ios](https://github.com/element-hq/element-ios).
|
||||
|
||||
Getting Started
|
||||
===============
|
||||
# Getting Started
|
||||
|
||||
The easiest way to test Element is to just use the hosted copy at https://app.element.io.
|
||||
The `develop` branch is continuously deployed to https://develop.element.io
|
||||
The easiest way to test Element is to just use the hosted copy at <https://app.element.io>.
|
||||
The `develop` branch is continuously deployed to <https://develop.element.io>
|
||||
for those who like living dangerously.
|
||||
|
||||
To host your own copy of Element, the quickest bet is to use a pre-built
|
||||
released version of Element:
|
||||
To host your own instance of Element see [Installing Element Web](docs/install.md).
|
||||
|
||||
1. Download the latest version from https://github.com/vector-im/element-web/releases
|
||||
1. Untar the tarball on your web server
|
||||
1. Move (or symlink) the `element-x.x.x` directory to an appropriate name
|
||||
1. Configure the correct caching headers in your webserver (see below)
|
||||
1. If desired, copy `config.sample.json` to `config.json` and edit it
|
||||
as desired. See the [configuration docs](docs/config.md) for details.
|
||||
1. Enter the URL into your browser and log into Element!
|
||||
To install Element as a desktop application, see [Running as a desktop app](#running-as-a-desktop-app) below.
|
||||
|
||||
Releases are signed using gpg and the OpenPGP standard, and can be checked against the public key located
|
||||
at https://packages.riot.im/element-release-key.asc.
|
||||
# Important Security Notes
|
||||
|
||||
Note that for the security of your chats will need to serve Element
|
||||
over HTTPS. Major browsers also do not allow you to use VoIP/video
|
||||
chats over HTTP, as WebRTC is only usable over HTTPS.
|
||||
There are some exceptions like when using localhost, which is
|
||||
considered a [secure context](https://developer.mozilla.org/docs/Web/Security/Secure_Contexts)
|
||||
and thus allowed.
|
||||
|
||||
To install Element as a desktop application, see [Running as a desktop
|
||||
app](#running-as-a-desktop-app) below.
|
||||
|
||||
Important Security Notes
|
||||
========================
|
||||
|
||||
Separate domains
|
||||
----------------
|
||||
## Separate domains
|
||||
|
||||
We do not recommend running Element from the same domain name as your Matrix
|
||||
homeserver. The reason is the risk of XSS (cross-site-scripting)
|
||||
homeserver. The reason is the risk of XSS (cross-site-scripting)
|
||||
vulnerabilities that could occur if someone caused Element to load and render
|
||||
malicious user generated content from a Matrix API which then had trusted
|
||||
access to Element (or other apps) due to sharing the same domain.
|
||||
|
||||
We have put some coarse mitigations into place to try to protect against this
|
||||
situation, but it's still not good practice to do it in the first place. See
|
||||
https://github.com/vector-im/element-web/issues/1977 for more details.
|
||||
situation, but it's still not good practice to do it in the first place. See
|
||||
<https://github.com/element-hq/element-web/issues/1977> for more details.
|
||||
|
||||
Configuration best practices
|
||||
----------------------------
|
||||
## Configuration best practices
|
||||
|
||||
Unless you have special requirements, you will want to add the following to
|
||||
your web server configuration when hosting Element Web:
|
||||
|
||||
- The `X-Frame-Options: SAMEORIGIN` header, to prevent Element Web from being
|
||||
framed and protect from [clickjacking][owasp-clickjacking].
|
||||
- The `frame-ancestors 'none'` directive to your `Content-Security-Policy`
|
||||
header, as the modern replacement for `X-Frame-Options` (though both should be
|
||||
included since not all browsers support it yet, see
|
||||
[this][owasp-clickjacking-csp]).
|
||||
- The `X-Content-Type-Options: nosniff` header, to [disable MIME
|
||||
sniffing][mime-sniffing].
|
||||
- The `X-XSS-Protection: 1; mode=block;` header, for basic XSS protection in
|
||||
legacy browsers.
|
||||
- The `X-Frame-Options: SAMEORIGIN` header, to prevent Element Web from being
|
||||
framed and protect from [clickjacking][owasp-clickjacking].
|
||||
- The `frame-ancestors 'self'` directive to your `Content-Security-Policy`
|
||||
header, as the modern replacement for `X-Frame-Options` (though both should be
|
||||
included since not all browsers support it yet, see
|
||||
[this][owasp-clickjacking-csp]).
|
||||
- The `X-Content-Type-Options: nosniff` header, to [disable MIME
|
||||
sniffing][mime-sniffing].
|
||||
- The `X-XSS-Protection: 1; mode=block;` header, for basic XSS protection in
|
||||
legacy browsers.
|
||||
|
||||
[mime-sniffing]:
|
||||
<https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types#mime_sniffing>
|
||||
|
||||
[owasp-clickjacking-csp]:
|
||||
<https://cheatsheetseries.owasp.org/cheatsheets/Clickjacking_Defense_Cheat_Sheet.html#content-security-policy-frame-ancestors-examples>
|
||||
|
||||
[owasp-clickjacking]:
|
||||
<https://cheatsheetseries.owasp.org/cheatsheets/Clickjacking_Defense_Cheat_Sheet.html>
|
||||
[mime-sniffing]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types#mime_sniffing
|
||||
[owasp-clickjacking-csp]: https://cheatsheetseries.owasp.org/cheatsheets/Clickjacking_Defense_Cheat_Sheet.html#content-security-policy-frame-ancestors-examples
|
||||
[owasp-clickjacking]: https://cheatsheetseries.owasp.org/cheatsheets/Clickjacking_Defense_Cheat_Sheet.html
|
||||
|
||||
If you are using nginx, this would look something like the following:
|
||||
|
||||
@@ -106,15 +95,23 @@ If you are using nginx, this would look something like the following:
|
||||
add_header X-Frame-Options SAMEORIGIN;
|
||||
add_header X-Content-Type-Options nosniff;
|
||||
add_header X-XSS-Protection "1; mode=block";
|
||||
add_header Content-Security-Policy "frame-ancestors 'none'";
|
||||
add_header Content-Security-Policy "frame-ancestors 'self'";
|
||||
```
|
||||
|
||||
For Apache, the configuration looks like:
|
||||
|
||||
```
|
||||
Header set X-Frame-Options SAMEORIGIN
|
||||
Header set X-Content-Type-Options nosniff
|
||||
Header set X-XSS-Protection "1; mode=block"
|
||||
Header set Content-Security-Policy "frame-ancestors 'self'"
|
||||
```
|
||||
|
||||
Note: In case you are already setting a `Content-Security-Policy` header
|
||||
elsewhere, you should modify it to include the `frame-ancestors` directive
|
||||
instead of adding that last line.
|
||||
|
||||
Building From Source
|
||||
====================
|
||||
# Building From Source
|
||||
|
||||
Element is a modular webapp built with modern ES6 and uses a Node.js build system.
|
||||
Ensure you have the latest LTS version of Node.js installed.
|
||||
@@ -122,15 +119,15 @@ Ensure you have the latest LTS version of Node.js installed.
|
||||
Using `yarn` instead of `npm` is recommended. Please see the Yarn [install
|
||||
guide](https://classic.yarnpkg.com/en/docs/install) if you do not have it already.
|
||||
|
||||
1. Install or update `node.js` so that your `node` is at least v10.x.
|
||||
1. Install or update `node.js` so that your `node` is at least the current recommended LTS.
|
||||
1. Install `yarn` if not present already.
|
||||
1. Clone the repo: `git clone https://github.com/vector-im/element-web.git`.
|
||||
1. Clone the repo: `git clone https://github.com/element-hq/element-web.git`.
|
||||
1. Switch to the element-web directory: `cd element-web`.
|
||||
1. Install the prerequisites: `yarn install`.
|
||||
* If you're using the `develop` branch, then it is recommended to set up a
|
||||
- If you're using the `develop` branch, then it is recommended to set up a
|
||||
proper development environment (see [Setting up a dev
|
||||
environment](#setting-up-a-dev-environment) below). Alternatively, you
|
||||
can use https://develop.element.io - the continuous integration release of
|
||||
can use <https://develop.element.io> - the continuous integration release of
|
||||
the develop branch.
|
||||
1. Configure the app by copying `config.sample.json` to `config.json` and
|
||||
modifying it. See the [configuration docs](docs/config.md) for details.
|
||||
@@ -144,86 +141,32 @@ will not appear in Settings without using the dist script. You can then mount th
|
||||
`webapp` directory on your web server to actually serve up the app, which is
|
||||
entirely static content.
|
||||
|
||||
Running as a Desktop app
|
||||
========================
|
||||
# Running as a Desktop app
|
||||
|
||||
Element can also be run as a desktop app, wrapped in Electron. You can download a
|
||||
pre-built version from https://element.io/get-started or, if you prefer,
|
||||
pre-built version from <https://element.io/get-started> or, if you prefer,
|
||||
build it yourself.
|
||||
|
||||
To build it yourself, follow the instructions at https://github.com/vector-im/element-desktop.
|
||||
To build it yourself, follow the instructions at <https://github.com/element-hq/element-desktop>.
|
||||
|
||||
Many thanks to @aviraldg for the initial work on the Electron integration.
|
||||
|
||||
Other options for running as a desktop app:
|
||||
* @asdf:matrix.org points out that you can use nativefier and it just works(tm)
|
||||
The [configuration docs](docs/config.md#desktop-app-configuration) show how to override the desktop app's default settings if desired.
|
||||
|
||||
```bash
|
||||
yarn global add nativefier
|
||||
nativefier https://app.element.io/
|
||||
```
|
||||
|
||||
The [configuration docs](docs/config.md#desktop-app-configuration) show how to
|
||||
override the desktop app's default settings if desired.
|
||||
|
||||
Running from Docker
|
||||
===================
|
||||
|
||||
The Docker image can be used to serve element-web as a web server. The easiest way to use
|
||||
it is to use the prebuilt image:
|
||||
```bash
|
||||
docker run -p 80:80 vectorim/element-web
|
||||
```
|
||||
|
||||
To supply your own custom `config.json`, map a volume to `/app/config.json`. For example,
|
||||
if your custom config was located at `/etc/element-web/config.json` then your Docker command
|
||||
would be:
|
||||
```bash
|
||||
docker run -p 80:80 -v /etc/element-web/config.json:/app/config.json vectorim/element-web
|
||||
```
|
||||
|
||||
To build the image yourself:
|
||||
```bash
|
||||
git clone https://github.com/vector-im/element-web.git element-web
|
||||
cd element-web
|
||||
git checkout master
|
||||
docker build .
|
||||
```
|
||||
|
||||
If you're building a custom branch, or want to use the develop branch, check out the appropriate
|
||||
element-web branch and then run:
|
||||
```bash
|
||||
docker build -t \
|
||||
--build-arg USE_CUSTOM_SDKS=true \
|
||||
--build-arg REACT_SDK_REPO="https://github.com/matrix-org/matrix-react-sdk.git" \
|
||||
--build-arg REACT_SDK_BRANCH="develop" \
|
||||
--build-arg JS_SDK_REPO="https://github.com/matrix-org/matrix-js-sdk.git" \
|
||||
--build-arg JS_SDK_BRANCH="develop" \
|
||||
.
|
||||
```
|
||||
|
||||
Running in Kubernetes
|
||||
=====================
|
||||
|
||||
The provided element-web docker image can also be run from within a Kubernetes cluster.
|
||||
See the [Kubernetes example](docs/kubernetes.md) for more details.
|
||||
|
||||
config.json
|
||||
===========
|
||||
# config.json
|
||||
|
||||
Element supports a variety of settings to configure default servers, behaviour, themes, etc.
|
||||
See the [configuration docs](docs/config.md) for more details.
|
||||
|
||||
Labs Features
|
||||
=============
|
||||
# Labs Features
|
||||
|
||||
Some features of Element may be enabled by flags in the `Labs` section of the settings.
|
||||
Some of these features are described in [labs.md](https://github.com/vector-im/element-web/blob/develop/docs/labs.md).
|
||||
Some of these features are described in [labs.md](https://github.com/element-hq/element-web/blob/develop/docs/labs.md).
|
||||
|
||||
Caching requirements
|
||||
====================
|
||||
# Caching requirements
|
||||
|
||||
Element requires the following URLs not to be cached, when/if you are serving Element from your own webserver:
|
||||
|
||||
```
|
||||
/config.*.json
|
||||
/i18n
|
||||
@@ -232,17 +175,22 @@ Element requires the following URLs not to be cached, when/if you are serving El
|
||||
/index.html
|
||||
```
|
||||
|
||||
Development
|
||||
===========
|
||||
We also recommend that you force browsers to re-validate any cached copy of Element on page load by configuring your
|
||||
webserver to return `Cache-Control: no-cache` for `/`. This ensures the browser will fetch a new version of Element on
|
||||
the next page load after it's been deployed. Note that this is already configured for you in the nginx config of our
|
||||
Dockerfile.
|
||||
|
||||
# Development
|
||||
|
||||
Before attempting to develop on Element you **must** read the [developer guide
|
||||
for `matrix-react-sdk`](https://github.com/matrix-org/matrix-react-sdk#developer-guide), which
|
||||
also defines the design, architecture and style for Element too.
|
||||
|
||||
Before starting work on a feature, it's best to ensure your plan aligns well
|
||||
with our vision for Element. Please chat with the team in
|
||||
[#element-dev:matrix.org](https://matrix.to/#/#element-dev:matrix.org) before you
|
||||
start so we can ensure it's something we'd be willing to merge.
|
||||
Read the [Choosing an issue](docs/choosing-an-issue.md) page for some guidance
|
||||
about where to start. Before starting work on a feature, it's best to ensure
|
||||
your plan aligns well with our vision for Element. Please chat with the team in
|
||||
[#element-dev:matrix.org](https://matrix.to/#/#element-dev:matrix.org) before
|
||||
you start so we can ensure it's something we'd be willing to merge.
|
||||
|
||||
You should also familiarise yourself with the ["Here be Dragons" guide
|
||||
](https://docs.google.com/document/d/12jYzvkidrp1h7liEuLIe6BMdU0NUjndUYI971O06ooM)
|
||||
@@ -253,25 +201,20 @@ top of the underlying `matrix-react-sdk`. `matrix-react-sdk` provides both the
|
||||
higher and lower level React components useful for building Matrix communication
|
||||
apps using React.
|
||||
|
||||
After creating a new component you must run `yarn reskindex` to regenerate
|
||||
the `component-index.js` for the app (used in future for skinning).
|
||||
|
||||
Please note that Element is intended to run correctly without access to the public
|
||||
internet. So please don't depend on resources (JS libs, CSS, images, fonts)
|
||||
internet. So please don't depend on resources (JS libs, CSS, images, fonts)
|
||||
hosted by external CDNs or servers but instead please package all dependencies
|
||||
into Element itself.
|
||||
|
||||
Setting up a dev environment
|
||||
============================
|
||||
# Setting up a dev environment
|
||||
|
||||
Much of the functionality in Element is actually in the `matrix-react-sdk` and
|
||||
`matrix-js-sdk` modules. It is possible to set these up in a way that makes it
|
||||
easy to track the `develop` branches in git and to make local changes without
|
||||
having to manually rebuild each time.
|
||||
Much of the functionality in Element is actually in the `matrix-js-sdk` module.
|
||||
It is possible to set these up in a way that makes it easy to track the `develop` branches
|
||||
in git and to make local changes without having to manually rebuild each time.
|
||||
|
||||
First clone and build `matrix-js-sdk`:
|
||||
|
||||
``` bash
|
||||
```bash
|
||||
git clone https://github.com/matrix-org/matrix-js-sdk.git
|
||||
pushd matrix-js-sdk
|
||||
yarn link
|
||||
@@ -279,53 +222,46 @@ yarn install
|
||||
popd
|
||||
```
|
||||
|
||||
Then similarly with `matrix-react-sdk`:
|
||||
Clone the repo and switch to the `element-web` directory:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/matrix-org/matrix-react-sdk.git
|
||||
pushd matrix-react-sdk
|
||||
yarn link
|
||||
yarn link matrix-js-sdk
|
||||
yarn install
|
||||
popd
|
||||
git clone https://github.com/element-hq/element-web.git
|
||||
cd element-web
|
||||
```
|
||||
|
||||
Configure the app by copying `config.sample.json` to `config.json` and
|
||||
modifying it. See the [configuration docs](docs/config.md) for details.
|
||||
|
||||
Finally, build and start Element itself:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/vector-im/element-web.git
|
||||
cd element-web
|
||||
yarn link matrix-js-sdk
|
||||
yarn link matrix-react-sdk
|
||||
yarn install
|
||||
yarn reskindex
|
||||
yarn start
|
||||
```
|
||||
|
||||
|
||||
Wait a few seconds for the initial build to finish; you should see something like:
|
||||
|
||||
```
|
||||
[element-js] <s> [webpack.Progress] 100%
|
||||
[element-js]
|
||||
[element-js] ℹ 「wdm」: 1840 modules
|
||||
[element-js] ℹ 「wdm」: Compiled successfully.
|
||||
```
|
||||
Remember, the command will not terminate since it runs the web server
|
||||
and rebuilds source files when they change. This development server also
|
||||
disables caching, so do NOT use it in production.
|
||||
|
||||
Configure the app by copying `config.sample.json` to `config.json` and
|
||||
modifying it. See the [configuration docs](docs/config.md) for details.
|
||||
Remember, the command will not terminate since it runs the web server
|
||||
and rebuilds source files when they change. This development server also
|
||||
disables caching, so do NOT use it in production.
|
||||
|
||||
Open http://127.0.0.1:8080/ in your browser to see your newly built Element.
|
||||
Open <http://127.0.0.1:8080/> in your browser to see your newly built Element.
|
||||
|
||||
**Note**: The build script uses inotify by default on Linux to monitor directories
|
||||
for changes. If the inotify limits are too low your build will fail silently or with
|
||||
`Error: EMFILE: too many open files`. To avoid these issues, we recommend a watch limit
|
||||
of at least `128M` and instance limit around `512`.
|
||||
|
||||
You may be interested in issues [#15750](https://github.com/vector-im/element-web/issues/15750) and
|
||||
[#15774](https://github.com/vector-im/element-web/issues/15774) for further details.
|
||||
You may be interested in issues [#15750](https://github.com/element-hq/element-web/issues/15750) and
|
||||
[#15774](https://github.com/element-hq/element-web/issues/15774) for further details.
|
||||
|
||||
To set a new inotify watch and instance limit, execute:
|
||||
|
||||
@@ -343,123 +279,35 @@ echo fs.inotify.max_user_instances=512 | sudo tee -a /etc/sysctl.conf
|
||||
sudo sysctl -p
|
||||
```
|
||||
|
||||
___
|
||||
---
|
||||
|
||||
When you make changes to `matrix-react-sdk` or `matrix-js-sdk` they should be
|
||||
automatically picked up by webpack and built.
|
||||
|
||||
If you add or remove any components from the Element skin, you will need to rebuild
|
||||
the skin's index by running, `yarn reskindex`.
|
||||
When you make changes to `matrix-js-sdk` they should be automatically picked up by webpack and built.
|
||||
|
||||
If any of these steps error with, `file table overflow`, you are probably on a mac
|
||||
which has a very low limit on max open files. Run `ulimit -Sn 1024` and try again.
|
||||
You'll need to do this in each new terminal you open before building Element.
|
||||
|
||||
Running the tests
|
||||
-----------------
|
||||
## Running the tests
|
||||
|
||||
There are a number of application-level tests in the `tests` directory; these
|
||||
are designed to run in a browser instance under the control of
|
||||
[karma](https://karma-runner.github.io). To run them:
|
||||
are designed to run with Jest and JSDOM. To run them
|
||||
|
||||
* Make sure you have Chrome installed (a recent version, like 59)
|
||||
* Make sure you have `matrix-js-sdk` and `matrix-react-sdk` installed and
|
||||
built, as above
|
||||
* `yarn test`
|
||||
|
||||
The above will run the tests under Chrome in a `headless` mode.
|
||||
|
||||
You can also tell karma to run the tests in a loop (every time the source
|
||||
changes), in an instance of Chrome on your desktop, with `yarn
|
||||
test-multi`. This also gives you the option of running the tests in 'debug'
|
||||
mode, which is useful for stepping through the tests in the developer tools.
|
||||
```
|
||||
yarn test
|
||||
```
|
||||
|
||||
### End-to-End tests
|
||||
|
||||
See [matrix-react-sdk](https://github.com/matrix-org/matrix-react-sdk/#end-to-end-tests) how to run the end-to-end tests.
|
||||
See [matrix-react-sdk](https://github.com/matrix-org/matrix-react-sdk/#end-to-end-tests) for how to run the end-to-end tests.
|
||||
|
||||
Translations
|
||||
============
|
||||
# Translations
|
||||
|
||||
To add a new translation, head to the [translating doc](docs/translating.md).
|
||||
|
||||
For a developer guide, see the [translating dev doc](docs/translating-dev.md).
|
||||
|
||||
[<img src="https://translate.element.io/widgets/element-web/-/multi-auto.svg" alt="translationsstatus" width="340">](https://translate.element.io/engage/element-web/?utm_source=widget)
|
||||
# Triaging issues
|
||||
|
||||
Triaging issues
|
||||
===============
|
||||
Issues are triaged by community members and the Web App Team, following the [triage process](https://github.com/element-hq/element-meta/wiki/Triage-process).
|
||||
|
||||
We strive to completely cover all applicable issues with these core labels:
|
||||
|
||||
1. __Type__ — Every issue is assigned a type:
|
||||
- __[T-Defect](https://github.com/vector-im/element-web/labels/T-Defect):__
|
||||
Bugs, crashes, hangs, vulnerabilities, or other reported problems
|
||||
- __[T-Enhancement](https://github.com/vector-im/element-web/labels/T-Enhancement):__
|
||||
New features, changes in functionality, performance boosts, user-facing
|
||||
improvements
|
||||
- __[T-Task](https://github.com/vector-im/element-web/labels/T-Task):__
|
||||
Refactoring, enabling or disabling functionality, other engineering tasks
|
||||
- __[T-Other](https://github.com/vector-im/element-web/labels/T-Other):__
|
||||
Questions, user support, anything else
|
||||
|
||||
2. __Severity__ — All issues labeled `T-Defect` are also assigned a severity:
|
||||
* __[S-Critical](https://github.com/vector-im/element-web/labels/S-Critical):__
|
||||
Prevents work, causes data loss, affects many users, and/or has no
|
||||
workaround
|
||||
* __[S-Major](https://github.com/vector-im/element-web/labels/S-Major):__
|
||||
Severely degrades major functionality or product features, with no
|
||||
satisfactory workaround
|
||||
* __[S-Minor](https://github.com/vector-im/element-web/labels/S-Minor):__
|
||||
Impairs non-critical functionality, or suitable workarounds exist
|
||||
* __[S-Tolerable](https://github.com/vector-im/element-web/labels/S-Tolerable):__
|
||||
Purely cosmetic or low / no impact to users
|
||||
|
||||
3. __Priority__ — All issues which are not `T-Other` are assigned a priority:
|
||||
* __[P1](https://github.com/vector-im/element-web/labels/P1):__ Next
|
||||
* __[P2](https://github.com/vector-im/element-web/labels/P2):__ Later
|
||||
* __[P3](https://github.com/vector-im/element-web/labels/P3):__ Eventually
|
||||
* __[P4](https://github.com/vector-im/element-web/labels/P4):__ Interesting —
|
||||
Not yet scheduled, will accept patches
|
||||
* __[P5](https://github.com/vector-im/element-web/labels/P5):__ Dubious —
|
||||
Will not schedule, would consider patches
|
||||
|
||||
4. __Area__ — Most issues are assigned one or several "areas" using one of the
|
||||
many `A-` prefixed labels, e.g. `A-Composer` or `A-Spaces`. Each area label
|
||||
maps to a group of features or portion of the UI surface in the app.
|
||||
|
||||
### Other common labels
|
||||
|
||||
We have a handful of other labels which are added on an as-needed basis, and not expected to be exhaustive:
|
||||
|
||||
* __Exceptions__ — Special flags for issues and pull requests:
|
||||
* __[X-Needs-Info](https://github.com/vector-im/element-web/labels/X-Needs-Info):__
|
||||
This issue is blocked pending further information from the reporter
|
||||
* __[X-Regression](https://github.com/vector-im/element-web/labels/X-Regression):__
|
||||
Denotes things breaking which previously worked
|
||||
* __[X-Release-Blocker](https://github.com/vector-im/element-web/labels/X-Release-Blocker):__
|
||||
Issues which must be resolved before making a release
|
||||
|
||||
* __[Easy](https://github.com/vector-im/element-web/labels/Easy)__ / __[Help
|
||||
Wanted](https://github.com/vector-im/element-web/labels/Help%20Wanted)__ —
|
||||
Well-defined issues which are suitable for folks new to the codebase
|
||||
|
||||
* __[A11y](https://github.com/vector-im/element-web/labels/A11y)__ /
|
||||
__[Meta](https://github.com/vector-im/element-web/labels/Meta)__ /
|
||||
__[I18n](https://github.com/vector-im/element-web/labels/I18n)__ /
|
||||
__[Privacy](https://github.com/vector-im/element-web/labels/Privacy)__ /
|
||||
__[Security](https://github.com/vector-im/element-web/labels/Security)__ —
|
||||
Issues which fall under these conceptual themes (which apply to many software
|
||||
projects and are not specific to Element)
|
||||
|
||||
* __[Sponsored](https://github.com/vector-im/element-web/labels/Sponsored)__ —
|
||||
Used internally by Element to denote issues with external funding
|
||||
|
||||
### Ad hoc labels (`Z-`)
|
||||
|
||||
We have reserved the `Z-` prefix for ad hoc labels.
|
||||
|
||||
Any member of the core team is welcome to create labels beginning with `Z-` for
|
||||
any purpose, such as tracking personal areas of interest or providing a common
|
||||
way to label cross-repo initiatives. The prefix avoids interference with the
|
||||
project's main labels.
|
||||
We use [issue labels](https://github.com/element-hq/element-meta/wiki/Issue-labelling) to sort all incoming issues.
|
||||
|
||||
6
__mocks__/FontManager.js
Normal file
6
__mocks__/FontManager.js
Normal file
@@ -0,0 +1,6 @@
|
||||
// Stub out FontManager for tests as it doesn't validate anything we don't already know given
|
||||
// our fixed test environment and it requires the installation of node-canvas.
|
||||
|
||||
module.exports = {
|
||||
fixupColorFonts: () => Promise.resolve(),
|
||||
};
|
||||
2
__mocks__/empty.js
Normal file
2
__mocks__/empty.js
Normal file
@@ -0,0 +1,2 @@
|
||||
// Yes, this is empty.
|
||||
module.exports = {};
|
||||
1
__mocks__/imageMock.js
Normal file
1
__mocks__/imageMock.js
Normal file
@@ -0,0 +1 @@
|
||||
module.exports = "image-file-stub";
|
||||
4
__mocks__/languages.json
Normal file
4
__mocks__/languages.json
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"en": "en_EN.json",
|
||||
"en-us": "en_US.json"
|
||||
}
|
||||
40
__mocks__/maplibre-gl.js
Normal file
40
__mocks__/maplibre-gl.js
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
Copyright 2024 New Vector Ltd.
|
||||
Copyright 2022 The Matrix.org Foundation C.I.C.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
const EventEmitter = require("events");
|
||||
const { LngLat, NavigationControl, LngLatBounds } = require("maplibre-gl");
|
||||
|
||||
class MockMap extends EventEmitter {
|
||||
addControl = jest.fn();
|
||||
removeControl = jest.fn();
|
||||
zoomIn = jest.fn();
|
||||
zoomOut = jest.fn();
|
||||
setCenter = jest.fn();
|
||||
setStyle = jest.fn();
|
||||
fitBounds = jest.fn();
|
||||
}
|
||||
const MockMapInstance = new MockMap();
|
||||
|
||||
class MockAttributionControl {}
|
||||
class MockGeolocateControl extends EventEmitter {
|
||||
trigger = jest.fn();
|
||||
}
|
||||
const MockGeolocateInstance = new MockGeolocateControl();
|
||||
const MockMarker = {};
|
||||
MockMarker.setLngLat = jest.fn().mockReturnValue(MockMarker);
|
||||
MockMarker.addTo = jest.fn().mockReturnValue(MockMarker);
|
||||
MockMarker.remove = jest.fn().mockReturnValue(MockMarker);
|
||||
module.exports = {
|
||||
Map: jest.fn().mockReturnValue(MockMapInstance),
|
||||
GeolocateControl: jest.fn().mockReturnValue(MockGeolocateInstance),
|
||||
Marker: jest.fn().mockReturnValue(MockMarker),
|
||||
LngLat,
|
||||
LngLatBounds,
|
||||
NavigationControl,
|
||||
AttributionControl: MockAttributionControl,
|
||||
};
|
||||
2
__mocks__/svg.js
Normal file
2
__mocks__/svg.js
Normal file
@@ -0,0 +1,2 @@
|
||||
export const Icon = "div";
|
||||
export default "image-file-stub";
|
||||
11
__mocks__/workerFactoryMock.js
Normal file
11
__mocks__/workerFactoryMock.js
Normal file
@@ -0,0 +1,11 @@
|
||||
/*
|
||||
Copyright 2024 New Vector Ltd.
|
||||
Copyright 2023 The Matrix.org Foundation C.I.C.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
export default function workerFactory(options) {
|
||||
return jest.fn;
|
||||
}
|
||||
@@ -1,25 +1,34 @@
|
||||
module.exports = {
|
||||
"sourceMaps": true,
|
||||
"presets": [
|
||||
["@babel/preset-env", {
|
||||
"targets": [
|
||||
"last 2 Chrome versions",
|
||||
"last 2 Firefox versions",
|
||||
"last 2 Safari versions",
|
||||
"last 2 Edge versions",
|
||||
],
|
||||
}],
|
||||
"@babel/preset-typescript",
|
||||
sourceMaps: true,
|
||||
presets: [
|
||||
[
|
||||
"@babel/preset-env",
|
||||
{
|
||||
targets: [
|
||||
"last 2 Chrome versions",
|
||||
"last 2 Firefox versions",
|
||||
"last 2 Safari versions",
|
||||
"last 2 Edge versions",
|
||||
],
|
||||
include: ["@babel/plugin-transform-class-properties"],
|
||||
},
|
||||
],
|
||||
["@babel/preset-typescript", { allowDeclareFields: true }],
|
||||
"@babel/preset-react",
|
||||
],
|
||||
"plugins": [
|
||||
["@babel/plugin-proposal-decorators", {legacy: true}],
|
||||
plugins: [
|
||||
"@babel/plugin-proposal-export-default-from",
|
||||
"@babel/plugin-proposal-numeric-separator",
|
||||
"@babel/plugin-proposal-class-properties",
|
||||
"@babel/plugin-proposal-object-rest-spread",
|
||||
"@babel/plugin-proposal-optional-chaining",
|
||||
"@babel/plugin-proposal-nullish-coalescing-operator",
|
||||
"@babel/plugin-transform-numeric-separator",
|
||||
"@babel/plugin-transform-object-rest-spread",
|
||||
"@babel/plugin-transform-optional-chaining",
|
||||
"@babel/plugin-transform-nullish-coalescing-operator",
|
||||
|
||||
// transform logical assignment (??=, ||=, &&=). preset-env doesn't
|
||||
// normally bother with these (presumably because all the target
|
||||
// browsers support it natively), but they make our webpack version (or
|
||||
// something downstream of babel, at least) fall over.
|
||||
"@babel/plugin-transform-logical-assignment-operators",
|
||||
|
||||
"@babel/plugin-syntax-dynamic-import",
|
||||
"@babel/plugin-transform-runtime",
|
||||
],
|
||||
|
||||
33
book.toml
Normal file
33
book.toml
Normal file
@@ -0,0 +1,33 @@
|
||||
# Documentation for possible options in this file is at
|
||||
# https://rust-lang.github.io/mdBook/format/config.html
|
||||
[book]
|
||||
title = "Element Web & Desktop"
|
||||
authors = ["New Vector Ltd.", "The Matrix.org Foundation C.I.C."]
|
||||
language = "en"
|
||||
multilingual = false
|
||||
|
||||
# The directory that documentation files are stored in
|
||||
src = "docs"
|
||||
|
||||
[build]
|
||||
# Prevent markdown pages from being automatically generated when they're
|
||||
# linked to in SUMMARY.md
|
||||
create-missing = false
|
||||
|
||||
[output.html]
|
||||
# Remove the numbers that appear before each item in the sidebar, as they can
|
||||
# get quite messy as we nest deeper
|
||||
no-section-label = true
|
||||
additional-css = ["docs/lib/custom.css"]
|
||||
|
||||
# The source code URL of the repository
|
||||
git-repository-url = "https://github.com/element-hq/element-web"
|
||||
|
||||
# The path that the docs are hosted on
|
||||
site-url = "/element-web/"
|
||||
additional-js = ["docs/lib/mermaid.min.js", "docs/lib/mermaid-init.js"]
|
||||
|
||||
[preprocessor]
|
||||
|
||||
[preprocessor.mermaid]
|
||||
command = "mdbook-mermaid"
|
||||
25
build_config.sample.yaml
Normal file
25
build_config.sample.yaml
Normal file
@@ -0,0 +1,25 @@
|
||||
# A sample build_config.yaml to supply to Element Web's build pipeline,
|
||||
# enabling custom functionality at compile time. Copy this file to
|
||||
# `build_config.yaml` in the same directory to use, as you would with
|
||||
# `config.json`.
|
||||
#
|
||||
# Note: The vast majority of users DO NOT need this. If you are looking
|
||||
# to build your own Element Web as seen on app.element.io or similar then
|
||||
# this is not required.
|
||||
#
|
||||
# This config file does become required if you are looking to add runtime
|
||||
# functionality to Element Web, such as customisation endpoints and modules.
|
||||
#
|
||||
# Over time we might expand this config to better support some use cases.
|
||||
# Watch the release notes for features which might impact this config.
|
||||
|
||||
# The modules to install. See ./docs/modules.md for more information on
|
||||
# what modules are.
|
||||
#
|
||||
# The values of this are provided to `yarn add` for inclusion.
|
||||
modules:
|
||||
# An example of pulling a module from NPM
|
||||
- "@vector-im/element-web-ilag-module@^0.0.1"
|
||||
|
||||
# An example of pulling a module from local filesystem during development
|
||||
- "file:/home/user/development/element-web-ilag-module"
|
||||
412
code_style.md
Normal file
412
code_style.md
Normal file
@@ -0,0 +1,412 @@
|
||||
# Element Web/Desktop code style guide
|
||||
|
||||
This code style applies to projects which the element-web team directly maintains or is reasonably
|
||||
adjacent to. As of writing, these are:
|
||||
|
||||
- element-desktop
|
||||
- element-web
|
||||
- matrix-js-sdk
|
||||
|
||||
Other projects might extend this code style for increased strictness. For example, matrix-events-sdk
|
||||
has stricter code organization to reduce the maintenance burden. These projects will declare their code
|
||||
style within their own repos.
|
||||
|
||||
Note that some requirements will be layer-specific. Where the requirements don't make sense for the
|
||||
project, they are used to the best of their ability, used in spirit, or ignored if not applicable,
|
||||
in that order.
|
||||
|
||||
## Guiding principles
|
||||
|
||||
1. We want the lint rules to feel natural for most team members. No one should have to think too much
|
||||
about the linter.
|
||||
2. We want to stay relatively close to [industry standards](https://google.github.io/styleguide/tsguide.html)
|
||||
to make onboarding easier.
|
||||
3. We describe what good code looks like rather than point out bad examples. We do this to avoid
|
||||
excessively punishing people for writing code which fails the linter.
|
||||
4. When something isn't covered by the style guide, we come up with a reasonable rule rather than
|
||||
claim that it "passes the linter". We update the style guide and linter accordingly.
|
||||
5. While we aim to improve readability, understanding, and other aspects of the code, we deliberately
|
||||
do not let solely our personal preferences drive decisions.
|
||||
6. We aim to have an understandable guide.
|
||||
|
||||
## Coding practices
|
||||
|
||||
1. Lint rules enforce decisions made by this guide. The lint rules and this guide are kept in
|
||||
perfect sync.
|
||||
2. Commit messages are descriptive for the changes. When the project supports squash merging,
|
||||
only the squashed commit needs to have a descriptive message.
|
||||
3. When there is disagreement with a code style approved by the linter, a PR is opened against
|
||||
the lint rules rather than making exceptions on the responsible code PR.
|
||||
4. Rules which are intentionally broken (via eslint-ignore, @ts-ignore, etc) have a comment
|
||||
included in the immediate vicinity for why. Determination of whether this is valid applies at
|
||||
code review time.
|
||||
5. When editing a file, nearby code is updated to meet the modern standards. "Nearby" is subjective,
|
||||
but should be whatever is reasonable at review time. Such an example might be to update the
|
||||
class's code style, but not the file's.
|
||||
1. These changes should be minor enough to include in the same commit without affecting a code
|
||||
reviewer's job.
|
||||
|
||||
## All code
|
||||
|
||||
Unless otherwise specified, the following applies to all code:
|
||||
|
||||
1. Files must be formatted with Prettier.
|
||||
2. 120 character limit per line. Match existing code in the file if it is using a lower guide.
|
||||
3. A tab/indentation is 4 spaces.
|
||||
4. Newlines are Unix.
|
||||
5. A file has a single empty line at the end.
|
||||
6. Lines are trimmed of all excess whitespace, including blank lines.
|
||||
7. Long lines are broken up for readability.
|
||||
|
||||
## TypeScript / JavaScript
|
||||
|
||||
1. Write TypeScript. Turn JavaScript into TypeScript when working in the area.
|
||||
2. Use [TSDoc](https://tsdoc.org/) to document your code. See [Comments](#comments) below.
|
||||
3. Use named exports.
|
||||
4. Use semicolons for block/line termination.
|
||||
1. Except when defining interfaces, classes, and non-arrow functions specifically.
|
||||
5. When a statement's body is a single line, it must be written without curly braces, so long as the body is placed on
|
||||
the same line as the statement.
|
||||
|
||||
```typescript
|
||||
if (x) doThing();
|
||||
```
|
||||
|
||||
6. Blocks for `if`, `for`, `switch` and so on must have a space surrounding the condition, but not
|
||||
within the condition.
|
||||
|
||||
```typescript
|
||||
if (x) {
|
||||
doThing();
|
||||
}
|
||||
```
|
||||
|
||||
7. lowerCamelCase is used for function and variable naming.
|
||||
8. UpperCamelCase is used for general naming.
|
||||
9. Interface names should not be marked with an uppercase `I`.
|
||||
10. One variable declaration per line.
|
||||
11. If a variable is not receiving a value on declaration, its type must be defined.
|
||||
|
||||
```typescript
|
||||
let errorMessage: Optional<string>;
|
||||
```
|
||||
|
||||
12. Objects can use shorthand declarations, including mixing of types.
|
||||
|
||||
```typescript
|
||||
{
|
||||
room,
|
||||
prop: this.prop,
|
||||
}
|
||||
// ... or ...
|
||||
{ room, prop: this.prop }
|
||||
```
|
||||
|
||||
13. Object keys should always be non-strings when possible.
|
||||
|
||||
```typescript
|
||||
{
|
||||
property: "value",
|
||||
"m.unavoidable": true,
|
||||
[EventType.RoomMessage]: true,
|
||||
}
|
||||
```
|
||||
|
||||
14. If a variable's type should be boolean, make sure it really is one.
|
||||
|
||||
```typescript
|
||||
const isRealUser = !!userId && ...; // good
|
||||
const isRealUser = Boolean(userId) && Boolean(userName); // also good
|
||||
const isRealUser = Boolean(userId) && isReal; // also good (where isReal is another boolean variable)
|
||||
const isRealUser = Boolean(userId && userName); // also fine
|
||||
const isRealUser = Boolean(userId || userName); // good: same as &&
|
||||
const isRealUser = userId && ...; // bad: isRealUser is userId's type, not a boolean
|
||||
|
||||
if (userId) // fine: userId is evaluated for truthiness, not stored as a boolean
|
||||
```
|
||||
|
||||
15. Use `switch` statements when checking against more than a few enum-like values.
|
||||
16. Use `const` for constants, `let` for mutability.
|
||||
17. Describe types exhaustively (ensure noImplictAny would pass).
|
||||
1. Notable exceptions are arrow functions used as parameters, when a void return type is
|
||||
obvious, and when declaring and assigning a variable in the same line.
|
||||
18. Declare member visibility (public/private/protected).
|
||||
19. Private members are private and not prefixed unless required for naming conflicts.
|
||||
1. Convention is to use an underscore or the word "internal" to denote conflicted member names.
|
||||
2. "Conflicted" typically refers to a getter which wants the same name as the underlying variable.
|
||||
20. Prefer readonly members over getters backed by a variable, unless an internal setter is required.
|
||||
21. Prefer Interfaces for object definitions, and types for parameter-value-only declarations.
|
||||
|
||||
1. Note that an explicit type is optional if not expected to be used outside of the function call,
|
||||
unlike in this example:
|
||||
|
||||
```typescript
|
||||
interface MyObject {
|
||||
hasString: boolean;
|
||||
}
|
||||
|
||||
type Options = MyObject | string;
|
||||
|
||||
function doThing(arg: Options) {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
22. Variables/properties which are `public static` should also be `readonly` when possible.
|
||||
23. Interface and type properties are terminated with semicolons, not commas.
|
||||
24. Prefer arrow formatting when declaring functions for interfaces/types:
|
||||
|
||||
```typescript
|
||||
interface Test {
|
||||
myCallback: (arg: string) => Promise<void>;
|
||||
}
|
||||
```
|
||||
|
||||
25. Prefer a type definition over an inline type. For example, define an interface.
|
||||
26. Always prefer to add types or declare a type over the use of `any`. Prefer inferred types
|
||||
when they are not `any`.
|
||||
1. When using `any`, a comment explaining why must be present.
|
||||
27. `import` should be used instead of `require`, as `require` does not have types.
|
||||
28. Export only what can be reused.
|
||||
29. Prefer a type like `Optional<X>` (`type Optional<T> = T | null | undefined`) instead
|
||||
of truly optional parameters.
|
||||
|
||||
1. A notable exception is when the likelihood of a bug is minimal, such as when a function
|
||||
takes an argument that is more often not required than required. An example where the
|
||||
`?` operator is inappropriate is when taking a room ID: typically the caller should
|
||||
supply the room ID if it knows it, otherwise deliberately acknowledge that it doesn't
|
||||
have one with `null`.
|
||||
|
||||
```typescript
|
||||
function doThingWithRoom(
|
||||
thing: string,
|
||||
room: Optional<string>, // require the caller to specify
|
||||
) {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
30. There should be approximately one interface, class, or enum per file unless the file is named
|
||||
"types.ts", "global.d.ts", or ends with "-types.ts".
|
||||
1. The file name should match the interface, class, or enum name.
|
||||
31. Bulk functions can be declared in a single file, though named as "foo-utils.ts" or "utils/foo.ts".
|
||||
32. Imports are grouped by external module imports first, then by internal imports.
|
||||
33. File ordering is not strict, but should generally follow this sequence:
|
||||
1. Licence header
|
||||
2. Imports
|
||||
3. Constants
|
||||
4. Enums
|
||||
5. Interfaces
|
||||
6. Functions
|
||||
7. Classes
|
||||
1. Public/protected/private static properties
|
||||
2. Public/protected/private properties
|
||||
3. Constructors
|
||||
4. Public/protected/private getters & setters
|
||||
5. Protected and abstract functions
|
||||
6. Public/private functions
|
||||
7. Public/protected/private static functions
|
||||
34. Variable names should be noticeably unique from their types. For example, "str: string" instead
|
||||
of "string: string".
|
||||
35. Use double quotes to enclose strings. You may use single quotes if the string contains double quotes.
|
||||
|
||||
```typescript
|
||||
const example1 = "simple string";
|
||||
const example2 = 'string containing "double quotes"';
|
||||
```
|
||||
|
||||
36. Prefer async-await to promise-chaining
|
||||
|
||||
```typescript
|
||||
async function () {
|
||||
const result = await anotherAsyncFunction();
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
37. Avoid functions whose fundamental behaviour varies with different parameter types.
|
||||
Multiple return types are fine, but if the function's behaviour is going to change significantly,
|
||||
have two separate functions. For example, `SDKConfig.get()` with a string param which returns the
|
||||
type according to the param given is ok, but `SDKConfig.get()` with no args returning the whole
|
||||
config object would not be: this should just be a separate function.
|
||||
|
||||
## React
|
||||
|
||||
Inheriting all the rules of TypeScript, the following additionally apply:
|
||||
|
||||
1. Types for lifecycle functions are not required (render, componentDidMount, and so on).
|
||||
2. Class components must always have a `Props` interface declared immediately above them. It can be
|
||||
empty if the component accepts no props.
|
||||
3. Class components should have an `State` interface declared immediately above them, but after `Props`.
|
||||
4. Props and State should not be exported. Use `React.ComponentProps<typeof ComponentNameHere>`
|
||||
instead.
|
||||
5. One component per file, except when a component is a utility component specifically for the "primary"
|
||||
component. The utility component should not be exported.
|
||||
6. Exported constants, enums, interfaces, functions, etc must be separate from files containing components
|
||||
or stores.
|
||||
7. Stores should use a singleton pattern with a static instance property:
|
||||
|
||||
```typescript
|
||||
class FooStore {
|
||||
public static readonly instance = new FooStore();
|
||||
|
||||
// or if the instance can't be created eagerly:
|
||||
private static _instance: FooStore;
|
||||
public static get instance(): FooStore {
|
||||
if (!FooStore._instance) {
|
||||
FooStore._instance = new FooStore();
|
||||
}
|
||||
return FooStore._instance;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
8. Stores must support using an alternative MatrixClient and dispatcher instance.
|
||||
9. Utilities which require JSX must be split out from utilities which do not. This is to prevent import
|
||||
cycles during runtime where components accidentally include more of the app than they intended.
|
||||
10. Interdependence between stores should be kept to a minimum. Break functions and constants out to utilities
|
||||
if at all possible.
|
||||
11. A component should only use CSS class names in line with the component name.
|
||||
|
||||
1. When knowingly using a class name from another component, document it with a [comment](#comments).
|
||||
|
||||
12. Curly braces within JSX should be padded with a space, however properties on those components should not.
|
||||
See above code example.
|
||||
13. Functions used as properties should either be defined on the class or stored in a variable. They should not
|
||||
be inline unless mocking/short-circuiting the value.
|
||||
14. Prefer hooks (functional components) over class components. Be consistent with the existing area if unsure
|
||||
which should be used.
|
||||
1. Unless the component is considered a "structure", in which case use classes.
|
||||
15. Write more views than structures. Structures are chunks of functionality like MatrixChat while views are
|
||||
isolated components.
|
||||
16. Components should serve a single, or near-single, purpose.
|
||||
17. Prefer to derive information from component properties rather than establish state.
|
||||
18. Do not use `React.Component::forceUpdate`.
|
||||
|
||||
## Stylesheets (\*.pcss = PostCSS + Plugins)
|
||||
|
||||
Note: We use PostCSS + some plugins to process our styles. It looks like SCSS, but actually it is not.
|
||||
|
||||
1. Class names must be prefixed with "mx\_".
|
||||
2. Class names must denote the component which defines them, followed by any context.
|
||||
The context is not further specified here in terms of meaning or syntax.
|
||||
Use whatever is appropriate for your implementation use case.
|
||||
Some examples:
|
||||
1. `mx_MyFoo`
|
||||
2. `mx_MyFoo_avatar`
|
||||
3. `mx_MyFoo_avatarUser`
|
||||
4. `mx_MyFoo_avatar--user`
|
||||
3. Use the `$font` variables instead of manual values.
|
||||
4. Keep indentation/nesting to a minimum. Maximum suggested nesting is 5 layers.
|
||||
5. Use the whole class name instead of shortcuts:
|
||||
|
||||
```scss
|
||||
.mx_MyFoo {
|
||||
& .mx_MyFoo_avatar {
|
||||
// instead of &_avatar
|
||||
// ...
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
6. Break multiple selectors over multiple lines this way:
|
||||
|
||||
```scss
|
||||
.mx_MyFoo,
|
||||
.mx_MyBar,
|
||||
.mx_MyFooBar {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
7. Non-shared variables should use $lowerCamelCase. Shared variables use $dashed-naming.
|
||||
8. Overrides to Z indexes, adjustments of dimensions/padding with pixels, and so on should all be
|
||||
[documented](#comments) for what the values mean:
|
||||
|
||||
```scss
|
||||
.mx_MyFoo {
|
||||
width: calc(100% - 12px); // 12px for read receipts
|
||||
top: -2px; // visually centred vertically
|
||||
z-index: 10; // above user avatar, but below dialogs
|
||||
}
|
||||
```
|
||||
|
||||
9. Avoid the use of `!important`. If `!important` is necessary, add a [comment](#comments) explaining why.
|
||||
|
||||
## Tests
|
||||
|
||||
1. Tests must be written in TypeScript.
|
||||
2. Jest mocks are declared below imports, but above everything else.
|
||||
3. Use the following convention template:
|
||||
|
||||
```typescript
|
||||
// Describe the class, component, or file name.
|
||||
describe("FooComponent", () => {
|
||||
// all test inspecific variables go here
|
||||
|
||||
beforeEach(() => {
|
||||
// exclude if not used.
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
// exclude if not used.
|
||||
});
|
||||
|
||||
// Use "it should..." terminology
|
||||
it("should call the correct API", async () => {
|
||||
// test-specific variables go here
|
||||
// function calls/state changes go here
|
||||
// expectations go here
|
||||
});
|
||||
});
|
||||
|
||||
// If the file being tested is a utility class:
|
||||
describe("foo-utils", () => {
|
||||
describe("firstUtilFunction", () => {
|
||||
it("should...", async () => {
|
||||
// ...
|
||||
});
|
||||
});
|
||||
|
||||
describe("secondUtilFunction", () => {
|
||||
it("should...", async () => {
|
||||
// ...
|
||||
});
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
## Comments
|
||||
|
||||
1. As a general principle: be liberal with comments. This applies to all files: stylesheets as well as
|
||||
JavaScript/TypeScript.
|
||||
|
||||
Good comments not only help future readers understand and maintain the code; they can also encourage good design
|
||||
by clearly setting out how different parts of the codebase interact where that would otherwise be implicit and
|
||||
subject to interpretation.
|
||||
|
||||
2. Aim to document all types, methods, class properties, functions, etc, with [TSDoc](https://tsdoc.org/) doc comments.
|
||||
This is _especially_ important for public interfaces in `matrix-js-sdk`, but is good practice in general.
|
||||
|
||||
Even very simple interfaces can often benefit from a doc-comment, both as a matter of consistency, and because simple
|
||||
interfaces have a habit of becoming more complex over time.
|
||||
|
||||
3. React components should be documented in the same way as other classes or functions. The documentation should give
|
||||
a brief description of how the component should be used, and, especially for more complex components, each of its
|
||||
properties should be clearly documented.
|
||||
|
||||
4. Inside a function, there is no need to comment every line, but consider:
|
||||
|
||||
- before a particular multiline section of code within the function, give an overview of what it does,
|
||||
to make it easier for a reader to follow the flow through the function as a whole.
|
||||
- if it is anything less than obvious, explain _why_ we are doing a particular operation, with particular emphasis
|
||||
on how this function interacts with other parts of the codebase.
|
||||
|
||||
5. When making changes to existing code, authors are expected to read existing comments and make any necessary changes
|
||||
to ensure they remain accurate.
|
||||
|
||||
6. Reviewers are encouraged to consider whether more comments would be useful, and to ask the author to add them.
|
||||
|
||||
It is natural for an author to feel that the code they have just written is "obvious" and that comments would be
|
||||
redundant, whereas in reality it would take some time for reader unfamiliar with the code to understand it. A
|
||||
reviewer is well-placed to make a more objective judgement.
|
||||
5
components.json
Normal file
5
components.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"src/components/views/auth/AuthFooter.tsx": "src/components/views/auth/VectorAuthFooter.tsx",
|
||||
"src/components/views/auth/AuthHeaderLogo.tsx": "src/components/views/auth/VectorAuthHeaderLogo.tsx",
|
||||
"src/components/views/auth/AuthPage.tsx": "src/components/views/auth/VectorAuthPage.tsx"
|
||||
}
|
||||
@@ -12,6 +12,7 @@
|
||||
"disable_guests": false,
|
||||
"disable_login_language_selector": false,
|
||||
"disable_3pid_login": false,
|
||||
"force_verification": false,
|
||||
"brand": "Element",
|
||||
"integrations_ui_url": "https://scalar.vector.im/",
|
||||
"integrations_rest_url": "https://scalar.vector.im/api",
|
||||
@@ -22,31 +23,29 @@
|
||||
"https://scalar-staging.vector.im/api",
|
||||
"https://scalar-staging.riot.im/scalar/api"
|
||||
],
|
||||
"bug_report_endpoint_url": "https://element.io/bugreports/submit",
|
||||
"defaultCountryCode": "GB",
|
||||
"showLabsSettings": false,
|
||||
"features": { },
|
||||
"default_widget_container_height": 280,
|
||||
"default_country_code": "GB",
|
||||
"show_labs_settings": false,
|
||||
"features": {},
|
||||
"default_federate": true,
|
||||
"default_theme": "light",
|
||||
"roomDirectory": {
|
||||
"servers": [
|
||||
"matrix.org"
|
||||
]
|
||||
},
|
||||
"piwik": {
|
||||
"url": "https://piwik.riot.im/",
|
||||
"whitelistedHSUrls": ["https://matrix.org"],
|
||||
"whitelistedISUrls": ["https://vector.im", "https://matrix.org"],
|
||||
"siteId": 1
|
||||
"room_directory": {
|
||||
"servers": ["matrix.org"]
|
||||
},
|
||||
"enable_presence_by_hs_url": {
|
||||
"https://matrix.org": false,
|
||||
"https://matrix-client.matrix.org": false
|
||||
},
|
||||
"settingDefaults": {
|
||||
"setting_defaults": {
|
||||
"breadcrumbs": true
|
||||
},
|
||||
"jitsi": {
|
||||
"preferredDomain": "jitsi.riot.im"
|
||||
}
|
||||
"preferred_domain": "meet.element.io"
|
||||
},
|
||||
"element_call": {
|
||||
"url": "https://call.element.io",
|
||||
"participant_limit": 8,
|
||||
"brand": "Element Call"
|
||||
},
|
||||
"map_style_url": "https://api.maptiler.com/maps/streets/style.json?key=fU3vlMsMn4Jb6dnEIFsx"
|
||||
}
|
||||
|
||||
@@ -1,17 +1,13 @@
|
||||
{
|
||||
"name": "Element",
|
||||
"name": "Element",
|
||||
"description": "A glossy Matrix collaboration client for the web.",
|
||||
"repository": {
|
||||
"url": "https://github.com/vector-im/element-web",
|
||||
"license": "Apache License 2.0"
|
||||
"url": "https://github.com/element-hq/element-web",
|
||||
"license": "AGPL-3.0-only OR GPL-3.0-only"
|
||||
},
|
||||
"bugs": {
|
||||
"list": "https://github.com/vector-im/element-web/issues",
|
||||
"report": "https://github.com/vector-im/element-web/issues/new/choose"
|
||||
"list": "https://github.com/element-hq/element-web/issues",
|
||||
"report": "https://github.com/element-hq/element-web/issues/new/choose"
|
||||
},
|
||||
"keywords": [
|
||||
"chat",
|
||||
"riot",
|
||||
"matrix"
|
||||
]
|
||||
"keywords": ["chat", "riot", "matrix"]
|
||||
}
|
||||
|
||||
2
debian/.gitignore
vendored
Normal file
2
debian/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
/files
|
||||
/tmp
|
||||
1
debian/conffiles
vendored
Normal file
1
debian/conffiles
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/etc/element-web/config.json
|
||||
13
debian/control
vendored
Executable file
13
debian/control
vendored
Executable file
@@ -0,0 +1,13 @@
|
||||
Source: element-web
|
||||
Maintainer: support@element.io
|
||||
Section: web
|
||||
Priority: optional
|
||||
Homepage: https://element.io/
|
||||
|
||||
Package: element-web
|
||||
Architecture: all
|
||||
Recommends: httpd, element-io-archive-keyring
|
||||
Description:
|
||||
A feature-rich client for Matrix.org
|
||||
This package contains the web-based client that can be served through a web
|
||||
server.
|
||||
55
docs/SUMMARY.md
Normal file
55
docs/SUMMARY.md
Normal file
@@ -0,0 +1,55 @@
|
||||
# Summary
|
||||
|
||||
- [Introduction](../README.md)
|
||||
|
||||
# Usage
|
||||
|
||||
- [Betas](betas.md)
|
||||
- [Labs](labs.md)
|
||||
|
||||
# Setup
|
||||
|
||||
- [Install](install.md)
|
||||
- [Config](config.md)
|
||||
- [Custom home page](custom-home.md)
|
||||
- [Kubernetes](kubernetes.md)
|
||||
- [Jitsi](jitsi.md)
|
||||
- [Encryption](e2ee.md)
|
||||
|
||||
# Build
|
||||
|
||||
- [Customisations](customisations.md)
|
||||
- [Modules](modules.md)
|
||||
- [Native Node modules](native-node-modules.md)
|
||||
|
||||
# Contribution
|
||||
|
||||
- [Choosing an issue](choosing-an-issue.md)
|
||||
- [Translation](translating.md)
|
||||
- [Netlify builds](pr-previews.md)
|
||||
- [Code review](review.md)
|
||||
|
||||
# Development
|
||||
|
||||
- [App load order](app-load.md)
|
||||
- [Translation](translating-dev.md)
|
||||
- [Theming](theming.md)
|
||||
- [Playwright end to end tests](playwright.md)
|
||||
- [Memory profiling](memory-profiles-and-leaks.md)
|
||||
- [Jitsi](jitsi-dev.md)
|
||||
- [Feature flags](feature-flags.md)
|
||||
- [OIDC and delegated authentication](oidc.md)
|
||||
- [Release Process](release.md)
|
||||
|
||||
# Deep dive
|
||||
|
||||
- [Skinning](skinning.md)
|
||||
- [Cider editor](ciderEditor.md)
|
||||
- [Iconography](icons.md)
|
||||
- [Jitsi](jitsi.md)
|
||||
- [Local echo](local-echo-dev.md)
|
||||
- [Media](media-handling.md)
|
||||
- [Room List Store](room-list-store.md)
|
||||
- [Scrolling](scrolling.md)
|
||||
- [Usercontent](usercontent.md)
|
||||
- [Widget layouts](widget-layouts.md)
|
||||
155
docs/app-load.md
155
docs/app-load.md
@@ -1,81 +1,108 @@
|
||||
# App load order
|
||||
|
||||
**Dev note**: As of March 2022, the skin is no longer part of the app load order at all. The document's graphs have
|
||||
been kept untouched for posterity.
|
||||
|
||||
Old slow flow:
|
||||

|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A1(((load_modernizr))) --> B
|
||||
A2((rageshake)) --> B
|
||||
B(((skin))) --> C
|
||||
C(((olm))) --> D
|
||||
D{mobile} --> E
|
||||
E((config)) --> F
|
||||
F((i18n)) --> G
|
||||
style F stroke:lime
|
||||
G(((theme))) --> H
|
||||
H(((modernizr))) --> app
|
||||
style H stroke:red
|
||||
```
|
||||
|
||||
Current more parallel flow:
|
||||

|
||||
|
||||
<details><summary>Code</summary>
|
||||
<p>
|
||||
<pre><code>
|
||||
digraph G {
|
||||
node [shape=box];
|
||||
```mermaid
|
||||
flowchart TD
|
||||
subgraph index.ts
|
||||
style index.ts stroke:orange
|
||||
|
||||
subgraph cluster_0 {
|
||||
color=orange;
|
||||
node [style=filled];
|
||||
label = "index.ts";
|
||||
A[/rageshake/] --> B{mobile}
|
||||
B-- No -->C1(.)
|
||||
B-- Yes -->C2((redirect))
|
||||
C1 --> D[/olm/] --> R
|
||||
C1 --> E[platform] --> F[/config/]
|
||||
F --> G1[/skin/]
|
||||
F --> R
|
||||
G1 --> H
|
||||
G1 --> R
|
||||
F --> G2[/theme/]
|
||||
G2 --> H
|
||||
G2 --> R
|
||||
F --> G3[/i18n/]
|
||||
G3 --> H
|
||||
G3 --> R
|
||||
H{modernizr}-- No --> J((incompatible))-- user ignore --> R
|
||||
H-- Yes --> R
|
||||
|
||||
entrypoint, s0, ready [shape=point];
|
||||
rageshake, config, i18n, theme, skin, olm [shape=parallelogram];
|
||||
mobile [shape=diamond, label="mobile"];
|
||||
modernizr [shape=diamond];
|
||||
redirect, incompatible [shape=egg];
|
||||
linkStyle 0,7,9,11,12,14,15 stroke:blue;
|
||||
linkStyle 4,8,10,13,16 stroke:red;
|
||||
end
|
||||
|
||||
entrypoint -> rageshake;
|
||||
rageshake -> mobile [color=blue];
|
||||
mobile -> s0 [label="No"];
|
||||
mobile -> redirect [label="Yes"];
|
||||
R>ready] --> 2A
|
||||
style R stroke:gray
|
||||
|
||||
s0 -> platform;
|
||||
s0 -> olm;
|
||||
platform -> config;
|
||||
subgraph init.tsx
|
||||
style init.tsx stroke:lime
|
||||
2A[loadApp] --> 2B[matrixchat]
|
||||
end
|
||||
|
||||
config -> i18n [color=blue];
|
||||
config -> theme [color=blue];
|
||||
config -> skin [color=blue];
|
||||
|
||||
i18n -> modernizr [color=blue];
|
||||
theme -> modernizr [color=blue];
|
||||
skin -> modernizr [color=blue];
|
||||
|
||||
modernizr -> ready [label="Yes"];
|
||||
modernizr -> incompatible [label="No"];
|
||||
incompatible -> ready [label="user ignore"];
|
||||
|
||||
olm -> ready [color=red];
|
||||
config -> ready [color=red];
|
||||
skin -> ready [color=red];
|
||||
theme -> ready [color=red];
|
||||
i18n -> ready [color=red];
|
||||
}
|
||||
|
||||
subgraph cluster_1 {
|
||||
color = green;
|
||||
node [style=filled];
|
||||
label = "init.tsx";
|
||||
|
||||
ready -> loadApp;
|
||||
loadApp -> matrixchat;
|
||||
}
|
||||
}
|
||||
</code></pre>
|
||||
</p>
|
||||
</details>
|
||||
```
|
||||
|
||||
Key:
|
||||
+ Parallelogram: async/await task
|
||||
+ Box: sync task
|
||||
+ Diamond: conditional branch
|
||||
+ Egg: user interaction
|
||||
+ Blue arrow: async task is allowed to settle but allowed to fail
|
||||
+ Red arrow: async task success is asserted
|
||||
|
||||
- Parallelogram: async/await task
|
||||
- Box: sync task
|
||||
- Diamond: conditional branch
|
||||
- Circle: user interaction
|
||||
- Blue arrow: async task is allowed to settle but allowed to fail
|
||||
- Red arrow: async task success is asserted
|
||||
|
||||
Notes:
|
||||
+ A task begins when all its dependencies (arrows going into it) are fulfilled.
|
||||
+ The success of setting up rageshake is never asserted, element-web has a fallback path for running without IDB (and thus rageshake).
|
||||
+ Everything is awaited to be settled before the Modernizr check, to allow it to make use of things like i18n if they are successful.
|
||||
|
||||
- A task begins when all its dependencies (arrows going into it) are fulfilled.
|
||||
- The success of setting up rageshake is never asserted, element-web has a fallback path for running without IDB (and thus rageshake).
|
||||
- Everything is awaited to be settled before the Modernizr check, to allow it to make use of things like i18n if they are successful.
|
||||
|
||||
Underlying dependencies:
|
||||

|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A((rageshake))
|
||||
B{mobile}
|
||||
C((config))
|
||||
D(((olm)))
|
||||
E((i18n))
|
||||
F(((load_modernizr)))
|
||||
G(((modernizr)))
|
||||
H(((skin)))
|
||||
I(((theme)))
|
||||
X[app]
|
||||
|
||||
A --> G
|
||||
A --> B
|
||||
A-- assert -->X
|
||||
F --> G --> X
|
||||
G --> H --> X
|
||||
C --> I --> X
|
||||
C --> E --> X
|
||||
E --> G
|
||||
B --> C-- assert -->X
|
||||
B --> D --> X
|
||||
|
||||
style X stroke:red
|
||||
style G stroke:red
|
||||
style E stroke:lime
|
||||
linkStyle 0,11 stroke:yellow;
|
||||
linkStyle 2,13 stroke:red;
|
||||
```
|
||||
|
||||
14
docs/betas.md
Normal file
14
docs/betas.md
Normal file
@@ -0,0 +1,14 @@
|
||||
# Beta features
|
||||
|
||||
Beta features are features that are not ready for production yet but the team
|
||||
wants more people to try the features and give feedback on them.
|
||||
|
||||
Before a feature gets into its beta phase, it is often a labs feature (see
|
||||
[Labs](https://github.com/element-hq/element-web/blob/develop/docs/labs.md)).
|
||||
|
||||
**Be warned! Beta features may not be completely finalised or stable!**
|
||||
|
||||
## Video rooms (`feature_video_rooms`)
|
||||
|
||||
Enables support for creating and joining video rooms, which are persistent video
|
||||
chats that users can jump in and out of.
|
||||
1867
docs/changelogs/CHANGELOG-2022.md
Normal file
1867
docs/changelogs/CHANGELOG-2022.md
Normal file
File diff suppressed because it is too large
Load Diff
1017
docs/changelogs/CHANGELOG-2023.md
Normal file
1017
docs/changelogs/CHANGELOG-2023.md
Normal file
File diff suppressed because it is too large
Load Diff
6035
docs/changelogs/CHANGELOG-pre-2022.md
Normal file
6035
docs/changelogs/CHANGELOG-pre-2022.md
Normal file
File diff suppressed because it is too large
Load Diff
80
docs/choosing-an-issue.md
Normal file
80
docs/choosing-an-issue.md
Normal file
@@ -0,0 +1,80 @@
|
||||
# Choosing an issue to work on
|
||||
|
||||
So you want to contribute to Element Web? That is awesome!
|
||||
|
||||
If you're not sure where to start, make sure you read
|
||||
[CONTRIBUTING.md](../CONTRIBUTING.md), and the
|
||||
[Development](../README.md#development) and
|
||||
[Setting up a dev environment](../README.md#setting-up-a-dev-environment)
|
||||
sections of the README.
|
||||
|
||||
Maybe you've got something specific you'd like to work on? If so, make sure you
|
||||
create an issue and
|
||||
[discuss it with the developers](https://matrix.to/#/#element-dev:matrix.org)
|
||||
before you put a lot of time into it.
|
||||
|
||||
If you're looking for inspiration on where to start, keep reading!
|
||||
|
||||
## Finding a good first issue
|
||||
|
||||
All the issues for Element Web live in the
|
||||
[element-web](https://github.com/element-hq/element-web) repository, including
|
||||
issues that actually need fixing in one of the related repos.
|
||||
|
||||
The first place to look is for
|
||||
[issues tagged with "good first issue"](https://github.com/element-hq/element-web/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22).
|
||||
|
||||
Look through that list and find something that catches your interest. If there
|
||||
is nothing, there, try gently asking in
|
||||
[#element-dev:matrix.org](https://matrix.to/#/#element-dev:matrix.org) for
|
||||
someone to add something.
|
||||
|
||||
When you're looking through the list, here are some things that might make an
|
||||
issue a **GOOD** choice:
|
||||
|
||||
- It is a problem or feature you care about.
|
||||
- It concerns a type of code you know a little about.
|
||||
- You think you can understand what's needed.
|
||||
- It already has approval from Element Web's designers (look for comments from
|
||||
members of the
|
||||
[Product](https://github.com/orgs/element-hq/teams/product/members) or
|
||||
[Design](https://github.com/orgs/element-hq/teams/design/members) teams).
|
||||
|
||||
Here are some things that might make it a **BAD** choice:
|
||||
|
||||
- You don't understand it (maybe add a comment asking a clarifying question).
|
||||
- It sounds difficult, or is part of a larger change you don't know about.
|
||||
- **It is tagged with `X-Needs-Design` or `X-Needs-Product`.**
|
||||
|
||||
**Element Web's Design and Product teams tend to be very busy**, so if you make
|
||||
changes that require approval from one of those teams, you will probably have
|
||||
to wait a very long time. The kind of change affected by this is changing the
|
||||
way the product works, or how it looks in a specific area.
|
||||
|
||||
## Finding a good second issue
|
||||
|
||||
Once you've fixed a few small things, you can consider taking on something a
|
||||
little larger. This should mostly be driven by what you find interesting, but
|
||||
you may also find the
|
||||
[Help Wanted](https://github.com/element-hq/element-web/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3A%22Help+Wanted%22)
|
||||
label useful.
|
||||
|
||||
Note that the same comment applies as in the previous section: if you want to
|
||||
work in areas that require Design or Product approval, you should look to join
|
||||
existing work that is already designed, as getting approval for your random
|
||||
change will take a very long time.
|
||||
|
||||
So you should **always avoid issues tagged with `X-Needs-Design` or
|
||||
`X-Needs-Product`**.
|
||||
|
||||
## Asking questions
|
||||
|
||||
Feel free to ask questions about the issues or how to choose them in the
|
||||
[#element-dev:matrix.org](https://matrix.to/#/#element-dev:matrix.org) Matrix
|
||||
room.
|
||||
|
||||
## Thank you
|
||||
|
||||
Thank you again for contributing to Element Web. We welcome your contributions
|
||||
and are grateful for your work. We find working on it great fun, and we hope
|
||||
you do too!
|
||||
71
docs/ciderEditor.md
Normal file
71
docs/ciderEditor.md
Normal file
@@ -0,0 +1,71 @@
|
||||
# The CIDER (Contenteditable-Input-Diff-Error-Reconcile) editor
|
||||
|
||||
The CIDER editor is a custom editor written for Element.
|
||||
Most of the code can be found in the `/editor/` directory.
|
||||
It is used to power the composer main composer (both to send and edit messages), and might be used for other usecases where autocomplete is desired (invite box, ...).
|
||||
|
||||
## High-level overview.
|
||||
|
||||
The editor is backed by a model that contains parts.
|
||||
A part has some text and a type (plain text, pill, ...). When typing in the editor,
|
||||
the model validates the input and updates the parts.
|
||||
The parts are then reconciled with the DOM.
|
||||
|
||||
## Inner workings
|
||||
|
||||
When typing in the `contenteditable` element, the `input` event fires and
|
||||
the DOM of the editor is turned into a string. The way this is done has
|
||||
some logic to it to deal with adding newlines for block elements, to make sure
|
||||
the caret offset is calculated in the same way as the content string, and to ignore
|
||||
caret nodes (more on that later).
|
||||
For these reasons it doesn't use `innerText`, `textContent` or anything similar.
|
||||
The model addresses any content in the editor within as an offset within this string.
|
||||
The caret position is thus also converted from a position in the DOM tree
|
||||
to an offset in the content string. This happens in `getCaretOffsetAndText` in `dom.ts`.
|
||||
|
||||
Once the content string and caret offset is calculated, it is passed to the `update()`
|
||||
method of the model. The model first calculates the same content string of its current parts,
|
||||
basically just concatenating their text. It then looks for differences between
|
||||
the current and the new content string. The diffing algorithm is very basic,
|
||||
and assumes there is only one change around the caret offset,
|
||||
so this should be very inexpensive. See `diff.ts` for details.
|
||||
|
||||
The result of the diffing is the strings that were added and/or removed from
|
||||
the current content. These differences are then applied to the parts,
|
||||
where parts can apply validation logic to these changes.
|
||||
|
||||
For example, if you type an @ in some plain text, the plain text part rejects
|
||||
that character, and this character is then presented to the part creator,
|
||||
which will turn it into a pill candidate part.
|
||||
Pill candidate parts are what opens the auto completion, and upon picking a completion,
|
||||
replace themselves with an actual pill which can't be edited anymore.
|
||||
|
||||
The diffing is needed to preserve state in the parts apart from their text
|
||||
(which is the only thing the model receives from the DOM), e.g. to build
|
||||
the model incrementally. Any text that didn't change is assumed
|
||||
to leave the parts it intersects alone.
|
||||
|
||||
The benefit of this is that we can use the `input` event, which is broadly supported,
|
||||
to find changes in the editor. We don't have to rely on keyboard events,
|
||||
which relate poorly to text input or changes, and don't need the `beforeinput` event,
|
||||
which isn't broadly supported yet.
|
||||
|
||||
Once the parts of the model are updated, the DOM of the editor is then reconciled
|
||||
with the new model state, see `renderModel` in `render.ts` for this.
|
||||
If the model didn't reject the input and didn't make any additional changes,
|
||||
this won't make any changes to the DOM at all, and should thus be fairly efficient.
|
||||
|
||||
For the browser to allow the user to place the caret between two pills,
|
||||
or between a pill and the start and end of the line, we need some extra DOM nodes.
|
||||
These DOM nodes are called caret nodes, and contain an invisble character, so
|
||||
the caret can be placed into them. The model is unaware of caret nodes, and they
|
||||
are only added to the DOM during the render phase. Likewise, when calculating
|
||||
the content string, caret nodes need to be ignored, as they would confuse the model.
|
||||
|
||||
As part of the reconciliation, the caret position is also adjusted to any changes
|
||||
the model made to the input. The caret is passed around in two formats.
|
||||
The model receives the caret _offset_ within the content string (which includes
|
||||
an atNodeEnd flag to make it unambiguous if it is at a part and or the next part start).
|
||||
The model converts this to a caret _position_ internally, which has a partIndex
|
||||
and an offset within the part text, which is more natural to work with.
|
||||
From there on, the caret _position_ is used, also during reconciliation.
|
||||
741
docs/config.md
741
docs/config.md
@@ -1,154 +1,517 @@
|
||||
Configuration
|
||||
=============
|
||||
# Configuration
|
||||
|
||||
You can configure the app by copying `config.sample.json` to
|
||||
`config.json` and customising it:
|
||||
### 🦖 Deprecation notice
|
||||
|
||||
For a good example, see https://develop.element.io/config.json.
|
||||
Configuration keys were previously a mix of camelCase and snake_case.
|
||||
We standardised to snake_case but added compatibility for camelCase to all settings.
|
||||
This backwards compatibility will be getting removed in a future release so please ensure you are using snake_case.
|
||||
|
||||
1. `default_server_config` sets the default homeserver and identity server URL for
|
||||
Element to use. The object is the same as returned by [https://<server_name>/.well-known/matrix/client](https://matrix.org/docs/spec/client_server/latest.html#get-well-known-matrix-client),
|
||||
with added support for a `server_name` under the `m.homeserver` section to display
|
||||
a custom homeserver name. Alternatively, the config can contain a `default_server_name`
|
||||
instead which is where Element will go to get that same object, although this option is
|
||||
deprecated - see the `.well-known` link above for more information on using this option.
|
||||
Note that the `default_server_name` is used to get a complete server configuration
|
||||
whereas the `server_name` in the `default_server_config` is for display purposes only.
|
||||
* *Note*: The URLs can also be individually specified as `default_hs_url` and
|
||||
`default_is_url`, however these are deprecated. They are maintained for backwards
|
||||
compatibility with older configurations. `default_is_url` is respected only
|
||||
if `default_hs_url` is used.
|
||||
* Element will fail to load if a mix of `default_server_config`, `default_server_name`, or
|
||||
`default_hs_url` is specified. When multiple sources are specified, it is unclear
|
||||
which should take priority and therefore the application cannot continue.
|
||||
* As of Element 1.4.0, identity servers are optional. See [Identity servers](#identity-servers) below.
|
||||
1. `sso_immediate_redirect`: When `true`, Element will assume the default server supports SSO
|
||||
and attempt to send the user there to continue (if they aren't already logged in). Default
|
||||
`false`. Note that this disables all usage of the welcome page.
|
||||
1. `features`: Lookup of optional features that may be force-enabled (`true`) or force-disabled (`false`).
|
||||
When features are not listed here, their defaults will be used, and users can turn them on/off if `showLabsSettings`
|
||||
allows them to. The available optional experimental features vary from release to release and are
|
||||
[documented](labs.md). The feature flag process is [documented](feature-flags.md) as well.
|
||||
1. `showLabsSettings`: Shows the "labs" tab of user settings. Useful to allow users to turn on experimental features
|
||||
they might not otherwise have access to.
|
||||
1. `brand`: String to pass to your homeserver when configuring email notifications, to let the
|
||||
homeserver know what email template to use when talking to you.
|
||||
1. `branding`: Configures various branding and logo details, such as:
|
||||
1. `welcomeBackgroundUrl`: An image to use as a wallpaper outside the app
|
||||
during authentication flows. If an array is passed, an image is chosen randomly for each visit.
|
||||
1. `authHeaderLogoUrl`: An logo image that is shown in the header during
|
||||
authentication flows
|
||||
1. `authFooterLinks`: a list of links to show in the authentication page footer:
|
||||
`[{"text": "Link text", "url": "https://link.target"}, {"text": "Other link", ...}]`
|
||||
1. `reportEvent`: Configures the dialog for reporting content to the homeserver
|
||||
admin.
|
||||
1. `adminMessageMD`: An extra message to show on the reporting dialog to
|
||||
mention homeserver-specific policies. Accepts Markdown.
|
||||
1. `integrations_ui_url`: URL to the web interface for the integrations server. The integrations
|
||||
server is not Element and normally not your homeserver either. The integration server settings
|
||||
may be left blank to disable integrations.
|
||||
1. `integrations_rest_url`: URL to the REST interface for the integrations server.
|
||||
1. `integrations_widgets_urls`: list of URLs to the REST interface for the widget integrations server.
|
||||
1. `bug_report_endpoint_url`: endpoint to send bug reports to (must be running a
|
||||
https://github.com/matrix-org/rageshake server). Bug reports are sent when a user clicks
|
||||
"Send Logs" within the application. Bug reports can be disabled/hidden by leaving the
|
||||
`bug_report_endpoint_url` out of your config file.
|
||||
1. `roomDirectory`: config for the public room directory. This section is optional.
|
||||
1. `roomDirectory.servers`: List of other homeservers' directories to include in the drop
|
||||
down list. Optional.
|
||||
1. `default_theme`: name of theme to use by default (e.g. 'light')
|
||||
1. `update_base_url` (electron app only): HTTPS URL to a web server to download
|
||||
updates from. This should be the path to the directory containing `macos`
|
||||
and `win32` (for update packages, not installer packages).
|
||||
1. `piwik`: Analytics can be disabled by setting `piwik: false` or by leaving the piwik config
|
||||
option out of your config file. If you want to enable analytics, set `piwik` to be an object
|
||||
containing the following properties:
|
||||
1. `url`: The URL of the Piwik instance to use for collecting analytics
|
||||
1. `whitelistedHSUrls`: a list of HS URLs to not redact from the analytics
|
||||
1. `whitelistedISUrls`: a list of IS URLs to not redact from the analytics
|
||||
1. `siteId`: The Piwik Site ID to use when sending analytics to the Piwik server configured above
|
||||
1. `welcomeUserId`: the user ID of a bot to invite whenever users register that can give them a tour
|
||||
1. `embeddedPages`: Configures the pages displayed in portions of Element that
|
||||
embed static files, such as:
|
||||
1. `welcomeUrl`: Initial content shown on the outside of the app when not
|
||||
logged in. Defaults to `welcome.html` supplied with Element.
|
||||
1. `homeUrl`: Content shown on the inside of the app when a specific room is
|
||||
not selected. By default, no home page is configured. If one is set, a
|
||||
button to access it will be shown in the top left menu.
|
||||
1. `loginForWelcome`: Overrides `welcomeUrl` to make the welcome page be the
|
||||
same page as the login page when `true`. This effectively disables the
|
||||
welcome page.
|
||||
1. `defaultCountryCode`: The ISO 3166 alpha2 country code to use when showing
|
||||
country selectors, like the phone number input on the registration page.
|
||||
Defaults to `GB` if the given code is unknown or not provided.
|
||||
1. `settingDefaults`: Defaults for settings that support the `config` level,
|
||||
as an object mapping setting name to value (note that the "theme" setting
|
||||
is special cased to the `default_theme` in the config file).
|
||||
1. `disable_custom_urls`: disallow the user to change the
|
||||
default homeserver when signing up or logging in.
|
||||
1. `permalinkPrefix`: Used to change the URL that Element generates permalinks with.
|
||||
By default, this is "https://matrix.to" to generate matrix.to (spec) permalinks.
|
||||
Set this to your Element instance URL if you run an unfederated server (eg:
|
||||
"https://element.example.org").
|
||||
1. `jitsi`: Used to change the default conference options. Learn more about the
|
||||
Jitsi options at [jitsi.md](./jitsi.md).
|
||||
1. `preferredDomain`: The domain name of the preferred Jitsi instance. Defaults
|
||||
to `jitsi.riot.im`. This is used whenever a user clicks on the voice/video
|
||||
call buttons - integration managers may use a different domain.
|
||||
1. `enable_presence_by_hs_url`: The property key should be the URL of the homeserver
|
||||
and its value defines whether to enable/disable the presence status display
|
||||
from that homeserver. If no options are configured, presence is shown for all
|
||||
homeservers.
|
||||
1. `disable_guests`: Disables guest access tokens and auto-guest registrations.
|
||||
Defaults to false (guests are allowed).
|
||||
1. `disable_login_language_selector`: Disables the login language selector. Defaults
|
||||
to false (language selector is shown).
|
||||
1. `disable_3pid_login`: Disables 3rd party identity options on login and registration form
|
||||
Defaults to false (3rd party identity options are shown).
|
||||
1. `default_federate`: Default option for room federation when creating a room
|
||||
Defaults to true (room federation enabled).
|
||||
1. `desktopBuilds`: Used to alter promotional links to the desktop app. By default
|
||||
the builds are considered available and accessible from https://element.io. This
|
||||
config option is typically used in the context of encouraging encrypted message
|
||||
search capabilities (Seshat). All the options listed below are required if this
|
||||
option is specified.
|
||||
1. `available`: When false, the desktop app will not be promoted to the user.
|
||||
1. `logo`: An HTTP URL to the avatar for the desktop build. Should be 24x24, ideally
|
||||
an SVG.
|
||||
1. `url`: An HTTP URL for where to send the user to download the desktop build.
|
||||
1. `mobileBuilds`: Used to alter promotional links to the mobile app. By default the
|
||||
builds are considered available and accessible from https://element.io. This config
|
||||
option is typically used in a context of encouraging the user to try the mobile app
|
||||
instead of a mobile/incompatible browser.
|
||||
1. `ios`: The URL to the iOS build. If `null`, it will be assumed to be not available.
|
||||
If not set, the default element.io builds will be used.
|
||||
1. `android`: The URL to the Android build. If `null`, it will be assumed to be not available.
|
||||
If not set, the default element.io builds will be used.
|
||||
1. `fdroid`: The URL to the FDroid build. If `null`, it will be assumed to be not available.
|
||||
If not set, the default element.io builds will be used.
|
||||
1. `mobileGuideToast`: Whether to show a toast a startup which nudges users on
|
||||
iOS and Android towards the native mobile apps. The toast redirects to the
|
||||
mobile guide if they accept. Defaults to false.
|
||||
1. `audioStreamUrl`: If supplied, show an option on Jitsi widgets to stream
|
||||
audio using Jitsi's live streaming feature. This option is experimental and
|
||||
may be removed at any time without notice.
|
||||
1. `voip`: Behaviour related to calls
|
||||
1. `obeyAssertedIdentity`: If set, MSC3086 asserted identity messages sent
|
||||
on VoIP calls will cause the call to appear in the room corresponding to the
|
||||
asserted identity. This *must* only be set in trusted environments.
|
||||
---
|
||||
|
||||
Note that `index.html` also has an og:image meta tag that is set to an image
|
||||
hosted on riot.im. This is the image used if links to your copy of Element
|
||||
appear in some websites like Facebook, and indeed Element itself. This has to be
|
||||
static in the HTML and an absolute URL (and HTTP rather than HTTPS), so it's
|
||||
not possible for this to be an option in config.json. If you'd like to change
|
||||
it, you can build Element, but run
|
||||
`RIOT_OG_IMAGE_URL="http://example.com/logo.png" yarn build`.
|
||||
Alternatively, you can edit the `og:image` meta tag in `index.html` directly
|
||||
each time you download a new version of Element.
|
||||
You can configure the app by copying `config.sample.json` to `config.json` or `config.$domain.json` and customising it.
|
||||
Element will attempt to load first `config.$domain.json` and if it fails `config.json`. This mechanism allows different
|
||||
configuration options depending on if you're hitting e.g. `app1.example.com` or `app2.example.com`. Configs are not mixed
|
||||
in any way, it either entirely uses the domain config, or entirely uses `config.json`.
|
||||
|
||||
Identity servers
|
||||
================
|
||||
The possible configuration options are described here. If you run into issues, please visit
|
||||
[#element-web:matrix.org](https://matrix.to/#/#element-web:matrix.org) on Matrix.
|
||||
|
||||
For a good example of a production-tuned config, see https://app.element.io/config.json
|
||||
|
||||
For an example of a development/beta-tuned config, see https://develop.element.io/config.json
|
||||
|
||||
After changing the config, the app will need to be reloaded. For web browsers this is a simple page refresh, however
|
||||
for the desktop app the application will need to be exited fully (including via the task tray) and re-started.
|
||||
|
||||
## Homeserver configuration
|
||||
|
||||
In order for Element to even start you will need to tell it what homeserver to connect to _by default_. Users will be
|
||||
able to use a different homeserver if they like, though this can be disabled with `"disable_custom_urls": true` in your
|
||||
config.
|
||||
|
||||
One of the following options **must** be supplied:
|
||||
|
||||
1. `default_server_config`: The preferred method of setting the homeserver connection information. Simply copy/paste
|
||||
your [`/.well-known/matrix/client`](https://spec.matrix.org/latest/client-server-api/#getwell-knownmatrixclient)
|
||||
into this field. For example:
|
||||
```json
|
||||
{
|
||||
"default_server_config": {
|
||||
"m.homeserver": {
|
||||
"base_url": "https://matrix-client.matrix.org"
|
||||
},
|
||||
"m.identity_server": {
|
||||
"base_url": "https://vector.im"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
2. `default_server_name`: A different method of connecting to the homeserver by looking up the connection information
|
||||
using `.well-known`. When using this option, simply use your server's domain name (the part at the end of user IDs):
|
||||
`"default_server_name": "matrix.org"`
|
||||
3. <del>`default_hs_url` and (optionally) `default_is_url`</del>: A very deprecated method of defining the connection
|
||||
information. These are the same values seen as `base_url` in the `default_server_config` example, with `default_is_url`
|
||||
being optional.
|
||||
|
||||
If both `default_server_config` and `default_server_name` are used, Element will try to look up the connection
|
||||
information using `.well-known`, and if that fails, take `default_server_config` as the homeserver connection
|
||||
information.
|
||||
|
||||
## Labs flags
|
||||
|
||||
Labs flags are optional, typically beta or in-development, features that can be turned on or off. The full range of
|
||||
labs flags and their development status are documented [here](./labs.md). If interested, the feature flag process is
|
||||
documented [here](./feature-flags.md).
|
||||
|
||||
To force a labs flag on or off, use the following:
|
||||
|
||||
```json
|
||||
{
|
||||
"features": {
|
||||
"feature_you_want_to_turn_on": true,
|
||||
"feature_you_want_to_keep_off": false
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
If you'd like the user to be able to self-select which labs flags they can turn on, add `"show_labs_settings": true` to
|
||||
your config. This will turn on the tab in user settings.
|
||||
|
||||
**Note**: Feature support varies release-by-release. Check the [labs flag documentation](./labs.md) frequently if enabling
|
||||
the functionality.
|
||||
|
||||
## Default settings
|
||||
|
||||
Some settings additionally support being specified at the config level to affect the user experience of your Element Web
|
||||
instance. As of writing those settings are not fully documented, however a few are:
|
||||
|
||||
1. `default_federate`: When `true` (default), rooms will be marked as "federatable" during creation. Typically this setting
|
||||
shouldn't be used as the federation capabilities of a room **cannot** be changed after the room is created.
|
||||
2. `default_country_code`: An optional ISO 3166 alpha2 country code (eg: `GB`, the default) to use when showing phone number
|
||||
inputs.
|
||||
3. `room_directory`: Optionally defines how the room directory component behaves. Currently only a single property, `servers`
|
||||
is supported to add additional servers to the dropdown. For example:
|
||||
```json
|
||||
{
|
||||
"room_directory": {
|
||||
"servers": ["matrix.org", "example.org"]
|
||||
}
|
||||
}
|
||||
```
|
||||
4. `setting_defaults`: Optional configuration for settings which are not described by this document and support the `config`
|
||||
level. This list is incomplete. For example:
|
||||
```json
|
||||
{
|
||||
"setting_defaults": {
|
||||
"MessageComposerInput.showStickersButton": false,
|
||||
"MessageComposerInput.showPollsButton": false
|
||||
}
|
||||
}
|
||||
```
|
||||
These values will take priority over the hardcoded defaults for the settings. For a list of available settings, see
|
||||
[Settings.tsx](https://github.com/element-hq/element-web/blob/develop/src/settings/Settings.tsx).
|
||||
|
||||
## Customisation & branding
|
||||
|
||||
<!-- Author's note: https://english.stackexchange.com/questions/570116/alternative-ways-of-saying-white-labeled -->
|
||||
|
||||
Element supports some customisation of the user experience through various branding and theme options. While it doesn't support
|
||||
complete re-branding/private labeling, a more personalised experience can be achieved for your users.
|
||||
|
||||
1. `default_theme`: Typically either `light` (the default) or `dark`, this is the optional name of the colour theme to use.
|
||||
If using custom themes, this can be a theme name from that as well.
|
||||
2. `default_device_display_name`: Optional public name for devices created by login and registration, instead of the default
|
||||
templated string. Note that this option does not support templating, currently.
|
||||
3. `brand`: Optional name for the app. Defaults to `Element`. This is used throughout the application in various strings/locations.
|
||||
4. `permalink_prefix`: An optional URL pointing to an Element Web deployment. For example, `https://app.element.io`. This will
|
||||
change all permalinks (via the "Share" menus) to point at the Element Web deployment rather than `matrix.to`.
|
||||
5. `desktop_builds`: Optional. Where the desktop builds for the application are, if available. This is explained in more detail
|
||||
down below.
|
||||
6. `mobile_builds`: Optional. Like `desktop_builds`, except for the mobile apps. Also described in more detail down below.
|
||||
7. `mobile_guide_toast`: When `true` (default), users accessing the Element Web instance from a mobile device will be prompted to
|
||||
download the app instead.
|
||||
8. `update_base_url`: For the desktop app only, the URL where to acquire update packages. If specified, must be a path to a directory
|
||||
containing `macos` and `win32` directories, with the update packages within. Defaults to `https://packages.element.io/desktop/update/`
|
||||
in production.
|
||||
9. `map_style_url`: Map tile server style URL for location sharing. e.g. `https://api.maptiler.com/maps/streets/style.json?key=YOUR_KEY_GOES_HERE`
|
||||
This setting is ignored if your homeserver provides `/.well-known/matrix/client` in its well-known location, and the JSON file
|
||||
at that location has a key `m.tile_server` (or the unstable version `org.matrix.msc3488.tile_server`). In this case, the
|
||||
configuration found in the well-known location is used instead.
|
||||
10. `welcome_user_id`: **DEPRECATED** An optional user ID to start a DM with after creating an account. Defaults to nothing (no DM created).
|
||||
11. `custom_translations_url`: An optional URL to allow overriding of translatable strings. The JSON file must be in a format of
|
||||
`{"affected|translation|key": {"languageCode": "new string"}}`. See https://github.com/matrix-org/matrix-react-sdk/pull/7886 for details.
|
||||
12. `branding`: Options for configuring various assets used within the app. Described in more detail down below.
|
||||
13. `embedded_pages`: Further optional URLs for various assets used within the app. Described in more detail down below.
|
||||
14. `disable_3pid_login`: When `false` (default), **enables** the options to log in with email address or phone number. Set to
|
||||
`true` to hide these options.
|
||||
15. `disable_login_language_selector`: When `false` (default), **enables** the language selector on the login pages. Set to `true`
|
||||
to hide this dropdown.
|
||||
16. `disable_guests`: When `false` (default), **enable** guest-related functionality (peeking/previewing rooms, etc) for unregistered
|
||||
users. Set to `true` to disable this functionality.
|
||||
17. `user_notice`: Optional notice to show to the user, e.g. for sunsetting a deployment and pushing users to move in their own time.
|
||||
Takes a configuration object as below:
|
||||
1. `title`: Required. Title to show at the top of the notice.
|
||||
2. `description`: Required. The description to use for the notice.
|
||||
3. `show_once`: Optional. If true then the notice will only be shown once per device.
|
||||
18. `help_url`: The URL to point users to for help with the app, defaults to `https://element.io/help`.
|
||||
19. `help_encryption_url`: The URL to point users to for help with encryption, defaults to `https://element.io/help#encryption`.
|
||||
20. `force_verification`: If true, users must verify new logins (eg. with another device / their security key)
|
||||
|
||||
### `desktop_builds` and `mobile_builds`
|
||||
|
||||
These two options describe the various availability for the application. When the app needs to promote an alternative download,
|
||||
such as trying to get the user to use an Android app or the desktop app for encrypted search, the config options will be looked
|
||||
at to see if the link should be to somewhere else.
|
||||
|
||||
Starting with `desktop_builds`, the following subproperties are available:
|
||||
|
||||
1. `available`: Required. When `true`, the desktop app can be downloaded from somewhere.
|
||||
2. `logo`: Required. A URL to a logo (SVG), intended to be shown at 24x24 pixels.
|
||||
3. `url`: Required. The download URL for the app. This is used as a hyperlink.
|
||||
4. `url_macos`: Optional. Direct link to download macOS desktop app.
|
||||
5. `url_win32`: Optional. Direct link to download Windows 32-bit desktop app.
|
||||
6. `url_win64`: Optional. Direct link to download Windows 64-bit desktop app.
|
||||
7. `url_linux`: Optional. Direct link to download Linux desktop app.
|
||||
|
||||
When `desktop_builds` is not specified at all, the app will assume desktop downloads are available from https://element.io
|
||||
|
||||
For `mobile_builds`, the following subproperties are available:
|
||||
|
||||
1. `ios`: The URL for where to download the iOS app, such as an App Store link. When explicitly `null`, the app will assume the
|
||||
iOS app cannot be downloaded. When not provided, the default Element app will be assumed available.
|
||||
2. `android`: The same as `ios`, except for Android instead.
|
||||
3. `fdroid`: The same as `android`, except for FDroid instead.
|
||||
|
||||
Together, these two options might look like the following in your config:
|
||||
|
||||
```json
|
||||
{
|
||||
"desktop_builds": {
|
||||
"available": true,
|
||||
"logo": "https://example.org/assets/logo-small.svg",
|
||||
"url": "https://example.org/not_element/download"
|
||||
},
|
||||
"mobile_builds": {
|
||||
"ios": null,
|
||||
"android": "https://example.org/not_element/android",
|
||||
"fdroid": "https://example.org/not_element/fdroid"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### `branding` and `embedded_pages`
|
||||
|
||||
These two options point at various URLs for changing different internal pages (like the welcome page) and logos within the
|
||||
application.
|
||||
|
||||
Starting with `branding`, the following subproperties are available:
|
||||
|
||||
1. `welcome_background_url`: When a string, the URL for the full-page image background of the login, registration, and welcome
|
||||
pages. This property can additionally be an array to have the app choose an image at random from the selections.
|
||||
2. `auth_header_logo_url`: A URL to the logo used on the login, registration, etc pages.
|
||||
3. `auth_footer_links`: A list of links to add to the footer during login, registration, etc. Each entry must have a `text` and
|
||||
`url` property.
|
||||
|
||||
`embedded_pages` can be configured as such:
|
||||
|
||||
1. `welcome_url`: A URL to an HTML page to show as a welcome page (landing on `#/welcome`). When not specified, the default
|
||||
`welcome.html` that ships with Element will be used instead.
|
||||
2. `home_url`: A URL to an HTML page to show within the app as the "home" page. When the app doesn't have a room/screen to
|
||||
show the user, it will use the home page instead. The home page is additionally accessible from the user menu. By default,
|
||||
no home page is set and therefore a hardcoded landing screen is used. More documentation and examples are [here](./custom-home.md).
|
||||
3. `login_for_welcome`: When `true` (default `false`), the app will use the login form as a welcome page instead of the welcome
|
||||
page itself. This disables use of `welcome_url` and all welcome page functionality.
|
||||
|
||||
Together, the options might look like this in your config:
|
||||
|
||||
```json
|
||||
{
|
||||
"branding": {
|
||||
"welcome_background_url": "https://example.org/assets/background.jpg",
|
||||
"auth_header_logo_url": "https://example.org/assets/logo.svg",
|
||||
"auth_footer_links": [
|
||||
{ "text": "FAQ", "url": "https://example.org/faq" },
|
||||
{ "text": "Donate", "url": "https://example.org/donate" }
|
||||
]
|
||||
},
|
||||
"embedded_pages": {
|
||||
"welcome_url": "https://example.org/assets/welcome.html",
|
||||
"home_url": "https://example.org/assets/home.html"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Note that `index.html` also has an og:image meta tag that is set to an image hosted on element.io. This is the image used if
|
||||
links to your copy of Element appear in some websites like Facebook, and indeed Element itself. This has to be static in the HTML
|
||||
and an absolute URL (and HTTP rather than HTTPS), so it's not possible for this to be an option in config.json. If you'd like to
|
||||
change it, you can build Element, but run `RIOT_OG_IMAGE_URL="http://example.com/logo.png" yarn build`. Alternatively, you can edit
|
||||
the `og:image` meta tag in `index.html` directly each time you download a new version of Element.
|
||||
|
||||
## SSO setup
|
||||
|
||||
When Element is deployed alongside a homeserver with SSO-only login, some options to ease the user experience might want to be set:
|
||||
|
||||
1. `logout_redirect_url`: Optional URL to redirect the user to after they have logged out. Some SSO systems support a page that the
|
||||
user can be sent to in order to log them out of that system too, making logout symmetric between Element and the SSO system.
|
||||
2. `sso_redirect_options`: Options to define how to handle unauthenticated users. If the object contains `"immediate": true`, then
|
||||
all unauthenticated users will be automatically redirected to the SSO system to start their login. If instead you'd only like to
|
||||
have users which land on the welcome page to be redirected, use `"on_welcome_page": true`. Additionally, there is an option to
|
||||
redirect anyone landing on the login page, by using `"on_login_page": true`. As an example:
|
||||
```json
|
||||
{
|
||||
"sso_redirect_options": {
|
||||
"immediate": false,
|
||||
"on_welcome_page": true,
|
||||
"on_login_page": true
|
||||
}
|
||||
}
|
||||
```
|
||||
It is most common to use the `immediate` flag instead of `on_welcome_page`.
|
||||
|
||||
## Native OIDC
|
||||
|
||||
Native OIDC support is currently in labs and is subject to change.
|
||||
|
||||
Static OIDC Client IDs are preferred and can be specified under `oidc_static_clients` as a mapping from `issuer` to configuration object containing `client_id`.
|
||||
Issuer must have a trailing forward slash. As an example:
|
||||
|
||||
```json
|
||||
{
|
||||
"oidc_static_clients": {
|
||||
"https://auth.example.com/": {
|
||||
"client_id": "example-client-id"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
If a matching static client is not found, the app will attempt to dynamically register a client using metadata specified under `oidc_metadata`.
|
||||
The app has sane defaults for the metadata properties below but on stricter policy identity providers they may not pass muster, e.g. `contacts` may be required.
|
||||
The following subproperties are available:
|
||||
|
||||
1. `client_uri`: This is the base URI for the OIDC client registration, typically `logo_uri`, `tos_uri`, and `policy_uri` must be either on the same domain or a subdomain of this URI.
|
||||
2. `logo_uri`: Optional URI for the client logo.
|
||||
3. `tos_uri`: Optional URI for the client's terms of service.
|
||||
4. `policy_uri`: Optional URI for the client's privacy policy.
|
||||
5. `contacts`: Optional list of contact emails for the client.
|
||||
|
||||
As an example:
|
||||
|
||||
```json
|
||||
{
|
||||
"oidc_metadata": {
|
||||
"client_uri": "https://example.com",
|
||||
"logo_uri": "https://example.com/logo.png",
|
||||
"tos_uri": "https://example.com/tos",
|
||||
"policy_uri": "https://example.com/policy",
|
||||
"contacts": ["support@example.com"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## VoIP / Jitsi calls
|
||||
|
||||
Currently, Element uses Jitsi to offer conference calls in rooms, with an experimental Element Call implementation in the works.
|
||||
A set of defaults are applied, pointing at our Jitsi and Element Call instances, to ensure conference calling works, however you
|
||||
can point Element at your own if you prefer.
|
||||
|
||||
More information about the Jitsi setup can be found [here](./jitsi.md).
|
||||
|
||||
The VoIP and Jitsi options are:
|
||||
|
||||
1. `jitsi`: Optional configuration for how to start Jitsi conferences. Currently can only contain a single `preferred_domain`
|
||||
value which points at the domain of the Jitsi instance. Defaults to `meet.element.io`. This is _not_ used if the Jitsi widget
|
||||
was created by an integration manager, or if the homeserver provides Jitsi information in `/.well-known/matrix/client`. For
|
||||
example:
|
||||
```json
|
||||
{
|
||||
"jitsi": {
|
||||
"preferred_domain": "meet.jit.si"
|
||||
}
|
||||
}
|
||||
```
|
||||
2. `jitsi_widget`: Optional configuration for the built-in Jitsi widget. Currently can only contain a single `skip_built_in_welcome_screen`
|
||||
value, denoting whether the "Join Conference" button should be shown. When `true` (default `false`), Jitsi calls will skip to
|
||||
the call instead of having a screen with a single button on it. This is most useful if the Jitsi instance being used already
|
||||
has a landing page for users to test audio and video before joining the call, otherwise users will automatically join the call.
|
||||
For example:
|
||||
```json
|
||||
{
|
||||
"jitsi_widget": {
|
||||
"skip_built_in_welcome_screen": true
|
||||
}
|
||||
}
|
||||
```
|
||||
3. `voip`: Optional configuration for various VoIP features. Currently can only contain a single `obey_asserted_identity` value to
|
||||
send MSC3086-style asserted identity messages during VoIP calls in the room corresponding to the asserted identity. This _must_
|
||||
only be set in trusted environments. The option defaults to `false`. For example:
|
||||
```json
|
||||
{
|
||||
"voip": {
|
||||
"obey_asserted_identity": false
|
||||
}
|
||||
}
|
||||
```
|
||||
4. `widget_build_url`: Optional URL to have Element make a request to when a user presses the voice/video call buttons in the app,
|
||||
if a call would normally be started by the action. The URL will be called with a `roomId` query parameter to identify the room
|
||||
being called in. The URL must respond with a JSON object similar to the following:
|
||||
```json
|
||||
{
|
||||
"widget_id": "$arbitrary_string",
|
||||
"widget": {
|
||||
"creatorUserId": "@user:example.org",
|
||||
"id": "$the_same_widget_id",
|
||||
"type": "m.custom",
|
||||
"waitForIframeLoad": true,
|
||||
"name": "My Widget Name Here",
|
||||
"avatar_url": "mxc://example.org/abc123",
|
||||
"url": "https://example.org/widget.html",
|
||||
"data": {
|
||||
"title": "Subtitle goes here"
|
||||
}
|
||||
},
|
||||
"layout": {
|
||||
"container": "top",
|
||||
"index": 0,
|
||||
"width": 65,
|
||||
"height": 50
|
||||
}
|
||||
}
|
||||
```
|
||||
The `widget` is the `content` of a normal widget state event. The `layout` is the layout specifier for the widget being created,
|
||||
as defined by the `io.element.widgets.layout` state event. By default this applies to all rooms, but the behaviour can be skipped for
|
||||
2-person rooms, causing Element to fall back to 1:1 VoIP, by setting the option `widget_build_url_ignore_dm` to `true`.
|
||||
5. `audio_stream_url`: Optional URL to pass to Jitsi to enable live streaming. This option is considered experimental and may be removed
|
||||
at any time without notice.
|
||||
6. `element_call`: Optional configuration for native group calls using Element Call, with the following subkeys:
|
||||
- `url`: The URL of the Element Call instance to use for native group calls. This option is considered experimental
|
||||
and may be removed at any time without notice. Defaults to `https://call.element.io`.
|
||||
- `use_exclusively`: A boolean specifying whether Element Call should be used exclusively as the only VoIP stack in
|
||||
the app, removing the ability to start legacy 1:1 calls or Jitsi calls. Defaults to `false`.
|
||||
- `participant_limit`: The maximum number of users who can join a call; if
|
||||
this number is exceeded, the user will not be able to join a given call.
|
||||
- `brand`: Optional name for the app. Defaults to `Element Call`. This is
|
||||
used throughout the application in various strings/locations.
|
||||
- `guest_spa_url`: Optional URL for an Element Call single-page app (SPA),
|
||||
for guest links. If this is set, Element Web will expose a "join" link
|
||||
for public video rooms, which can then be shared to non-matrix users.
|
||||
The target Element Call SPA is typically set up to use a homeserver that
|
||||
allows users to register without email ("passwordless guest users") and to
|
||||
federate.
|
||||
|
||||
## Bug reporting
|
||||
|
||||
If you run your own rageshake server to collect bug reports, the following options may be of interest:
|
||||
|
||||
1. `bug_report_endpoint_url`: URL for where to submit rageshake logs to. Rageshakes include feedback submissions and bug reports. When
|
||||
not present in the config, the app will disable all rageshake functionality. Set to `https://element.io/bugreports/submit` to submit
|
||||
rageshakes to us, or use your own rageshake server.
|
||||
2. `uisi_autorageshake_app`: If a user has enabled the "automatically send debug logs on decryption errors" flag, this option will be sent
|
||||
alongside the rageshake so the rageshake server can filter them by app name. By default, this will be `element-auto-uisi`
|
||||
(in contrast to other rageshakes submitted by the app, which use `element-web`).
|
||||
3. `existing_issues_url`: URL for where to find existing issues.
|
||||
4. `new_issue_url`: URL for where to submit new issues.
|
||||
|
||||
If you would like to use [Sentry](https://sentry.io/) for rageshake data, add a `sentry` object to your config with the following values:
|
||||
|
||||
1. `dsn`: The Sentry [DSN](https://docs.sentry.io/product/sentry-basics/dsn-explainer/).
|
||||
2. `environment`: Optional [environment](https://docs.sentry.io/product/sentry-basics/environments/) to pass to Sentry.
|
||||
|
||||
For example:
|
||||
|
||||
```json
|
||||
{
|
||||
"sentry": {
|
||||
"dsn": "dsn-goes-here",
|
||||
"environment": "production"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Integration managers
|
||||
|
||||
Integration managers are embedded applications within Element to help the user configure bots, bridges, and widgets. An integration manager
|
||||
is a separate piece of software not typically available with your homeserver. To disable integrations, set the options defined here to `null`.
|
||||
|
||||
1. `integrations_ui_url`: The UI URL for the integration manager.
|
||||
2. `integrations_rest_url`: The REST interface URL for the integration manager.
|
||||
3. `integrations_widgets_urls`: A list of URLs the integration manager uses to host widgets.
|
||||
|
||||
If you would like to use Scalar, the integration manager maintained by Element, the following options would apply:
|
||||
|
||||
```json
|
||||
{
|
||||
"integrations_ui_url": "https://scalar.vector.im/",
|
||||
"integrations_rest_url": "https://scalar.vector.im/api",
|
||||
"integrations_widgets_urls": [
|
||||
"https://scalar.vector.im/_matrix/integrations/v1",
|
||||
"https://scalar.vector.im/api",
|
||||
"https://scalar-staging.vector.im/_matrix/integrations/v1",
|
||||
"https://scalar-staging.vector.im/api",
|
||||
"https://scalar-staging.riot.im/scalar/api"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
For widgets in general (from an integration manager or not) there is also:
|
||||
|
||||
- `default_widget_container_height`
|
||||
|
||||
This controls the height that the top widget panel initially appears as and is the height in pixels, default 280.
|
||||
|
||||
## Administrative options
|
||||
|
||||
If you would like to include a custom message when someone is reporting an event, set the following Markdown-capable field:
|
||||
|
||||
```json
|
||||
{
|
||||
"report_event": {
|
||||
"admin_message_md": "Please be sure to review our [terms of service](https://example.org/terms) before reporting a message."
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
To add additional "terms and conditions" links throughout the app, use the following template:
|
||||
|
||||
```json
|
||||
{
|
||||
"terms_and_conditions_links": [{ "text": "Code of conduct", "url": "https://example.org/code-of-conduct" }]
|
||||
}
|
||||
```
|
||||
|
||||
## Analytics
|
||||
|
||||
To configure [Posthog](https://posthog.com/), add the following under `posthog` in your config:
|
||||
|
||||
1. `api_host`: The hostname of the posthog server.
|
||||
2. `project_api_key`: The API key from posthog.
|
||||
|
||||
When these configuration options are not present,
|
||||
analytics are deemed impossible and the user won't be asked to opt in to the system.
|
||||
|
||||
There are additional root-level options which can be specified:
|
||||
|
||||
1. `analytics_owner`: the company name used in dialogs talking about analytics - this defaults to `brand`,
|
||||
and is useful when the provider of analytics is different from the provider of the Element instance.
|
||||
2. `privacy_policy_url`: URL to the privacy policy including the analytics collection policy.
|
||||
|
||||
## Miscellaneous
|
||||
|
||||
Element supports other options which don't quite fit into other sections of this document.
|
||||
|
||||
To configure whether presence UI is shown for a given homeserver, set `enable_presence_by_hs_url`. It is recommended to
|
||||
set this value to the following at a minimum:
|
||||
|
||||
```json
|
||||
{
|
||||
"enable_presence_by_hs_url": {
|
||||
"https://matrix.org": false,
|
||||
"https://matrix-client.matrix.org": false
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Identity servers
|
||||
|
||||
The identity server is used for inviting other users to a room via third party
|
||||
identifiers like emails and phone numbers. It is not used to store your password
|
||||
@@ -161,8 +524,8 @@ Element will check multiple sources when looking for an identity server to use i
|
||||
the following order of preference:
|
||||
|
||||
1. The identity server set in the user's account data
|
||||
* For a new user, no value is present in their account data. It is only set
|
||||
if the user visits Settings and manually changes their identity server.
|
||||
- For a new user, no value is present in their account data. It is only set
|
||||
if the user visits Settings and manually changes their identity server.
|
||||
2. The identity server provided by the `.well-known` lookup that occurred at
|
||||
login
|
||||
3. The identity server provided by the Riot config file
|
||||
@@ -175,48 +538,58 @@ Currently, the only two public identity servers are https://vector.im and
|
||||
https://matrix.org, however in the future identity servers will be
|
||||
decentralised.
|
||||
|
||||
Desktop app configuration
|
||||
=========================
|
||||
## Desktop app configuration
|
||||
|
||||
See https://github.com/vector-im/element-desktop#user-specified-configjson
|
||||
See https://github.com/element-hq/element-desktop#user-specified-configjson
|
||||
|
||||
UI Features
|
||||
===========
|
||||
## UI Features
|
||||
|
||||
Parts of the UI can be disabled using UI features. These are settings which appear
|
||||
under `settingDefaults` and can only be `true` (default) or `false`. When `false`,
|
||||
under `setting_defaults` and can only be `true` (default) or `false`. When `false`,
|
||||
parts of the UI relating to that feature will be disabled regardless of the user's
|
||||
preferences.
|
||||
|
||||
Currently, the following UI feature flags are supported:
|
||||
|
||||
* `UIFeature.urlPreviews` - Whether URL previews are enabled across the entire application.
|
||||
* `UIFeature.feedback` - Whether prompts to supply feedback are shown.
|
||||
* `UIFeature.voip` - Whether or not VoIP is shown readily to the user. When disabled,
|
||||
Jitsi widgets will still work though they cannot easily be added.
|
||||
* `UIFeature.widgets` - Whether or not widgets will be shown.
|
||||
* `UIFeature.flair` - Whether or not community flair is shown in rooms.
|
||||
* `UIFeature.communities` - Whether or not to show any UI related to communities. Implicitly
|
||||
disables `UIFeature.flair` when disabled.
|
||||
* `UIFeature.advancedSettings` - Whether or not sections titled "advanced" in room and
|
||||
user settings are shown to the user.
|
||||
* `UIFeature.shareQrCode` - Whether or not the QR code on the share room/event dialog
|
||||
is shown.
|
||||
* `UIFeature.shareSocial` - Whether or not the social icons on the share room/event dialog
|
||||
are shown.
|
||||
* `UIFeature.identityServer` - Whether or not functionality requiring an identity server
|
||||
is shown. When disabled, the user will not be able to interact with the identity
|
||||
server (sharing email addresses, 3PID invites, etc).
|
||||
* `UIFeature.thirdPartyId` - Whether or not UI relating to third party identifiers (3PIDs)
|
||||
is shown. Typically this is considered "contact information" on the homeserver, and is
|
||||
not directly related to the identity server.
|
||||
* `UIFeature.registration` - Whether or not the registration page is accessible. Typically
|
||||
useful if accounts are managed externally.
|
||||
* `UIFeature.passwordReset` - Whether or not the password reset page is accessible. Typically
|
||||
useful if accounts are managed externally.
|
||||
* `UIFeature.deactivate` - Whether or not the deactivate account button is accessible. Typically
|
||||
useful if accounts are managed externally.
|
||||
* `UIFeature.advancedEncryption` - Whether or not advanced encryption options are shown to the
|
||||
user.
|
||||
* `UIFeature.roomHistorySettings` - Whether or not the room history settings are shown to the user.
|
||||
This should only be used if the room history visibility options are managed by the server.
|
||||
- `UIFeature.urlPreviews` - Whether URL previews are enabled across the entire application.
|
||||
- `UIFeature.feedback` - Whether prompts to supply feedback are shown.
|
||||
- `UIFeature.voip` - Whether or not VoIP is shown readily to the user. When disabled,
|
||||
Jitsi widgets will still work though they cannot easily be added.
|
||||
- `UIFeature.widgets` - Whether or not widgets will be shown.
|
||||
- `UIFeature.advancedSettings` - Whether or not sections titled "advanced" in room and
|
||||
user settings are shown to the user.
|
||||
- `UIFeature.shareQrCode` - Whether or not the QR code on the share room/event dialog
|
||||
is shown.
|
||||
- `UIFeature.shareSocial` - Whether or not the social icons on the share room/event dialog
|
||||
are shown.
|
||||
- `UIFeature.identityServer` - Whether or not functionality requiring an identity server
|
||||
is shown. When disabled, the user will not be able to interact with the identity
|
||||
server (sharing email addresses, 3PID invites, etc).
|
||||
- `UIFeature.thirdPartyId` - Whether or not UI relating to third party identifiers (3PIDs)
|
||||
is shown. Typically this is considered "contact information" on the homeserver, and is
|
||||
not directly related to the identity server.
|
||||
- `UIFeature.registration` - Whether or not the registration page is accessible. Typically
|
||||
useful if accounts are managed externally.
|
||||
- `UIFeature.passwordReset` - Whether or not the password reset page is accessible. Typically
|
||||
useful if accounts are managed externally.
|
||||
- `UIFeature.deactivate` - Whether or not the deactivate account button is accessible. Typically
|
||||
useful if accounts are managed externally.
|
||||
- `UIFeature.advancedEncryption` - Whether or not advanced encryption options are shown to the
|
||||
user.
|
||||
- `UIFeature.roomHistorySettings` - Whether or not the room history settings are shown to the user.
|
||||
This should only be used if the room history visibility options are managed by the server.
|
||||
- `UIFeature.TimelineEnableRelativeDates` - Display relative date separators (eg: 'Today', 'Yesterday') in the
|
||||
timeline for recent messages. When false day dates will be used.
|
||||
- `UIFeature.BulkUnverifiedSessionsReminder` - Display popup reminders to verify or remove unverified sessions. Defaults
|
||||
to true.
|
||||
- `UIFeature.locationSharing` - Whether or not location sharing menus will be shown.
|
||||
|
||||
## Undocumented / developer options
|
||||
|
||||
The following are undocumented or intended for developer use only.
|
||||
|
||||
1. `fallback_hs_url`
|
||||
2. `sync_timeline_limit`
|
||||
3. `dangerously_allow_unsafe_and_insecure_passwords`
|
||||
4. `latex_maths_delims`: An optional setting to override the default delimiters used for maths parsing. See https://github.com/matrix-org/matrix-react-sdk/pull/5939 for details. Only used when `feature_latex_maths` is enabled.
|
||||
5. `voice_broadcast.chunk_length`: Target chunk length in seconds for the Voice Broadcast feature currently under development.
|
||||
|
||||
63
docs/custom-home.md
Normal file
63
docs/custom-home.md
Normal file
@@ -0,0 +1,63 @@
|
||||
# Custom Home Page
|
||||
|
||||
The home page is shown whenever the user is logged in, but no room is selected.
|
||||
A custom `home.html` replacing the default home page can be configured either in `.well-known/matrix/client` or `config.json`.
|
||||
Such a custom home page can be used to communicate helpful information and important rules to the users.
|
||||
|
||||
## Configuration
|
||||
|
||||
To provide a custom home page for all element-web/desktop users of a homeserver, include the following in `.well-known/matrix/client`:
|
||||
|
||||
```
|
||||
{
|
||||
"io.element.embedded_pages": {
|
||||
"home_url": "https://example.org/home.html"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The home page can be overridden in `config.json` to provide all users of an element-web installation with the same experience:
|
||||
|
||||
```
|
||||
{
|
||||
"embeddedPages": {
|
||||
"homeUrl": "https://example.org/home.html"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## `home.html` Example
|
||||
|
||||
The following is a simple example for a custom `home.html`:
|
||||
|
||||
```
|
||||
<style type="text/css">
|
||||
.tos {
|
||||
width: auto;
|
||||
color: black;
|
||||
background : #ffcccb;
|
||||
font-weight: bold;
|
||||
}
|
||||
</style>
|
||||
|
||||
<h1>The example.org Matrix Server</h1>
|
||||
|
||||
<div class="tos">
|
||||
<p>Behave appropriately.</p>
|
||||
</div>
|
||||
|
||||
<h2>Start Chatting</h2>
|
||||
<ul>
|
||||
<li><a href="#/dm">Send a Direct Message</a></li>
|
||||
<li><a href="#/directory">Explore Public Rooms</a></li>
|
||||
<li><a href="#/new">Create a Group Chat</a></li>
|
||||
</ul>
|
||||
```
|
||||
|
||||
When choosing colors, be aware that the home page may be displayed in either light or dark mode.
|
||||
|
||||
It may be needed to set CORS headers for the `home.html` to enable element-desktop to fetch it, with e.g., the following nginx config:
|
||||
|
||||
```
|
||||
add_header Access-Control-Allow-Origin *;
|
||||
```
|
||||
@@ -1,10 +1,18 @@
|
||||
# Customisations
|
||||
|
||||
### 🦖 DEPRECATED
|
||||
|
||||
Customisations have been deprecated in favour of the [Module API](https://github.com/element-hq/element-web/blob/develop/docs/modules.md).
|
||||
If you have use cases from customisations which are not yet available via the Module API please open an issue.
|
||||
Customisations will be removed from the codebase in a future release.
|
||||
|
||||
---
|
||||
|
||||
Element Web and the React SDK support "customisation points" that can be used to
|
||||
easily add custom logic specific to a particular deployment of Element Web.
|
||||
|
||||
An example of this is the [security customisations
|
||||
module](https://github.com/matrix-org/matrix-react-sdk/blob/develop/src/customisations/Security.ts).
|
||||
module](https://github.com/element-hq/element-web/blob/develop/src/customisations/Security.ts).
|
||||
This module in the React SDK only defines some empty functions and their types:
|
||||
it does not do anything by default.
|
||||
|
||||
@@ -16,19 +24,56 @@ the React SDK, you can still override it from the Element Web layer:
|
||||
`element-web/src/customisations/YourNameSecurity.ts`
|
||||
2. Edit customisations points and make sure export the ones you actually want to
|
||||
activate
|
||||
3. Tweak the Element build process to use the customised module instead of the
|
||||
default by adding this to the `additionalPlugins` array in `webpack.config.js`:
|
||||
3. Create/add an entry to `customisations.json` next to the webpack config:
|
||||
|
||||
```js
|
||||
new webpack.NormalModuleReplacementPlugin(
|
||||
/src[\/\\]customisations[\/\\]Security\.ts/,
|
||||
path.resolve(__dirname, 'src/customisations/YourNameSecurity.ts'),
|
||||
),
|
||||
```json
|
||||
{
|
||||
"src/customisations/Security.ts": "src/customisations/YourNameSecurity.ts"
|
||||
}
|
||||
```
|
||||
|
||||
If we add more customisation modules in the future, we'll likely improve these
|
||||
steps to remove the need for build changes like the above.
|
||||
|
||||
By isolating customisations to their own module, this approach should remove the
|
||||
chance of merge conflicts when updating your fork, and thus simplify ongoing
|
||||
maintenance.
|
||||
|
||||
**Note**: The project deliberately does not exclude `customisations.json` from Git.
|
||||
This is to ensure that in shared projects it's possible to have a common config. By
|
||||
default, Element Web does _not_ ship with this file to prevent conflicts.
|
||||
|
||||
### Custom components
|
||||
|
||||
Maintainers can use the above system to override components if they wish. Maintenance and API surface compatibility are
|
||||
left as a responsibility for the project - the layering in Element Web (including the react-sdk) do not make guarantees
|
||||
that properties/state machines won't change.
|
||||
|
||||
### Component visibility customisation
|
||||
|
||||
UI for some actions can be hidden via the ComponentVisibility customisation:
|
||||
|
||||
- inviting users to rooms and spaces,
|
||||
- creating rooms,
|
||||
- creating spaces,
|
||||
|
||||
To customise visibility create a customisation module from [ComponentVisibility](https://github.com/element-hq/element-web/blob/master/src/customisations/ComponentVisibility.ts) following the instructions above.
|
||||
|
||||
`shouldShowComponent` determines whether the active MatrixClient user should be able to use
|
||||
the given UI component. When `shouldShowComponent` returns falsy all UI components for that feature will be hidden.
|
||||
If shown, the user might still not be able to use the
|
||||
component depending on their contextual permissions. For example, invite options
|
||||
might be shown to the user, but they won't have permission to invite users to
|
||||
the current room: the button will appear disabled.
|
||||
|
||||
For example, to only allow users who meet a certain condition to create spaces:
|
||||
|
||||
```typescript
|
||||
function shouldShowComponent(component: UIComponent): boolean {
|
||||
if (component === UIComponent.CreateSpaces) {
|
||||
// customConditionCheck() is a function of your own creation
|
||||
const userMeetsCondition = customConditionCheck(MatrixClientPeg.get().getUserId());
|
||||
return userMeetsCondition;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
```
|
||||
|
||||
In this example, all UI related to creating a space will be hidden unless the users meets the custom condition.
|
||||
|
||||
40
docs/e2ee.md
40
docs/e2ee.md
@@ -10,12 +10,34 @@ Set the following on your homeserver's
|
||||
|
||||
```json
|
||||
{
|
||||
"io.element.e2ee": {
|
||||
"default": false
|
||||
}
|
||||
"io.element.e2ee": {
|
||||
"default": false
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Disabling encryption
|
||||
|
||||
Set the following on your homeserver's
|
||||
`/.well-known/matrix/client` config:
|
||||
|
||||
```json
|
||||
{
|
||||
"io.element.e2ee": {
|
||||
"force_disable": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
When `force_disable` is true:
|
||||
|
||||
- all rooms will be created with encryption disabled, and it will not be possible to enable
|
||||
encryption from room settings.
|
||||
- any `io.element.e2ee.default` value will be disregarded.
|
||||
|
||||
Note: If the server is configured to forcibly enable encryption for some or all rooms,
|
||||
this behaviour will be overridden.
|
||||
|
||||
# Secure backup
|
||||
|
||||
By default, Element strongly encourages (but does not require) users to set up
|
||||
@@ -29,9 +51,9 @@ following on your homeserver's `/.well-known/matrix/client` config:
|
||||
|
||||
```json
|
||||
{
|
||||
"io.element.e2ee": {
|
||||
"secure_backup_required": true
|
||||
}
|
||||
"io.element.e2ee": {
|
||||
"secure_backup_required": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -44,9 +66,9 @@ only offer one of these, you can signal this via the
|
||||
|
||||
```json
|
||||
{
|
||||
"io.element.e2ee": {
|
||||
"secure_backup_setup_methods": ["passphrase"]
|
||||
}
|
||||
"io.element.e2ee": {
|
||||
"secure_backup_setup_methods": ["passphrase"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -5,10 +5,10 @@ flexibility and control over when and where those features are enabled.
|
||||
|
||||
For example, flags make the following things possible:
|
||||
|
||||
* Extended testing of a feature via labs on develop
|
||||
* Enabling features when ready instead of the first moment the code is released
|
||||
* Testing a feature with a specific set of users (by enabling only on a specific
|
||||
Element instance)
|
||||
- Extended testing of a feature via labs on develop
|
||||
- Enabling features when ready instead of the first moment the code is released
|
||||
- Testing a feature with a specific set of users (by enabling only on a specific
|
||||
Element instance)
|
||||
|
||||
The size of the feature controlled by a feature flag may vary widely: it could
|
||||
be a large project like reactions or a smaller change to an existing algorithm.
|
||||
@@ -35,8 +35,9 @@ clients commit to doing the associated clean up work once a feature stabilises.
|
||||
When starting work on a feature, we should create a matching feature flag:
|
||||
|
||||
1. Add a new
|
||||
[setting](https://github.com/matrix-org/matrix-react-sdk/blob/develop/src/settings/Settings.ts)
|
||||
[setting](https://github.com/element-hq/element-web/blob/develop/src/settings/Settings.tsx)
|
||||
of the form:
|
||||
|
||||
```js
|
||||
"feature_cats": {
|
||||
isFeature: true,
|
||||
@@ -45,11 +46,14 @@ When starting work on a feature, we should create a matching feature flag:
|
||||
default: false,
|
||||
},
|
||||
```
|
||||
|
||||
2. Check whether the feature is enabled as appropriate:
|
||||
|
||||
```js
|
||||
SettingsStore.getValue("feature_cats")
|
||||
SettingsStore.getValue("feature_cats");
|
||||
```
|
||||
3. Document the feature in the [labs documentation](https://github.com/vector-im/element-web/blob/develop/docs/labs.md)
|
||||
|
||||
3. Document the feature in the [labs documentation](https://github.com/element-hq/element-web/blob/develop/docs/labs.md)
|
||||
|
||||
With these steps completed, the feature is disabled by default, but can be
|
||||
enabled on develop and nightly by interested users for testing.
|
||||
@@ -60,9 +64,9 @@ The following lists a few common options.
|
||||
## Enabling by default on develop and nightly
|
||||
|
||||
Set the feature to `true` in the
|
||||
[develop](https://github.com/vector-im/element-web/blob/develop/element.io/develop/config.json)
|
||||
[develop](https://github.com/element-hq/element-web/blob/develop/element.io/develop/config.json)
|
||||
and
|
||||
[nightly](https://github.com/vector-im/element-desktop/blob/develop/element.io/nightly/config.json)
|
||||
[nightly](https://github.com/element-hq/element-desktop/blob/develop/element.io/nightly/config.json)
|
||||
configs:
|
||||
|
||||
```json
|
||||
@@ -74,34 +78,36 @@ configs:
|
||||
## Enabling by default on staging, app, and release
|
||||
|
||||
Set the feature to `true` in the
|
||||
[staging / app](https://github.com/vector-im/element-web/blob/develop/element.io/app/config.json)
|
||||
[staging / app](https://github.com/element-hq/element-web/blob/develop/element.io/app/config.json)
|
||||
and
|
||||
[release](https://github.com/vector-im/element-desktop/blob/develop/element.io/release/config.json)
|
||||
[release](https://github.com/element-hq/element-desktop/blob/develop/element.io/release/config.json)
|
||||
configs.
|
||||
|
||||
**Note:** The above will only enable the feature for https://app.element.io and official Element
|
||||
Desktop builds. It will not be enabled for self-hosted installed, custom desktop builds, etc. To
|
||||
cover these cases, change the setting's `default` in `Settings.ts` to `true`.
|
||||
cover these cases, change the setting's `default` in `Settings.tsx` to `true`.
|
||||
|
||||
## Feature deployed successfully
|
||||
|
||||
Once we're confident that a feature is working well, we should remove or convert the flag.
|
||||
|
||||
If the feature is meant to be turned off/on by the user:
|
||||
1. Remove `isFeature` from the [setting](https://github.com/matrix-org/matrix-react-sdk/blob/develop/src/settings/Settings.ts)
|
||||
|
||||
1. Remove `isFeature` from the [setting](https://github.com/element-hq/element-web/blob/develop/src/settings/Settings.ts)
|
||||
2. Change the `default` to `true` (if desired).
|
||||
3. Remove the feature from the [labs documentation](https://github.com/vector-im/element-web/blob/develop/docs/labs.md)
|
||||
3. Remove the feature from the [labs documentation](https://github.com/element-hq/element-web/blob/develop/docs/labs.md)
|
||||
4. Celebrate! 🥳
|
||||
|
||||
If the feature is meant to be forced on (non-configurable):
|
||||
1. Remove the [setting](https://github.com/matrix-org/matrix-react-sdk/blob/develop/src/settings/Settings.ts)
|
||||
|
||||
1. Remove the [setting](https://github.com/element-hq/element-web/blob/develop/src/settings/Settings.ts)
|
||||
2. Remove all `getValue` lines that test for the feature.
|
||||
3. Remove the feature from the [labs documentation](https://github.com/vector-im/element-web/blob/develop/docs/labs.md)
|
||||
3. Remove the feature from the [labs documentation](https://github.com/element-hq/element-web/blob/develop/docs/labs.md)
|
||||
4. If applicable, remove the feature state from
|
||||
[develop](https://github.com/vector-im/element-web/blob/develop/element.io/develop/config.json),
|
||||
[nightly](https://github.com/vector-im/element-desktop/blob/develop/element.io/nightly/config.json),
|
||||
[staging / app](https://github.com/vector-im/element-web/blob/develop/element.io/app/config.json),
|
||||
[develop](https://github.com/element-hq/element-web/blob/develop/element.io/develop/config.json),
|
||||
[nightly](https://github.com/element-hq/element-desktop/blob/develop/element.io/nightly/config.json),
|
||||
[staging / app](https://github.com/element-hq/element-web/blob/develop/element.io/app/config.json),
|
||||
and
|
||||
[release](https://github.com/vector-im/element-desktop/blob/develop/element.io/release/config.json)
|
||||
[release](https://github.com/element-hq/element-desktop/blob/develop/element.io/release/config.json)
|
||||
configs
|
||||
5. Celebrate! 🥳
|
||||
|
||||
6
docs/features/README.md
Normal file
6
docs/features/README.md
Normal file
@@ -0,0 +1,6 @@
|
||||
# Feature documention
|
||||
|
||||
The idea of this folder is to document the features we support in different parts of the app.
|
||||
In case anyone needs to work on a given part, and isn't aware of all the features in the area,
|
||||
they will hopefully get an idea for all the supported functionality to know what to take into account
|
||||
when making changes.
|
||||
38
docs/features/composer.md
Normal file
38
docs/features/composer.md
Normal file
@@ -0,0 +1,38 @@
|
||||
# Composer Features
|
||||
|
||||
## Auto Complete
|
||||
|
||||
- Hitting tab tries to auto-complete the word before the caret as a room member
|
||||
- If no matching name is found, a visual bell is shown
|
||||
- @ + a letter opens auto complete for members starting with the given letter
|
||||
- When inserting a user pill at the start in the composer, a colon and space is appended to the pill
|
||||
- When inserting a user pill anywhere else in composer, only a space is appended to the pill
|
||||
- # + a letter opens auto complete for rooms starting with the given letter
|
||||
- : open auto complete for emoji
|
||||
- Pressing arrow-up/arrow-down while the autocomplete is open navigates between auto complete options
|
||||
- Pressing tab while the autocomplete is open goes to the next autocomplete option,
|
||||
wrapping around at the end after reverting to the typed text first.
|
||||
|
||||
## Formatting
|
||||
|
||||
- When selecting text, a formatting bar appears above the selection.
|
||||
- The formatting bar allows to format the selected test as:
|
||||
bold, italic, strikethrough, a block quote, and a code block (inline if no linebreak is selected).
|
||||
- Formatting is applied as markdown syntax.
|
||||
- Hitting ctrl/cmd+B also marks the selected text as bold
|
||||
- Hitting ctrl/cmd+I also marks the selected text as italic
|
||||
- Hitting ctrl/cmd+> also marks the selected text as a blockquote
|
||||
|
||||
## Misc
|
||||
|
||||
- When hitting the arrow-up button while having the caret at the start in the composer,
|
||||
the last message sent by the syncing user is edited.
|
||||
- Clicking a display name on an event in the timeline inserts a user pill into the composer
|
||||
- Emoticons (like :-), >:-), :-/, ...) are replaced by emojis while typing if the relevant setting is enabled
|
||||
- Typing in the composer sends typing notifications in the room
|
||||
- Pressing ctrl/mod+z and ctrl/mod+y undoes/redoes modifications
|
||||
- Pressing shift+enter inserts a line break
|
||||
- Pressing enter sends the message.
|
||||
- Choosing "Quote" in the context menu of an event inserts a quote of the event body in the composer.
|
||||
- Choosing "Reply" in the context menu of an event shows a preview above the composer to reply to.
|
||||
- Pressing alt+arrow up/arrow down navigates in previously sent messages, putting them in the composer.
|
||||
59
docs/features/keyboardShortcuts.md
Normal file
59
docs/features/keyboardShortcuts.md
Normal file
@@ -0,0 +1,59 @@
|
||||
# Keyboard shortcuts
|
||||
|
||||
## Using the `KeyBindingManager`
|
||||
|
||||
The `KeyBindingManager` (accessible using `getKeyBindingManager()`) is a class
|
||||
with several methods that allow you to get a `KeyBindingAction` based on a
|
||||
`KeyboardEvent | React.KeyboardEvent`.
|
||||
|
||||
The event passed to the `KeyBindingManager` gets compared to the list of
|
||||
shortcuts that are retrieved from the `IKeyBindingsProvider`s. The
|
||||
`IKeyBindingsProvider` is in `KeyBindingDefaults`.
|
||||
|
||||
### Examples
|
||||
|
||||
Let's say we want to close a menu when the correct keys were pressed:
|
||||
|
||||
```ts
|
||||
const onKeyDown = (ev: KeyboardEvent): void => {
|
||||
let handled = true;
|
||||
const action = getKeyBindingManager().getAccessibilityAction(ev);
|
||||
switch (action) {
|
||||
case KeyBindingAction.Escape:
|
||||
closeMenu();
|
||||
break;
|
||||
default:
|
||||
handled = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (handled) {
|
||||
ev.preventDefault();
|
||||
ev.stopPropagation();
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
## Managing keyboard shortcuts
|
||||
|
||||
There are a few things at play when it comes to keyboard shortcuts. The
|
||||
`KeyBindingManager` gets `IKeyBindingsProvider`s one of which is
|
||||
`defaultBindingsProvider` defined in `KeyBindingDefaults`. In
|
||||
`KeyBindingDefaults` a `getBindingsByCategory()` method is used to create
|
||||
`KeyBinding`s based on `KeyboardShortcutSetting`s defined in
|
||||
`KeyboardShortcuts`.
|
||||
|
||||
### Adding keyboard shortcuts
|
||||
|
||||
To add a keyboard shortcut there are two files we have to look at:
|
||||
`KeyboardShortcuts.ts` and `KeyBindingDefaults.ts`. In most cases we only need
|
||||
to edit `KeyboardShortcuts.ts`: add a `KeyBindingAction` and add the
|
||||
`KeyBindingAction` to the `KEYBOARD_SHORTCUTS` object.
|
||||
|
||||
Though, to make matters worse, sometimes we want to add a shortcut that has
|
||||
multiple keybindings associated with. This keyboard shortcut won't be
|
||||
customizable as it would be rather difficult to manage both from the point of
|
||||
the settings and the UI. To do this, we have to add a `KeyBindingAction` and add
|
||||
the UI representation of that keyboard shortcut to the `getUIOnlyShortcuts()`
|
||||
method. Then, we also need to add the keybinding to the correct method in
|
||||
`KeyBindingDefaults`.
|
||||
56
docs/icons.md
Normal file
56
docs/icons.md
Normal file
@@ -0,0 +1,56 @@
|
||||
# Icons
|
||||
|
||||
Icons are loaded using [@svgr/webpack](https://www.npmjs.com/package/@svgr/webpack).
|
||||
This is configured in [element-web](https://github.com/vector-im/element-web/blob/develop/webpack.config.js#L458).
|
||||
|
||||
Each `.svg` exports a `ReactComponent` at the named export `Icon`.
|
||||
Icons have `role="presentation"` and `aria-hidden` automatically applied. These can be overriden by passing props to the icon component.
|
||||
|
||||
SVG file recommendations:
|
||||
|
||||
- Colours should not be defined absolutely. Use `currentColor` instead.
|
||||
- SVG files should be taken from the design compound as they are. Some icons contain special padding.
|
||||
This means that there should be icons for each size, e.g. warning-16px and warning-32px.
|
||||
|
||||
Example usage:
|
||||
|
||||
```
|
||||
import { Icon as FavoriteIcon } from 'res/img/element-icons/favorite.svg';
|
||||
|
||||
const MyComponent = () => {
|
||||
return <>
|
||||
<FavoriteIcon className="mx_Icon mx_Icon_16">
|
||||
</>;
|
||||
}
|
||||
```
|
||||
|
||||
If possible, use the icon classes from [here](../res/css/compound/_Icon.pcss).
|
||||
|
||||
## Custom styling
|
||||
|
||||
Icon components are svg elements and may be custom styled as usual.
|
||||
|
||||
`_MyComponents.pcss`:
|
||||
|
||||
```css
|
||||
.mx_MyComponent-icon {
|
||||
height: 20px;
|
||||
width: 20px;
|
||||
|
||||
* {
|
||||
fill: $accent;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
`MyComponent.tsx`:
|
||||
|
||||
```typescript
|
||||
import { Icon as FavoriteIcon } from 'res/img/element-icons/favorite.svg';
|
||||
|
||||
const MyComponent = () => {
|
||||
return <>
|
||||
<FavoriteIcon className="mx_MyComponent-icon" role="img" aria-hidden="false">
|
||||
</>;
|
||||
}
|
||||
```
|
||||
BIN
docs/img/RoomListStore2.png
Normal file
BIN
docs/img/RoomListStore2.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 74 KiB |
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user