Compare commits
1235 Commits
v7.0.1
...
main-chapr
Author | SHA1 | Date | |
---|---|---|---|
a461444bed | |||
1307f87912 | |||
23cf858a02 | |||
b49146b36f | |||
8d67dce865 | |||
543807aa50 | |||
|
82a8c3f9fc | ||
|
3e680e88d8 | ||
|
005f5374f0 | ||
|
79bb8e76ce | ||
|
61192f91d9 | ||
|
e31d4c7bac | ||
|
c30569dfd3 | ||
|
5e02b9bd5d | ||
|
9114db8764 | ||
|
bc7621c25d | ||
|
ae518aa2c3 | ||
|
e4a4b2819c | ||
|
5310021b67 | ||
|
e18fdd56b1 | ||
|
94963662e7 | ||
|
4f14d50f5d | ||
|
699ab71f21 | ||
|
daeb641530 | ||
|
6e71555ee4 | ||
|
27d61411ab | ||
|
3328e1c94c | ||
|
c63c787a6d | ||
|
0efeead71a | ||
|
5822fade32 | ||
|
621612d126 | ||
|
536350155d | ||
|
841a57fd66 | ||
|
175595098a | ||
|
03655b45b2 | ||
|
fa9ae16ead | ||
|
cb1f929045 | ||
|
9ba339a6d9 | ||
|
bc452596a7 | ||
|
2b732cdb94 | ||
|
1e4937bf41 | ||
|
8b28ffecfe | ||
|
80bf81db6f | ||
|
7fdbcd0e64 | ||
|
975a2c2305 | ||
|
abad4d054b | ||
|
b5b6d1f8b2 | ||
|
64aef7f70d | ||
|
4f0f210e21 | ||
|
c4299e92be | ||
|
0cc03e7e7a | ||
|
f9f246282b | ||
|
3e4a8b23fe | ||
|
cdda140137 | ||
|
0a15b003dc | ||
|
23539ecf47 | ||
|
efa448956e | ||
|
743f336dc5 | ||
|
8a0386fdcc | ||
|
b647f5463f | ||
|
46f2e40f91 | ||
|
8b1b4b6446 | ||
|
9407d00c67 | ||
|
f0d584aed6 | ||
|
2768c2a3ec | ||
|
8fb1716681 | ||
|
507cfa9ef2 | ||
|
5ef7807a68 | ||
|
952d3cf440 | ||
|
c9a95faa35 | ||
|
02185cee5f | ||
|
40290f27e7 | ||
|
bbfcb74eaa | ||
|
a2e618a8f6 | ||
|
ebbb39a9aa | ||
|
2d66a974d0 | ||
|
fa12dae7bc | ||
|
df25e16438 | ||
|
c39d61f62c | ||
|
01ce344d82 | ||
|
bb428fa1d7 | ||
|
5a710e4601 | ||
|
f91f4cb7ab | ||
|
f2ac748e06 | ||
|
27a47c6ee8 | ||
|
0a338feb40 | ||
|
d74daccfbb | ||
|
5c3acc8a4d | ||
|
48e7987f38 | ||
|
4d2a8e9f8d | ||
|
3d0e9a7374 | ||
|
fb054c40be | ||
|
c3c666e568 | ||
|
6b365458f5 | ||
|
885a3d92b5 | ||
|
6df80507f3 | ||
|
16754c15aa | ||
|
70a10efd49 | ||
|
9a63629b40 | ||
|
dcfc0d50f4 | ||
|
fde55bea2c | ||
|
3530ccc35d | ||
|
05c5cd1046 | ||
|
c38c706079 | ||
|
e1e93c2ec9 | ||
|
16b442ac19 | ||
|
0122bd7bab | ||
|
56259fd22e | ||
|
85181053e6 | ||
|
26062df4e5 | ||
|
2fb9fec8f8 | ||
|
d4cb67dc5f | ||
|
ad7b4ae343 | ||
|
57f489f61b | ||
|
6ce8879e9c | ||
|
1ee4cce2fd | ||
|
b69e5b5482 | ||
|
3f6ad0d950 | ||
|
9899351597 | ||
|
0b3bcbfe40 | ||
|
5e3139f563 | ||
|
7b8b32638c | ||
|
8035084e8e | ||
|
19466ddf62 | ||
|
bb7ed5315f | ||
|
6719aeba45 | ||
|
45844447bf | ||
|
82314eb1df | ||
|
d9c86ed575 | ||
|
89d231a5dd | ||
|
72406b4aac | ||
|
e08b58c3d3 | ||
|
387c992381 | ||
|
4e98383e65 | ||
|
dae84028c2 | ||
|
5e5bdc78ec | ||
|
15c10376b0 | ||
|
ccc165facc | ||
|
aa299af3ec | ||
|
b16e3efbd4 | ||
|
5db3e8ca51 | ||
|
0fcdb2a594 | ||
|
5029d93523 | ||
|
bab11b682b | ||
|
9343488864 | ||
|
782c8c97fa | ||
|
d2f7756313 | ||
|
07371b0852 | ||
|
25aa0303c6 | ||
|
6186f05a3e | ||
|
dd4f1e6b85 | ||
|
366390935f | ||
|
7eb07fa02f | ||
|
fbe2e41de7 | ||
|
cfc2d93b9b | ||
|
12170461cd | ||
|
ab079036da | ||
|
8001cf3809 | ||
|
d93a47d246 | ||
|
76fb90319b | ||
|
9ca1114670 | ||
|
251784c21c | ||
|
8c3ce2892b | ||
|
6c44fb2a2f | ||
|
465aa38222 | ||
|
6fc83db9df | ||
|
a486fe25b8 | ||
|
87c172acd0 | ||
|
968ec8182c | ||
|
451ed18261 | ||
|
078936fb8a | ||
|
0227b2e06c | ||
|
44c22bb984 | ||
|
da12005420 | ||
|
de65409e79 | ||
|
9ab99a0859 | ||
|
77fdbb5aa2 | ||
|
a8f4bc4617 | ||
|
18cd864e09 | ||
|
192861f9c9 | ||
|
4a43b46432 | ||
|
95bf14385b | ||
|
0fe2df24ad | ||
|
5a368a9c0f | ||
|
73b9cbea13 | ||
|
2dee891c63 | ||
|
97b87bcdc1 | ||
|
c10f18ad1c | ||
|
4d687b022a | ||
|
53d562481e | ||
|
7539fc1a6f | ||
|
f740332e95 | ||
|
4abc9c45d3 | ||
|
756942d2bd | ||
|
fdcab413f5 | ||
|
3c6dd5d0ae | ||
|
3004d7bff5 | ||
|
6494b34da3 | ||
|
447fe8ba08 | ||
|
8ab0b718de | ||
|
97e5bb9b11 | ||
|
5f38a914b1 | ||
|
fa132567da | ||
|
5ea00b8008 | ||
|
a76393f216 | ||
|
739d79e90c | ||
|
e63ba2075f | ||
|
8ca265d8d5 | ||
|
78a7841afb | ||
|
4733e7f65f | ||
|
8c84e276ff | ||
|
a251608fc5 | ||
|
3af6168270 | ||
|
34c17a7662 | ||
|
87aba699f1 | ||
|
defe5cdcb0 | ||
|
038a38cae0 | ||
|
8aaf792c6c | ||
|
659a69e7b7 | ||
|
ec70d4bc56 | ||
|
b0b8a3f89d | ||
|
72be204f77 | ||
|
d5deed0871 | ||
|
040d5bae9d | ||
|
b2ad6e844c | ||
|
b4fb710d61 | ||
|
a5be19ad50 | ||
|
6250be89ed | ||
|
e355814da7 | ||
|
1ecffd61af | ||
|
d887ea4b7b | ||
|
b2943351a1 | ||
|
0b514fbc3e | ||
|
0d743d428f | ||
|
0b809049e2 | ||
|
8b64482fd4 | ||
|
996e47b275 | ||
|
c3ff3370bd | ||
|
83726f0821 | ||
|
1ef2c3b3d4 | ||
|
0af4b185ac | ||
|
a3a90a9be8 | ||
|
7861af7bf9 | ||
|
e90cf6453e | ||
|
dbd36a0d75 | ||
|
c6bc5e1438 | ||
|
cc6a20b3e6 | ||
|
40024f4599 | ||
|
18d8b69f00 | ||
|
62cd0afa37 | ||
|
eb9fd74c77 | ||
|
6c9f0400c8 | ||
|
210d4cb87d | ||
|
7b6301d7f3 | ||
|
63cc8411a5 | ||
|
21c41f9265 | ||
|
83351fb98f | ||
|
4531dd4363 | ||
|
31b10aa0b0 | ||
|
ef16a52ced | ||
|
1a8ae3dcbe | ||
|
34a4a70ae2 | ||
|
f791169f47 | ||
|
782de0165f | ||
|
e555469e3f | ||
|
b4eb6c0994 | ||
|
74cda3f4b4 | ||
|
aebd98cf0a | ||
|
983d5ea09c | ||
|
3720092c09 | ||
|
36cb7a644e | ||
|
6293efd8ee | ||
|
5760379e0a | ||
|
a4ee3085b7 | ||
|
bd60861c1e | ||
|
fbe86e5af8 | ||
|
927add0707 | ||
|
8378ce739b | ||
|
f9e6c3ff95 | ||
|
98ae55790d | ||
|
bb0ad432b2 | ||
|
55e3417df3 | ||
|
92f71bafb2 | ||
|
f1734dbb40 | ||
|
0489e0f902 | ||
|
0aa66fee99 | ||
|
ed1099490c | ||
|
a74bbd093f | ||
|
8ae4b6abd4 | ||
|
ca3c8fc10b | ||
|
e8b9681a15 | ||
|
51516e38f6 | ||
|
de72d6bae3 | ||
|
0d9561e666 | ||
|
97be0bd8ac | ||
|
7f99b24e28 | ||
|
17e5804be7 | ||
|
fd9e41a917 | ||
|
760f4f7dd1 | ||
|
5231262bda | ||
|
34927b5b77 | ||
|
7028286855 | ||
|
342c75775b | ||
|
f1cc8c85f4 | ||
|
c5588e3c49 | ||
|
3d19def3e7 | ||
|
53521c2236 | ||
|
22170450b4 | ||
|
f014db8b7a | ||
|
fe9345b7fc | ||
|
d2bdce51e8 | ||
|
cac92c3ebc | ||
|
603f8349e8 | ||
|
5f6e70289b | ||
|
c716551fc8 | ||
|
78634cdec3 | ||
|
45e989f048 | ||
|
0cfe2a18af | ||
|
71d1383604 | ||
|
0df1c1880e | ||
|
06a2aac022 | ||
|
d8ea42a845 | ||
|
085de8405f | ||
|
990aefc6cb | ||
|
eb29d962f5 | ||
|
605c02901a | ||
|
368bcf258f | ||
|
07efd601da | ||
|
4aab83c4af | ||
|
f05a41f6a5 | ||
|
4d9c0d3f9a | ||
|
35bdcf58cd | ||
|
3ca478da32 | ||
|
5d3da20bd9 | ||
|
a95c070c2b | ||
|
c14c2b3b59 | ||
|
b7e793df02 | ||
|
c245599e65 | ||
|
7e86c561c7 | ||
|
25891ef0ee | ||
|
ba7c6d7a50 | ||
|
7e2dd55c16 | ||
|
b8579ccc90 | ||
|
73a7b209ce | ||
|
8dc8b1d564 | ||
|
d2b4f2e0f6 | ||
|
320f11f795 | ||
|
4237e5b3ae | ||
|
8671afc4b1 | ||
|
6d39fae71a | ||
|
0316f073e0 | ||
|
1744dbc420 | ||
|
eb8ebea920 | ||
|
6c13cfaf30 | ||
|
a228cf244c | ||
|
3b124cfdce | ||
|
4c8bc187b2 | ||
|
1ad6de2dd6 | ||
|
795a9a7e3e | ||
|
87ecf061f1 | ||
|
858a6051ac | ||
|
52693bfc0b | ||
|
79063b9993 | ||
|
22840f8a50 | ||
|
92f74b888b | ||
|
ac241e5ed1 | ||
|
6573d080e4 | ||
|
12a0d0e3cc | ||
|
2a7bfd13b5 | ||
|
ab7e879261 | ||
|
a57853156e | ||
|
a3c0f90476 | ||
|
b5bcc05947 | ||
|
bd579d8613 | ||
|
0c02fbe4cf | ||
|
0b172be3d0 | ||
|
7e9861ba8f | ||
|
0c9fd691ac | ||
|
984386aa64 | ||
|
ae2bd63d8f | ||
|
5e27e27845 | ||
|
ca9d68b99e | ||
|
99c5d7a760 | ||
|
4b6626ee70 | ||
|
8ea9e8a5ad | ||
|
f929f8b7f9 | ||
|
ad8c250314 | ||
|
02146bdf22 | ||
|
dbc0028880 | ||
|
f27238b76f | ||
|
5adc39ebac | ||
|
53ccc4948f | ||
|
e48bd0dd4b | ||
|
cb6fc463aa | ||
|
3b4ef074b9 | ||
|
a3b5c58023 | ||
|
1f7fe4f48e | ||
|
e03d7bc71c | ||
|
828b6785b4 | ||
|
e06d335b7d | ||
|
55d02cb37b | ||
|
8e612e3cd9 | ||
|
0af72d41da | ||
|
ebd9474ac1 | ||
|
2172409fec | ||
|
d22c063ae5 | ||
|
b71a7ae2ac | ||
|
6c26c1397f | ||
|
a31f87f25b | ||
|
18ca225450 | ||
|
fe10f2203b | ||
|
3c2eda4a1d | ||
|
0a07cad2cb | ||
|
f93b30f7b3 | ||
|
35b2c247f3 | ||
|
1915d70c41 | ||
|
059795c0f3 | ||
|
0260e5f803 | ||
|
1b60697565 | ||
|
fb158e418b | ||
|
995cc51f99 | ||
|
760fa4ae63 | ||
|
d4382fda19 | ||
|
4c394c072e | ||
|
699326547a | ||
|
2a9a01bc32 | ||
|
ce22508344 | ||
|
230b72139a | ||
|
0b168e8439 | ||
|
e492885ac0 | ||
|
7cb86638b5 | ||
|
2d5b0753e2 | ||
|
8e1c3e47df | ||
|
99ae9a9850 | ||
|
7b31f4d333 | ||
|
8930201b99 | ||
|
ad11dce92f | ||
|
0c049dd364 | ||
|
ca0953e4bd | ||
|
a17e8bea1c | ||
|
b331405658 | ||
|
c3e3f89e52 | ||
|
f0297fe075 | ||
|
4d4e0ffc8d | ||
|
e202ac9964 | ||
|
5c5825fb75 | ||
|
e0e1fd4f02 | ||
|
5e4fa98577 | ||
|
7e18873bcd | ||
|
592d982210 | ||
|
9d4382c754 | ||
|
b1a448f1e9 | ||
|
af342456c5 | ||
|
5d3895078b | ||
|
0464381cac | ||
|
32a443408a | ||
|
b429484501 | ||
|
2fa1d00fb4 | ||
|
c590c4f4bb | ||
|
6b1845ff39 | ||
|
fb704fdf87 | ||
|
f6a985c24f | ||
|
44cd910154 | ||
|
f21fc90629 | ||
|
21fb57ecfd | ||
|
3bb645ce24 | ||
|
fd991846f4 | ||
|
523566c218 | ||
|
cd1c6a4d23 | ||
|
c3933426b9 | ||
|
be561addfa | ||
|
c379fe80fb | ||
|
5ef0f3ad5d | ||
|
d570b6095e | ||
|
fca275b7c9 | ||
|
e160ee2ed5 | ||
|
70aa22d12d | ||
|
fbfd6c3ac4 | ||
|
7355c2c5fe | ||
|
297869c59f | ||
|
defea1631c | ||
|
82fb263438 | ||
|
d2b9c954d9 | ||
|
f9a9d327d1 | ||
|
d2622f6fed | ||
|
731e98b07c | ||
|
89a3c81a19 | ||
|
2133241998 | ||
|
47b016599e | ||
|
e52056bb33 | ||
|
1c0ce25f12 | ||
|
c42bd90c9d | ||
|
7409668a5d | ||
|
d432bab73a | ||
|
9328db645d | ||
|
21d3159081 | ||
|
b7ad1eaade | ||
|
727bad01c7 | ||
|
b248803a4b | ||
|
a468a0fb24 | ||
|
c2ba8ecf97 | ||
|
7b63b7b30f | ||
|
ca20f687bf | ||
|
bbef09346a | ||
|
1c8085f00e | ||
|
beb220f188 | ||
|
20cd90855f | ||
|
39e9ed8fe4 | ||
|
22a7e1b35f | ||
|
9a95c2d048 | ||
|
9a2424fa26 | ||
|
b44e1c82f0 | ||
|
a07bd7c817 | ||
|
85d75a5494 | ||
|
a2c7e83812 | ||
|
7c7b667745 | ||
|
e1a919749f | ||
|
8dff87658f | ||
|
38519a6261 | ||
|
f6c524f760 | ||
|
94d29bc617 | ||
|
0fb4dcac96 | ||
|
caf8360745 | ||
|
ea63c9a17d | ||
|
6a293de86b | ||
|
5caa5aa9ae | ||
|
b8487cfaa6 | ||
|
203afea72b | ||
|
7f40d1a2f2 | ||
|
47f3109957 | ||
|
066d29d637 | ||
|
12a2354d9e | ||
|
d8f6a16936 | ||
|
8a9e0f6d23 | ||
|
f4fdc36d31 | ||
|
ba52defdae | ||
|
505416a59e | ||
|
9d250c3cbf | ||
|
46e6cfb0d4 | ||
|
3d8a583101 | ||
|
337638034f | ||
|
0f648ed1eb | ||
|
d3fa925bff | ||
|
cb0b1765f3 | ||
|
bef2cbb462 | ||
|
125f45c447 | ||
|
817b1200ca | ||
|
8dcacd41bf | ||
|
2e9f478c87 | ||
|
b13c674047 | ||
|
dd539c7675 | ||
|
4f89c4c10f | ||
|
818ad0955a | ||
|
ac473fd297 | ||
|
11bbbb4899 | ||
|
0d0ee294ad | ||
|
7c51147023 | ||
|
003a90c71c | ||
|
d06761e2a8 | ||
|
c83cc69cef | ||
|
351212cd13 | ||
|
93ec6e4e83 | ||
|
007b4bce2f | ||
|
46a5a64dda | ||
|
72eb9d9595 | ||
|
ba6da97416 | ||
|
fab83139f8 | ||
|
6cd05eab39 | ||
|
16626c80a7 | ||
|
c809141ee6 | ||
|
53df0f8942 | ||
|
17678f06f6 | ||
|
5da069d585 | ||
|
10264e1647 | ||
|
900bb11fb0 | ||
|
1b3ab06614 | ||
|
a20188e7a8 | ||
|
d55fc92c1c | ||
|
0a9444c41b | ||
|
7ebb35d80c | ||
|
cada8146b6 | ||
|
68bcf51ed8 | ||
|
ed089d0546 | ||
|
6ee3ddbc8c | ||
|
c3aafdf341 | ||
|
9411860f69 | ||
|
4dc78c3742 | ||
|
ee4ab47442 | ||
|
4bb4f932cf | ||
|
f25f110e0e | ||
|
e9ae5306e3 | ||
|
8ad097f23f | ||
|
048560908e | ||
|
0dee9897dd | ||
|
a673086941 | ||
|
b16d035975 | ||
|
ca9e13a047 | ||
|
dc66c3a101 | ||
|
47bab27f7b | ||
|
077162529d | ||
|
32bc8917ab | ||
|
b418db5643 | ||
|
1c247969b4 | ||
|
c178cbbcd8 | ||
|
d31f1ce317 | ||
|
209bea2fcc | ||
|
c820920b2c | ||
|
ed7efb2c61 | ||
|
801a21e049 | ||
|
a8a397d8b2 | ||
|
bdc7390eca | ||
|
0f99d4833e | ||
|
b96150a629 | ||
|
6001273c6f | ||
|
430f1f5a0e | ||
|
128079f2a4 | ||
|
8efafc7c25 | ||
|
20666a334e | ||
|
c81841e036 | ||
|
3d74ed31c2 | ||
|
1a6a7ade73 | ||
|
ee4e056125 | ||
|
e4da0f894d | ||
|
284eccf047 | ||
|
bad2577e5e | ||
|
9b1a7c70a3 | ||
|
a06d180827 | ||
|
2af758e66d | ||
|
fa562cabae | ||
|
07b2425ff9 | ||
|
d48d748e30 | ||
|
33f3cb76ad | ||
|
78846ab984 | ||
|
afbb46bd8c | ||
|
ed63902ac1 | ||
|
35947e3d62 | ||
|
bdac6f1b47 | ||
|
c76e6fb86b | ||
|
664f290001 | ||
|
c62ea03e2e | ||
|
8db12e61bf | ||
|
f36c3fefdd | ||
|
a5b73f0309 | ||
|
e347621dc8 | ||
|
1ee75b78b7 | ||
|
571cb3bac1 | ||
|
5dd0065936 | ||
|
ecfc3e9fcf | ||
|
a60127e66f | ||
|
93e1758a0b | ||
|
2fb8ea3ea0 | ||
|
1c6ada4af8 | ||
|
ca02bdcb61 | ||
|
90d93b364a | ||
|
6177afd5b1 | ||
|
5abec5bff0 | ||
|
ec792abbda | ||
|
6890da11ed | ||
|
1b31e80f25 | ||
|
d2a33bc210 | ||
|
3cfdf4c946 | ||
|
5a7f16b6f9 | ||
|
32e521fdc7 | ||
|
521f3d88d2 | ||
|
cf8522b1ef | ||
|
6cff47c6d8 | ||
|
366932e999 | ||
|
be2ded3b7e | ||
|
1809e38911 | ||
|
06ec539839 | ||
|
84c6a0039c | ||
|
5ff57258ec | ||
|
d4f6b040f3 | ||
|
1104b28758 | ||
|
881a9a6d27 | ||
|
48f37aa1c0 | ||
|
7f2ab05f97 | ||
|
de092f8f00 | ||
|
9e48fdc91c | ||
|
05dcb4e8d7 | ||
|
864e8910c4 | ||
|
efafc2d691 | ||
|
ed490fc202 | ||
|
ae6dbeb287 | ||
|
75fee76693 | ||
|
caffcaaef2 | ||
|
2b7624e622 | ||
|
ad501d4309 | ||
|
126fa1809e | ||
|
d44abbb48e | ||
|
40a49042e9 | ||
|
6b3f8a3f39 | ||
|
2c1d6e3ecb | ||
|
906a606010 | ||
|
ef2c206507 | ||
|
b78c19f6f2 | ||
|
8aa16ea0be | ||
|
8d01d7a710 | ||
|
660d765c59 | ||
|
8f34065fc0 | ||
|
f40a8f69ae | ||
|
0950555b49 | ||
|
286ab1ad83 | ||
|
90cac3ecae | ||
|
f04a376653 | ||
|
b75e67fafa | ||
|
8854f67c20 | ||
|
9b4ce0011e | ||
|
c03bc7d600 | ||
|
8f2f3e6498 | ||
|
730cb9c822 | ||
|
acbd6000fc | ||
|
e80a12a8a4 | ||
|
a21abae5f6 | ||
|
5095027a0b | ||
|
5dc89fb2b3 | ||
|
353a90788c | ||
|
90ea092e4d | ||
|
7e88ffd098 | ||
|
6827e21df1 | ||
|
b4d00f86a8 | ||
|
c4ccde1b4d | ||
|
0c0af2d00b | ||
|
6c3a3dd1d3 | ||
|
fc51257ee1 | ||
|
47b8337ff6 | ||
|
8d62c2b103 | ||
|
726dbddea7 | ||
|
88d778bdea | ||
|
9edab0729f | ||
|
9cef50323a | ||
|
df53282b6e | ||
|
b936824348 | ||
|
a0ff85d74e | ||
|
f739b9d37d | ||
|
8eac031047 | ||
|
edd3b681c5 | ||
|
82ade54caa | ||
|
610e334bed | ||
|
44a573b6c4 | ||
|
95fbd55a19 | ||
|
d0627f800c | ||
|
ac36407d1d | ||
|
ebfda5c86e | ||
|
106cde9262 | ||
|
7b4f8954b3 | ||
|
0242fdb020 | ||
|
10c610232c | ||
|
c961615609 | ||
|
55146820e3 | ||
|
0ccf25d986 | ||
|
316748988b | ||
|
7075c9feee | ||
|
5cce34eb40 | ||
|
60826ac6c6 | ||
|
8931c61876 | ||
|
d1abf3a04e | ||
|
2bdea0dd18 | ||
|
d2a35d4ce1 | ||
|
8de4671603 | ||
|
b22127a877 | ||
|
d7af120154 | ||
|
7bc70f728a | ||
|
664c3522a7 | ||
|
c209b9e2b9 | ||
|
2bcf01f5ab | ||
|
14e5e3b3a6 | ||
|
3c0a621b47 | ||
|
fe3650d766 | ||
|
46201613a6 | ||
|
f2aa39e1c3 | ||
|
b90a435833 | ||
|
bff714f24c | ||
|
06460507d4 | ||
|
01efb02f9e | ||
|
3d8852950d | ||
|
e675c853f3 | ||
|
27bc548552 | ||
|
424a0c43a3 | ||
|
6665bef76c | ||
|
dff5f485c9 | ||
|
4047d619a1 | ||
|
956a890b94 | ||
|
767d5ec91d | ||
|
335a491e0d | ||
|
3e9f028bf4 | ||
|
8506646db2 | ||
|
be329a2d10 | ||
|
73989e09a9 | ||
|
46f567d0d1 | ||
|
18f883545b | ||
|
7a22afa9ec | ||
|
524e14f464 | ||
|
7503de27c5 | ||
|
f4da817cb2 | ||
|
51e0237f5d | ||
|
14020125b9 | ||
|
0f82b76c09 | ||
|
4c6c774251 | ||
|
fe28b3e6af | ||
|
f9a2719507 | ||
|
0b00d4f9e1 | ||
|
aa80093665 | ||
|
778121010f | ||
|
a5c391a6a3 | ||
|
f846cb1b20 | ||
|
789d3438e3 | ||
|
f6de5247d6 | ||
|
c80d65cf60 | ||
|
cba44998b9 | ||
|
ba0ea6c2c4 | ||
|
7848d8cb2f | ||
|
2c0fbec43c | ||
|
c5de9dd9f1 | ||
|
92093d6d28 | ||
|
670f435c64 | ||
|
846dfd6762 | ||
|
e00bf3da36 | ||
|
9e21813251 | ||
|
3d3242c00d | ||
|
522998bade | ||
|
629f382642 | ||
|
ad96db994e | ||
|
958d98a1a1 | ||
|
fb6bafdf6c | ||
|
6dea5959cc | ||
|
afd737f965 | ||
|
8de6e78729 | ||
|
be8a47b672 | ||
|
cf11f2588c | ||
|
bb60f8cff4 | ||
|
42b15497fc | ||
|
f598b7d267 | ||
|
9349ba200e | ||
|
619fb538d7 | ||
|
095d9b60cd | ||
|
33b426c79e | ||
|
2ac49fb9a5 | ||
|
b071a0e22f | ||
|
b6f2662ad7 | ||
|
5ea9564cc3 | ||
|
85a651ae79 | ||
|
dc711d494f | ||
|
14f0ed43c5 | ||
|
6f318bc86d | ||
|
bbc952b265 | ||
|
1121a90af0 | ||
|
969b2f2e11 | ||
|
8907adc236 | ||
|
c8304497b5 | ||
|
68f0be996f | ||
|
9fb92080f2 | ||
|
ba1b712fee | ||
|
543cf9066a | ||
|
bccd4a81b8 | ||
|
17d9d2766d | ||
|
2bbb889196 | ||
|
ff1b6d3adf | ||
|
39d60f05c3 | ||
|
54d6a6af56 | ||
|
5b3d03bc63 | ||
|
878a3b49a7 | ||
|
825e2643ae | ||
|
9bcf5f2947 | ||
|
c966c49304 | ||
|
90dff612c7 | ||
|
9e4a4ba2ff | ||
|
e3612e8c62 | ||
|
06c4ded063 | ||
|
ff233a5b1c | ||
|
982586b0e6 | ||
|
ae5a13bb06 | ||
|
f3efbba26c | ||
|
2f7dcb6bbc | ||
|
623deac3ec | ||
|
58d96c8594 | ||
|
8701708b53 | ||
|
279a3c3413 | ||
|
fe3e63d8c5 | ||
|
ec93e2fff3 | ||
|
59d55b3526 | ||
|
0756af2b30 | ||
|
1598640c80 | ||
|
994e528b45 | ||
|
06f03fc884 | ||
|
698f3a7b15 | ||
|
c0c8fbac38 | ||
|
19b34231d4 | ||
|
ad53a3c9a1 | ||
|
58b59fe263 | ||
|
d71ab6d30d | ||
|
2b12f8e257 | ||
|
9e81fa495e | ||
|
f40bbbf145 | ||
|
1fc44b9d8e | ||
|
7bd0d9a83f | ||
|
c8f0406c84 | ||
|
18e3b618b4 | ||
|
fdc81fa4ea | ||
|
dd609c1cec | ||
|
d0594a6bfc | ||
|
9c11e0dc32 | ||
|
4bdafb8ea3 | ||
|
8966290369 | ||
|
9ea8653ef7 | ||
|
fe29a86af9 | ||
|
1cb2b1f7a9 | ||
|
4870d41aae | ||
|
754f1fcb25 | ||
|
3d58b67517 | ||
|
57ccf4c20e | ||
|
4c804fcf2d | ||
|
1f7fecab21 | ||
|
d86f3094b9 | ||
|
4b737c1c93 | ||
|
ff14a706cf | ||
|
8e0701f7bb | ||
|
a5d428c42d | ||
|
b2445d36d1 | ||
|
db12e8a1e6 | ||
|
f7432672e4 | ||
|
7b49296a24 | ||
|
b678df8d23 | ||
|
a4b90e3ab2 | ||
|
458c51b32d | ||
|
6af9142810 | ||
|
7b7ec45db8 | ||
|
f283dd848e | ||
|
b2f09f64c3 | ||
|
3558936b46 | ||
|
9e90b60a4f | ||
|
a129638fd1 | ||
|
649e813ee8 | ||
|
943ad96d52 | ||
|
fdde708327 | ||
|
b439ae1cc4 | ||
|
cd9977c94e | ||
|
383f5c1d60 | ||
|
13e19eb7f8 | ||
|
42581b1d12 | ||
|
573cc3e8d9 | ||
|
a67603f689 | ||
|
2b984e7851 | ||
|
e57bc316d1 | ||
|
ee0628085b | ||
|
b24ece11e5 | ||
|
e5240c1a45 | ||
|
00f1aae38d | ||
|
be9db63718 | ||
|
548021b556 | ||
|
24e57244d1 | ||
|
724a6855ed | ||
|
e7ddd07d56 | ||
|
65742d32ec | ||
|
6d60a79369 | ||
|
ccd60f76c3 | ||
|
3bfd60a3df | ||
|
3129dd9351 | ||
|
c2a6b09a25 | ||
|
f897596215 | ||
|
7f5a1d205e | ||
|
b31eaadfab | ||
|
bd8a57e0c3 | ||
|
65efe5ad43 | ||
|
41d82a54b6 | ||
|
864f5fd7d3 | ||
|
1fd3e3676a | ||
|
16e7133e31 | ||
|
6d01a3153e | ||
|
3c99f1f840 | ||
|
b28594a976 | ||
|
3bdae848b3 | ||
|
89906f4826 | ||
|
fde371b90f | ||
|
453b993cfb | ||
|
90ab412628 | ||
|
1b91d9b69e | ||
|
79a4006a61 | ||
|
73c4c21533 | ||
|
b189fc83b0 | ||
|
005cf4dc96 | ||
|
f805f0d1ef | ||
|
9d5d94a8f4 | ||
|
e896361b2f | ||
|
224336e232 | ||
|
05abb1dae9 | ||
|
8f21b020b1 | ||
|
7126ee2df9 | ||
|
19e701683d | ||
|
d548180f20 | ||
|
bd452a04e8 | ||
|
001fe37059 | ||
|
fff431737b | ||
|
0aec04a9c9 | ||
|
cc0ddc92b3 | ||
|
2461d433e8 | ||
|
859d4ff640 | ||
|
249f0b4e79 | ||
|
02a821aa3c | ||
|
1b4787df99 | ||
|
6c39cbca5e | ||
|
e3faa3c443 | ||
|
94e4ff9cdd | ||
|
bb302b91c4 | ||
|
5dc3639831 | ||
|
c3f03e0e3e | ||
|
3e6634c1e4 | ||
|
a1e788b958 | ||
|
5450e0ccde | ||
|
164d2898c9 | ||
|
884b5a7661 | ||
|
76a64898ef | ||
|
7e793f9514 | ||
|
9555f7610d | ||
|
e023c1b47d | ||
|
9e089a5090 | ||
|
dde3ef206d | ||
|
c7c077074f | ||
|
f62b9ab665 | ||
|
56a7050160 | ||
|
da1eeb9cfa | ||
|
96f5b07bec | ||
|
e0ccba9e24 | ||
|
35ad4d31a1 | ||
|
d8daedea0d | ||
|
851bfc61e0 | ||
|
5006ebcbae | ||
|
69a9adb459 | ||
|
4646956922 | ||
|
2dbe50fc97 | ||
|
349b6d616d | ||
|
4ca30c4b93 | ||
|
4fd848ff3e | ||
|
d3ab68011a | ||
|
a921e303ac | ||
|
0d9c7bade3 | ||
|
b19a1e79f5 | ||
|
051eeb9980 | ||
|
6400710b56 | ||
|
08a47b9ad9 | ||
|
68d461bd42 | ||
|
a24aa1487e | ||
|
541613d1fe | ||
|
19a9da3032 | ||
|
698ad90c43 | ||
|
3e5bd34141 | ||
|
a778f3866a | ||
|
c90b7a9691 | ||
|
1bd4572957 | ||
|
8dd8c7d1dd | ||
|
64fd0ebcf6 | ||
|
68ca5dd279 | ||
|
9bac86fe1a | ||
|
16e1f95790 | ||
|
426bf1d631 | ||
|
49837c2da4 | ||
|
ce1c5ec7f6 | ||
|
d8cab006c8 | ||
|
d335a11119 | ||
|
4d0012f672 | ||
|
c11b3d03f4 | ||
|
5cab477bf4 | ||
|
61dacfd2a5 | ||
|
8d74e063af | ||
|
ccfa00d7b8 | ||
|
f158a996f4 | ||
|
ae3b2c597d | ||
|
f4bcfa5c44 | ||
|
16edc2954d | ||
|
c69eb6e1bf | ||
|
de4fd466dc | ||
|
c43969fece | ||
|
3ae71a45a2 | ||
|
a8a2bb4681 | ||
|
906fa93812 | ||
|
9ce4092a7c | ||
|
94bc087f50 | ||
|
8b052e20b9 | ||
|
45e0ba7f9b | ||
|
a32b7b64bf | ||
|
78fb5935c7 | ||
|
b2ac138c88 | ||
|
95c14e5a26 | ||
|
f81292e955 | ||
|
790caf9f5a | ||
|
18e48be5c4 | ||
|
3f24720633 | ||
|
28fb2472a4 | ||
|
f33fa1e9fc | ||
|
22b6b4b502 | ||
|
7abc81f8a4 | ||
|
ea6e370347 | ||
|
9f5dbad589 | ||
|
7407a5a681 | ||
|
b8d710800a | ||
|
bb317d1abb | ||
|
b31f334109 | ||
|
05c00c5e1c | ||
|
704b50fb3e | ||
|
fa7443be95 | ||
|
d1c807ec79 | ||
|
66abe309f6 | ||
|
336adac1ef | ||
|
d6c0129c86 | ||
|
fd2f253c09 | ||
|
a029ece808 | ||
|
e64798208f | ||
|
be9016a081 | ||
|
75b8a16465 | ||
|
a59920e6e5 | ||
|
6ca2183e24 | ||
|
bb7d1c5cba | ||
|
0ecd86ecf7 | ||
|
ccfb29f1b3 | ||
|
b9bf577ccd | ||
|
7f869ea72d | ||
|
dea2eea919 | ||
|
1949356ede | ||
|
eb65f75f45 | ||
|
758c46c5aa | ||
|
581f892613 | ||
|
0a1cbf87b8 | ||
|
5feaab9a95 | ||
|
a294827211 | ||
|
9568d57e5f | ||
|
5d1b5ac6c9 | ||
|
50dda3244e | ||
|
7f851208aa | ||
|
7199e63fd7 | ||
|
85bd192f3c | ||
|
1a88aff179 | ||
|
61bb0cfab7 | ||
|
2c7b220453 | ||
|
8bd2114d8a | ||
|
c0249b9c28 | ||
|
26c1c483da | ||
|
dcd1407109 | ||
|
b5b35a97c6 | ||
|
58c5e9676a | ||
|
5e6a6ba6ac | ||
|
9a2678450a | ||
|
bb8c7423b6 | ||
|
2f5cc3b271 | ||
|
11023dfef9 | ||
|
2da2dbff71 | ||
|
eaa67dab91 | ||
|
680701667e | ||
|
3f47c4d3dd | ||
|
d55c4eb66e | ||
|
9a2ded5a9a | ||
|
c1847a0b34 | ||
|
5e0b05356f | ||
|
12bb9375f4 | ||
|
f2ef8c7206 | ||
|
3f40098144 | ||
|
9372ad2dff | ||
|
e31fa1f7dd | ||
|
828eac1e72 | ||
|
bb3ac36098 | ||
|
794a709690 | ||
|
da131715ba | ||
|
62dbb1062f | ||
|
6b9c718df7 | ||
|
986f7550f3 | ||
|
1f476b8793 | ||
|
8db1f3e3f3 | ||
|
4349b016eb | ||
|
c09511adb8 | ||
|
18e6ebe9af | ||
|
594332181b | ||
|
2121766623 | ||
|
fe365a6561 | ||
|
eed9ee8033 | ||
|
e80afbfe39 | ||
|
e8eea6324e | ||
|
c457081597 | ||
|
e6e416306e | ||
|
2f244da8b1 | ||
|
14c9b2f4ae | ||
|
3b00a0e30d | ||
|
b771827d2a | ||
|
5a82478381 | ||
|
c855d2f4ce | ||
|
4ece50d07c | ||
|
23a4a20dc2 | ||
|
bb3f52d2f2 | ||
|
9174be8ff3 | ||
|
af2df84fc1 | ||
|
8572c86941 | ||
|
58586ab2e4 | ||
|
240fab99f4 | ||
|
e31d5ba939 | ||
|
c0fafcec70 | ||
|
e8536ebc88 | ||
|
2b6c56f148 | ||
|
ecfaba0781 | ||
|
4c1813d6d4 | ||
|
e3ebde9741 | ||
|
01e03fc677 | ||
|
d47c72711b | ||
|
824bf2ed30 | ||
|
5dc7a442f6 | ||
|
c0dc8c8915 | ||
|
f4b6b93b8b | ||
|
160ab3452e | ||
|
1a161ad2c7 | ||
|
b18cc6bcc5 | ||
|
34cba68432 | ||
|
5a3aaeb056 | ||
|
01ee942920 | ||
|
21dfd8a325 | ||
|
f5707c51c0 | ||
|
c608958eb3 | ||
|
f86efca9a6 | ||
|
8b9c97745f | ||
|
35db01d316 | ||
|
30e784b8ec | ||
|
33f62bb93c | ||
|
a65da05094 | ||
|
c002600ac5 | ||
|
fb316ff010 | ||
|
d2074afe9a | ||
|
f9650f33be | ||
|
7ae2b48da9 | ||
|
357b6406e2 | ||
|
db1905fdb6 | ||
|
c0e0a209e4 | ||
|
77b737ad87 | ||
|
4e3a81d697 | ||
|
1b50696ca7 | ||
|
2918a175ee | ||
|
a70e82c82b | ||
|
b03ea65943 | ||
|
f2e1b5983e | ||
|
4520a04be9 |
@ -1,7 +1,7 @@
|
||||
{
|
||||
"parser": "babel-eslint",
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 2017,
|
||||
"ecmaVersion": 2020,
|
||||
"sourceType": "module",
|
||||
"allowImportExportEverywhere": true
|
||||
},
|
||||
@ -10,8 +10,12 @@
|
||||
"jasmine": true,
|
||||
"es6": true
|
||||
},
|
||||
"plugins": ["lodash"],
|
||||
"extends": ["eslint:recommended", "plugin:lodash/canonical"],
|
||||
"plugins": ["@typescript-eslint"],
|
||||
"extends": [
|
||||
"eslint:recommended",
|
||||
"plugin:@typescript-eslint/eslint-recommended",
|
||||
"plugin:@typescript-eslint/recommended"
|
||||
],
|
||||
"globals": {
|
||||
"Uint8Array": true,
|
||||
"Promise": true,
|
||||
@ -21,20 +25,6 @@
|
||||
"window": true
|
||||
},
|
||||
"rules": {
|
||||
"lodash/prefer-lodash-chain": "off",
|
||||
"lodash/prefer-lodash-method": "off",
|
||||
"lodash/import-scope": "off",
|
||||
"lodash/prefer-constant": "off",
|
||||
"lodash/prefer-get": "off",
|
||||
"lodash/prefer-includes": "off",
|
||||
"lodash/prefer-invoke-map": "off",
|
||||
"lodash/prefer-is-nil": "off",
|
||||
"lodash/prefer-lodash-typecheck": "off",
|
||||
"lodash/prefer-noop": "off",
|
||||
"lodash/prefer-startswith": "off",
|
||||
"lodash/preferred-alias": "off",
|
||||
"lodash/matches-prop-shorthand": "off",
|
||||
"lodash/prop-shorthand": "off",
|
||||
"accessor-pairs": "error",
|
||||
"array-bracket-spacing": "off",
|
||||
"array-callback-return": "error",
|
||||
|
28
.github/CONTRIBUTING.md
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
# Contribution Guidelines
|
||||
|
||||
Thanks for contributing to [Converse.js](https://conversejs.org)
|
||||
|
||||
## Support questions
|
||||
|
||||
The Github issue tracker is used for bug reports and feature requests, not for general tech support.
|
||||
|
||||
For support, you can join our [XMPP webchat](https://inverse.chat/#converse/room?jid=discuss@conference.conversejs.org).
|
||||
Instead of the webchat, you can also open the room in your XMPP client, [click here](xmpp://discuss@conference.conversejs.org?join).
|
||||
|
||||
You can also ask questions on [StackOverflow](https://stackoverflow.com/questions/tagged/converse.js)
|
||||
|
||||
## Contributing Code
|
||||
|
||||
Please follow the usual Github workflow. Create a fork of this repository, make your changes and then submit a pull request.
|
||||
|
||||
### Before submitting a pull request
|
||||
|
||||
Please read the [style guide](https://conversejs.org/docs/html/style_guide.html) and make sure that your code follows it.
|
||||
|
||||
### Add tests for your bugfix or feature
|
||||
|
||||
Add a test for any bug fixed or feature added.
|
||||
|
||||
Tests can be found in various `./tests` folders in the Converse source code.
|
||||
|
||||
To run the tests, you can run `make check` on Linux and Mac, or `./node_modules/bin/karma start karma.conf` on Windows.
|
37
.github/CONTRIBUTING.rst
vendored
@ -1,37 +0,0 @@
|
||||
=======================
|
||||
Contribution Guidelines
|
||||
=======================
|
||||
|
||||
Thanks for contributing to `Converse.js <https://conversejs.org>`_.
|
||||
|
||||
Support questions
|
||||
=================
|
||||
Please ask support and setup questions on the mailing list: conversejs@librelist.com
|
||||
|
||||
The issue tracker is only for bugs (i.e. issues) and feature requests.
|
||||
|
||||
Contributing Code
|
||||
=================
|
||||
Please follow the usual github workflow. Create your own local fork of this repository,
|
||||
make your changes and then submit a pull request.
|
||||
|
||||
Before submitting a pull request
|
||||
--------------------------------
|
||||
|
||||
Please read the `style guide <https://conversejs.org/docs/html/style_guide.html>`_ and make sure that your code follows it.
|
||||
|
||||
Add tests for your bugfix or feature
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Add a test for any bug fixed or feature added. We use Jasmine
|
||||
for testing.
|
||||
|
||||
Take a look at `tests.html <https://github.com/jcbrand/converse.js/blob/master/tests.html>`_
|
||||
and the `spec files <https://github.com/jcbrand/converse.js/blob/master/tests.html>`_
|
||||
to see how tests are implemented.
|
||||
|
||||
Check that the tests pass
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Check that all tests complete sucessfully.
|
||||
|
||||
Run ``make check`` in your terminal or open `tests.html <https://github.com/jcbrand/converse.js/blob/master/tests.html>`_
|
||||
in your browser.
|
2
.github/codeql-config.yml
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
paths-ignore:
|
||||
- '**/tests/*.js'
|
61
.github/dependabot.yml
vendored
Normal file
@ -0,0 +1,61 @@
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: npm
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: daily
|
||||
open-pull-requests-limit: 10
|
||||
ignore:
|
||||
- dependency-name: mini-css-extract-plugin
|
||||
versions:
|
||||
- 1.3.5
|
||||
- 1.3.6
|
||||
- 1.3.7
|
||||
- 1.3.8
|
||||
- 1.3.9
|
||||
- 1.4.0
|
||||
- 1.4.1
|
||||
- 1.5.0
|
||||
- dependency-name: css-loader
|
||||
versions:
|
||||
- 5.0.1
|
||||
- 5.0.2
|
||||
- 5.1.0
|
||||
- 5.1.1
|
||||
- 5.1.2
|
||||
- 5.1.3
|
||||
- 5.2.0
|
||||
- 5.2.1
|
||||
- dependency-name: y18n
|
||||
versions:
|
||||
- 4.0.2
|
||||
- dependency-name: sinon
|
||||
versions:
|
||||
- 10.0.0
|
||||
- 9.2.4
|
||||
- dependency-name: bootstrap
|
||||
versions:
|
||||
- 4.6.0
|
||||
- dependency-name: "@babel/plugin-proposal-nullish-coalescing-operator"
|
||||
versions:
|
||||
- 7.12.1
|
||||
- 7.12.13
|
||||
- 7.13.0
|
||||
- 7.13.8
|
||||
- dependency-name: webpack-cli
|
||||
versions:
|
||||
- 4.4.0
|
||||
- 4.5.0
|
||||
- dependency-name: webpack-merge
|
||||
versions:
|
||||
- 5.7.3
|
||||
- dependency-name: xmldom
|
||||
versions:
|
||||
- 0.5.0
|
||||
- dependency-name: urijs
|
||||
versions:
|
||||
- 1.19.4
|
||||
- 1.19.6
|
||||
- dependency-name: sass-loader
|
||||
versions:
|
||||
- 10.1.1
|
43
.github/workflows/codeql.yml
vendored
Normal file
@ -0,0 +1,43 @@
|
||||
name: "CodeQL"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ "master" ]
|
||||
pull_request:
|
||||
branches: [ "master" ]
|
||||
schedule:
|
||||
- cron: "11 18 * * 6"
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
name: Analyze
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
security-events: write
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
language: [ javascript ]
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v2
|
||||
with:
|
||||
config-file: ./.github/codeql-config.yml
|
||||
languages: ${{ matrix.language }}
|
||||
queries: +security-and-quality
|
||||
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@v2
|
||||
if: ${{ matrix.language == 'javascript' }}
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v2
|
||||
with:
|
||||
category: "/language:${{ matrix.language }}"
|
34
.github/workflows/karma-tests.yml
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
# This workflow will do a clean installation of node dependencies, cache/restore them, build the source code and run tests across different versions of node
|
||||
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
|
||||
|
||||
name: CI Tests
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
DISPLAY: :99.0
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [18.x]
|
||||
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
cache: 'npm'
|
||||
- name: Run Karma tests
|
||||
uses: GabrielBB/xvfb-action@v1
|
||||
with:
|
||||
run: make check ARGS=--single-run
|
3
.gitignore
vendored
@ -1,6 +1,9 @@
|
||||
# Distribution directory
|
||||
dist
|
||||
|
||||
# conversejs/media repo checkout
|
||||
media
|
||||
|
||||
# Editor fluff
|
||||
*~
|
||||
.sw?
|
||||
|
@ -1,6 +1,5 @@
|
||||
{
|
||||
"arrowParens": "avoid",
|
||||
"printWidth": 100,
|
||||
"printWidth": 120,
|
||||
"quoteProps": "preserve",
|
||||
"singleQuote": true,
|
||||
"spaceBeforeFunctionParen": true,
|
||||
|
15
.travis.yml
@ -1,15 +0,0 @@
|
||||
dist: bionic
|
||||
language: node_js
|
||||
cache:
|
||||
directories:
|
||||
- node_modules
|
||||
addons:
|
||||
chrome: stable
|
||||
node_js:
|
||||
- "14"
|
||||
install: make node_modules
|
||||
services:
|
||||
- xvfb
|
||||
before_script:
|
||||
- export DISPLAY=:99.0
|
||||
script: make check ARGS=--single-run
|
36541
3rdparty/libsignal-protocol.js
vendored
Normal file
1
3rdparty/libsignal-protocol.min.js
vendored
Normal file
284
CHANGES.md
@ -1,9 +1,285 @@
|
||||
# Changelog
|
||||
|
||||
## 10.1.6 (2023-08-31)
|
||||
|
||||
- #3246: Badge color not responsive to dark theme
|
||||
- Fix a GIF rendering bug that causes a memory overflow
|
||||
|
||||
## 10.1.5 (2023-06-29)
|
||||
|
||||
- #3209: Fix error when importing the `converse` global with bootstrap modal API
|
||||
- #3207: `.po` translation files weren't included in previous release
|
||||
- Updated Galician and Portuguese translations
|
||||
|
||||
## 10.1.4 (2023-06-25)
|
||||
|
||||
- Fix `dist` directory not included in NPM package
|
||||
|
||||
## 10.1.3 (2023-06-23)
|
||||
|
||||
- Add the ability to set roles and affiliations via the MUC occupant modal
|
||||
- Fix `isOnlyEmojis is not a function` when using only `@converse/headless`
|
||||
- Fix `autojoin` checkbox state in MUC bookmark form
|
||||
- Remove call to `api.confirm` in `@converse/headless`
|
||||
- Generate TypeScript declaration files into `dist/types`
|
||||
- Removed documentation about the no longer implemented `fullname` option.
|
||||
- Updated translations
|
||||
- #3123: Contacts do not show up online until chat is opened with them.
|
||||
- #3156: Add function to prevent drag stutter effect over iframes when resize is called in overlay mode
|
||||
- #3165: Use configured nickname in profile view in the control box
|
||||
|
||||
- New config option [stanza_timeout](https://conversejs.org/docs/html/configuration.html#stanza-timeout)
|
||||
|
||||
## 10.1.2 (2023-02-17)
|
||||
|
||||
- #1490: Busy-loop when fetching registration form fails
|
||||
- #1556: Can't switch to registration form afrer logout
|
||||
- #3137: Various UI/UX bugfixes regarding the registration form
|
||||
- XEP-0437: Room Activity Indicators (RAI) optimizations
|
||||
|
||||
## 10.1.1 (2023-02-15)
|
||||
|
||||
- #1851: Sort open groupchats alphabetically
|
||||
- #2240: Ad-Hoc command result form not shown
|
||||
- #3128: Second bookmarked room shows info of the first one
|
||||
- Bugfix. Uyghur translations weren't loading
|
||||
|
||||
## 10.1.0 (2023-01-07)
|
||||
|
||||
- #326: Add the ability to reset your password
|
||||
- #2759: Don't automatically log in again if the user manually logged out
|
||||
- #2816: Chat highlight behaves odd
|
||||
- #2925: File upload is not always enabled
|
||||
- #3001: Add option to save SCRAM details and to use them to stay logged in upon reload
|
||||
- Add a "Add to Contacts" button in MUC occupant modals
|
||||
- Updated translations and add support for Uyghur
|
||||
|
||||
- New config option [reuse_scram_keys](https://conversejs.org/docs/html/configuration.html#reuse-scram-keys)
|
||||
|
||||
## 10.0.0 (2022-10-30)
|
||||
|
||||
- Update to Strophe.js 1.6.0 which adds support for SCRAM-SHA-256 and SCRAM-SHA-512
|
||||
- Don't automatically convert OpenStreetMap URLs into `geo:` URIs in sent messages
|
||||
- Remove the `allow_chat_pending_contacts` config option.
|
||||
- Show roster contacts with `subscription` set to `none`
|
||||
- Remove the `converse-carbons` plugin and make carbons part of the `converse-chat` plugin.
|
||||
- Remove the `message_carbons` configuration setting. Carbons are now always enabled.
|
||||
- Move the `converse-oauth` plugin to the [community-plugins](https://github.com/conversejs/community-plugins)
|
||||
- Don't apply message corrections when the MUC occupant-id doesn't match.
|
||||
- Update `nick` attribute on ChatRoom when user nickname changes
|
||||
- Restrict editing of MUC messages to ones with the same XEP-0421 occupant ID
|
||||
- Remove unfurls for links removed in a subsequent message correction
|
||||
- Bookmarks now appear in a modal and the `hide_open_bookmarks` config setting has been removed.
|
||||
- #1004: Stop using fonts to render icons and use SVG instead
|
||||
- #2797: Weird unicode characters rendering outside of line-height
|
||||
- #2870: Fix for multiple URLs to be linkified when sent together in chat and adds a test for this.
|
||||
- #2879: Quotes, lines not aligned to the first line
|
||||
- #2925: Fix missing disco-items in browser storage.
|
||||
- #2936: Fix documentation about enable_smacks option, which is true by default.
|
||||
- #2939: Data forms with a field named "username" are not displayed
|
||||
- #3005: Fix MUC messages with a fallback body not rendering.
|
||||
- #3007: Fix links becoming text when a message is edited
|
||||
- #3018: Fix MUC icons not functioning.
|
||||
- #3028: Fix encrypted media from Conversations/Quicksy not properly decrypting
|
||||
|
||||
|
||||
## 9.1.1 (2022-05-05)
|
||||
|
||||
- GIFs don't render inside unfurls and cause a TypeError
|
||||
- Improve how the `muc_domain` setting is populated via service discovery
|
||||
- Remove local (non-requesting) contacts not returned from a full roster response
|
||||
- Improve performance by looking up VCards via map instead of traversing an array
|
||||
- Fix infinite loop when receiving service discovery entities with a circular dependency
|
||||
- #1130: Display the room’s vCard-temp avatar
|
||||
- #2746: Always reply to all iqs, even those not understood
|
||||
- #2794: Some display problems with mobile view mode
|
||||
- #2868: Selected emoji is inserted into all open chat boxes
|
||||
|
||||
Remove the very old and largely unused config option `allow_muc`.
|
||||
If you don't want MUC support, you can add `'converse-muc'` to the
|
||||
`blacklisted_plugins` setting.
|
||||
|
||||
## 9.1.0 (2022-04-02)
|
||||
|
||||
- Updated translations: af, ar, es, eu, fr, gl, he, lt
|
||||
- Increased stanza timeout from 10 to 20 seconds
|
||||
- Replace various font icons with SVG icons
|
||||
- Fix bug where MUC config wasn't persisted across page loads
|
||||
- Add support for calling the IndexedDB `getAll` method to speed up fetching models from storage.
|
||||
- #1761: Add a new dark theme based on the [Dracula](https://draculatheme.com/) theme
|
||||
- #2557: Allow OMEMO encrypted messages to be edited
|
||||
- #2627: Spoiler toggles only after switching to another tab and back
|
||||
- #2733: Fix OMEMO race condition related to automatic reconnection and SMACKS
|
||||
- #2733: Wait for decrypted/parsed message before queuing to UI
|
||||
- #2751: Media not rendered when Converse runs in a browser extension
|
||||
- #2754: Navigation keys doesn't work anymore into chat input message
|
||||
- #2781: Flashing error when connecting to a room
|
||||
- #2786: Fix webpack configuration not working on Windows OS
|
||||
- #2788: `TypeError` when trying to use `@converse/headless`
|
||||
- #2789: Implement new hook `parseMessageForCommands` for plugins to add custom commands
|
||||
- #2814: Links are mangled on open/copy
|
||||
- #2822: Singleton doesn't work in overlayed view mode
|
||||
|
||||
- New config option [show_connection_url_input](https://conversejs.org/docs/html/configuration.html#show-connection-url-input)
|
||||
|
||||
## 9.0.0 (2021-11-26)
|
||||
|
||||
- Compress new avatar images before uploading them
|
||||
- Add initial support for XEP-0421 occupant Ids.
|
||||
- Use more specific types for form fields based on XEP-0122
|
||||
- Fix trimming of chats in overlayed view mode
|
||||
- OMEMO bugfix: Always create device session based on real JID.
|
||||
- If `auto_register_muc_nickname` is set, make sure to register when the user changes current nick.
|
||||
- #1322: Display occupants’ avatars in the occupants list
|
||||
- #1419: Clicking on avatar should show bigger version
|
||||
- #1426: Don't fetch member list if not affiliated
|
||||
- #2423: Could not find dependency "converse-controlbox" for plugin "converse-muc"
|
||||
- #2640: Add `beforeFetchLoginCredentials` hook
|
||||
- #2647: Singleton mode doesn't work
|
||||
- #2650: Clicking on occupant in sidebar should add nickname to textarea
|
||||
- #2683: Show error messages that don't refer to specific chat messages
|
||||
- #2704: Send button doesn't work in a multi-user chat
|
||||
- #2715: Singleton + fullscreen mode styling issue
|
||||
- #2718: Message is not displayed if it contains an invalid URL
|
||||
- #2725: Send new presence status to all connected MUCs
|
||||
- #2728: Not sending headers with upload request
|
||||
- #2733: OMEMO Messages received while client closed not decrypted
|
||||
|
||||
- Emit a `change` event when a configuration setting changes
|
||||
- 3 New configuration settings:
|
||||
- [render_media](https://conversejs.org/docs/html/configuration.html#render-media)
|
||||
- [allowed_audio_domains](https://conversejs.org/docs/html/configuration.html#allowed-audio-domains)
|
||||
- [allowed_video_domains](https://conversejs.org/docs/html/configuration.html#allowed-video-domains)
|
||||
- [allowed_image_domains](https://conversejs.org/docs/html/configuration.html#allowed-image-domains)
|
||||
|
||||
Three config settings have been obsoleted:
|
||||
- embed_audio
|
||||
- embed_video
|
||||
- show_images_inline
|
||||
- muc_show_ogp_unfurls
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
Configuration settings are no longer available on the `_converse` object.
|
||||
Instead, use `api.settings.get` and `api.settings.set`.
|
||||
|
||||
|
||||
## 8.0.1 (2021-09-09)
|
||||
|
||||
- #2326: 404 for asset /logo/conversejs-filled.svg
|
||||
- #2628: Open groupchats toggle emits an error
|
||||
- #2629: OMEMO button tooltip is wrong in private chat
|
||||
- #2633: Excessive logging of warning
|
||||
- #2634: Image previews not loading when not serving Converse locally
|
||||
- #2636: Don't fail when setting up a new XEP-0198 managed stream and `_converse.session` is undefined
|
||||
- Bugfix: Don't show minimized chats when logged out
|
||||
|
||||
## 8.0.0 (2021-09-03)
|
||||
|
||||
- Requires Node 12 or above
|
||||
|
||||
### Issues and features
|
||||
|
||||
- #1083: Add support for XEP-0393 Message Styling
|
||||
- #1182: Add support for XEP-0454 OMEMO Media sharing
|
||||
- #1823: New config options [mam_request_all_pages](https://conversejs.org/docs/html/configuration.html#mam-request-all-pages)
|
||||
- #2275: Allow punctuation to immediately precede a mention
|
||||
- #2348: `auto_join_room` not showing the room in `fullscreen` `view_mode`.
|
||||
- #2400: Fixes infinite loop bug when appending .png to allowed image urls
|
||||
- #2409: Integrate App Badging API for unread messages
|
||||
- #2464: New configuration setting [allow_url_history_change](https://conversejs.org/docs/html/configuration.html#allow-url-history-change)
|
||||
- #2497: Bugfix /nick command is not working
|
||||
- Add a Description Of A Project (DOAP) file
|
||||
- Add ability to deregister nickname when closing a MUC by setting `auto_register_muc_nickname` to `'unregister'`.
|
||||
- Add support for XEP-0437 Room Activity Indicators see [muc-subscribe-to-rai](https://conversejs.org/docs/html/configuration.html#muc-subscribe-to-rai)
|
||||
- Add support for rendering unfurls via [mod_ogp](https://modules.prosody.im/mod_ogp.html)
|
||||
- Bugfix: Connection protocol not updated based on XEP-0156 connection methods
|
||||
- Bugfix: Use real JID in XEP-0372 references only when the MUC is non-anonymous
|
||||
- Bugfix: `null` inserted by emoji picker and can't switch between skintones
|
||||
- File structure reordering: All plugins are now in `./plugins` folders.
|
||||
- Show a gap placeholder when there are gaps in the chat history. The user can click these to fill the gaps.
|
||||
- Use the MUC stanza id when sending XEP-0333 markers
|
||||
- Add support for pausing Gif images
|
||||
- Add limited support for XEP-0316 MUC notifications
|
||||
|
||||
### New configuration setings
|
||||
|
||||
- [show_tab_notifications](https://conversejs.org/docs/html/configuration.html#show-tab-notifications)
|
||||
- [muc_clear_messages_on_leave](https://conversejs.org/docs/html/configuration.html#muc-clear-messages-on-leave)
|
||||
- [send_chat_markers](https://conversejs.org/docs/html/configuration.html#send-chat-markers)
|
||||
- [muc_show_ogp_unfurls](https://conversejs.org/docs/html/configuration.html#muc-show-ogp-unfurls)
|
||||
- [prune-messages-above](https://conversejs.org/docs/html/configuration.html#prune-messages-above)
|
||||
- [pruning_behavior](https://conversejs.org/docs/html/configuration.html#pruning-behavior)
|
||||
|
||||
### New hooks and events
|
||||
|
||||
- New hook: [getMessageActionButtons](https://conversejs.org/docs/html/api/-_converse.html#event:getMessageActionButtons)
|
||||
- New hook: [shouldNotifyOfGroupMessage](https://conversejs.org/docs/html/api/-_converse.html#event:shouldNotifyOfGroupMessage)
|
||||
- New hook: [presenceConstructed](https://conversejs.org/docs/html/api/-_converse.html#event:presenceConstructed)
|
||||
- New event: [historyPruned](https://conversejs.org/docs/html/api/-_converse.html#event:historyPruned)
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
The default persistent store, set via the [persistent_store](https://conversejs.org/docs/html/configuration.html#persistent-store),
|
||||
is now IndexedDB. This main advantage of using IndexedDB is that it doesn't
|
||||
have a fixed size limit. We don't provide a tool to migrate data from
|
||||
localStorage to IndexedDB. For almost all data this is not a problem since
|
||||
the data can be fetched again from the XMPP server. However,
|
||||
decrypted OMEMO messages cannot be fetched again from the server, since the
|
||||
double ratchet makes it impossible to again decrypt them. This means your
|
||||
decrypted OMEMO history will be lost in the transition.
|
||||
|
||||
The [afterMessageBodyTransformed](https://conversejs.org/docs/html/api/-_converse.html#event:afterMessageBodyTransformed) and [beforeMessageBodyTransformed](https://conversejs.org/docs/html/api/-_converse.html#event:beforeMessageBodyTransformed) events now has a different signatures.
|
||||
When leaving a MUC, the message history is deleted. This means that decrypted
|
||||
OMEMO messages are gone and cannot be recovered on that device. See [muc_clear_messages_on_leave](https://conversejs.org/docs/html/configuration.html#muc-clear-messages-on-leave).
|
||||
|
||||
Removed events:
|
||||
* `bookmarkViewsInitialized`
|
||||
* `chatBoxInsertedIntoDOM`
|
||||
* `contactStatusMessageChanged`
|
||||
* `messageSend` (use `sendMessage` instead)
|
||||
* `rosterGroupsFetched`
|
||||
|
||||
The `chatBoxClosed`, `chatBoxMaximized` and `chatBoxMinimized` events now have the `model` as
|
||||
payload and not the `view`.
|
||||
|
||||
The `api.chatviews` and `api.roomviews` API groupings and methods have been
|
||||
removed. The original "views" don't really exist anymore, the UI is now composed web
|
||||
components which should update reactively based on changes made on the models.
|
||||
|
||||
## 7.0.6 (2021-06-11)
|
||||
|
||||
- #2500: Wrong assignment in OMEMO code
|
||||
|
||||
## 7.0.5 (2021-03-16)
|
||||
|
||||
- #2377: The @converse/headless NPM package is missing the dist directory, causing import errors
|
||||
- #2396: @converse/headless wrongly depends on `CustomElement` from the view layer
|
||||
- #2381: Converse does not reflect the browser language
|
||||
|
||||
## 7.0.4 (2020-12-09)
|
||||
|
||||
Bugfix: Set protocol after discovering connection methods
|
||||
|
||||
Otherwise if an endpoint was passed in with `converse.initialize`, then
|
||||
that endpoint's protocol is (potentially wrongly) used.
|
||||
|
||||
## 7.0.3 (2020-12-02)
|
||||
|
||||
- Bugfix: `null` inserted by emoji picker and can't switch between skintones
|
||||
|
||||
|
||||
## 7.0.2 (2020-11-23)
|
||||
|
||||
- Updated translations: de, nb, gl, tr
|
||||
- Still more necessary files not included in the 7.0.1 NPM package, causing `Module not found` errors.
|
||||
- #2337: Newly opened headline chat isn't hidden by default
|
||||
|
||||
## 7.0.1 (2020-11-19)
|
||||
|
||||
- Updated translations: de, es, fi, fr, gl, hu, nb_NO, oc, pl, pt, pt_BR, ru, tr, uk, zh
|
||||
- #2328: Honor `use_system_emojis` in emoji-picker
|
||||
- Not all *.js files were included in the 7.0.0 package, causing:
|
||||
- Not all template/*.js files were included in the 7.0.0 NPM package, causing:
|
||||
`Module not found: Error: Can't resolve 'templates/*.js'`
|
||||
|
||||
## 7.0.0 (2020-11-18)
|
||||
@ -12,6 +288,7 @@
|
||||
configuration settings should now be accessed via `_converse.api.settings.get` and not directly on the `_converse` object.
|
||||
Soon we'll deprecate the latter, so prepare now.
|
||||
|
||||
- #515 Add support for XEP-0050 Ad-Hoc commands
|
||||
- #2231: add sort_by_query and remove sort_by_length
|
||||
- #1313: Stylistic improvements to the send button
|
||||
- #1481: MUC OMEMO: Error No record for device
|
||||
@ -21,7 +298,6 @@ Soon we'll deprecate the latter, so prepare now.
|
||||
- #1793: Send button doesn't appear in Firefox in 1:1 chats
|
||||
- #1820: Set focus on jid field after controlbox is loaded
|
||||
- #1822: Don't log error if user has no bookmarks
|
||||
- #515 Add support for XEP-0050 Ad-Hoc commands
|
||||
- #1823: New config options [muc_roomid_policy](https://conversejs.org/docs/html/configuration.html#muc-roomid-policy)
|
||||
and [muc_roomid_policy_hint](https://conversejs.org/docs/html/configuration.html#muc-roomid-policy-hint)
|
||||
- #1826: A user can now add himself as a contact
|
||||
@ -41,6 +317,7 @@ Soon we'll deprecate the latter, so prepare now.
|
||||
- #2213: added CustomElement to converse.env
|
||||
- #2220: fix rendering of emojis in case `use_system_emojis == false` (again).
|
||||
- #2092: fixes room list update loop when having the `locked_muc_domain` truthy or `'hidden'`
|
||||
- #2259: Rename configuration setting `muc_show_join_leave` to `muc_show_info_messages`. Now accepts a list of events to show instead of a boolean.
|
||||
- #2285: Rename config option `muc_hats_from_vcard` to [muc_hats](https://conversejs.org/docs/html/configuration.html#muc-hats). Now accepts a list instead of a boolean and allows for more flexible choices regarding user badges.
|
||||
- #2300: Fix message reorder issue after message correction.
|
||||
- #2304: Custom emojis (stickers) images not shown
|
||||
@ -48,6 +325,7 @@ Soon we'll deprecate the latter, so prepare now.
|
||||
- #2308: Allow getHats method to be overriden in the `overrides` object in plugins.
|
||||
- #2321: When Converse runs inside a browser extension, enable browser sync and local storage for persistent storage
|
||||
- #1250: Change favicon color when unread messages
|
||||
- Updated translations: de, es, fi, fr, gl, hu, nb_NO, oc, pl, pt, pt_BR, ru, tr, uk, zh
|
||||
- The `trusted` configuration setting has been removed in favor of two new settings:
|
||||
[allow_user_trust_override](https://conversejs.org/docs/html/configuration.html#allow-user-trust-override)
|
||||
[clear_cache_on_logout](https://conversejs.org/docs/html/configuration.html#clear-cache-on-logout)
|
||||
@ -79,7 +357,7 @@ Soon we'll deprecate the latter, so prepare now.
|
||||
|
||||
## 6.0.0 (2020-01-09)
|
||||
|
||||
- [enable_smacks](https://conversejs.org/docs/html/configuration.html#enable-smacks) is not set to `true` by default.
|
||||
- [enable_smacks](https://conversejs.org/docs/html/configuration.html#enable-smacks) is now set to `true` by default.
|
||||
- Refactor some presence and status handling code from `converse-core` into `@converse/headless/converse-status`.
|
||||
- It's now possible to navigate the emoji-picker via the keyboard arrow keys.
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
*
|
||||
* An XMPP chat client that runs in the browser.
|
||||
*
|
||||
* Version: 7.0.1
|
||||
* Version: 10.1.6
|
||||
*
|
||||
* Copyright: JC Brand 2013-2018
|
||||
* Except for 3rd party dependencies.
|
||||
|
119
Makefile
@ -1,22 +1,18 @@
|
||||
# You can set these variables from the command line.
|
||||
BABEL ?= node_modules/.bin/babel
|
||||
BOOTSTRAP = ./node_modules/
|
||||
BUILDDIR = ./docs
|
||||
KARMA ?= ./node_modules/.bin/karma
|
||||
CHROMIUM ?= ./node_modules/.bin/run-headless-chromium
|
||||
CLEANCSS ?= ./node_modules/clean-css-cli/bin/cleancss --skip-rebase
|
||||
ESLINT ?= ./node_modules/.bin/eslint
|
||||
CLEANCSS ?= ./node_modules/clean-css-cli/bin/cleancss
|
||||
HTTPSERVE ?= ./node_modules/.bin/http-server
|
||||
HTTPSERVE_PORT ?= 8000
|
||||
INKSCAPE ?= inkscape
|
||||
INSTALL ?= install
|
||||
JSDOC ?= ./node_modules/.bin/jsdoc
|
||||
LERNA ?= ./node_modules/.bin/lerna
|
||||
OXIPNG ?= oxipng
|
||||
PAPER =
|
||||
RJS ?= ./node_modules/.bin/r.js
|
||||
NPX ?= ./node_modules/.bin/npx
|
||||
SASS ?= ./node_modules/.bin/node-sass
|
||||
SASS ?= ./node_modules/.bin/sass
|
||||
SED ?= sed
|
||||
SPHINXBUILD ?= ./bin/sphinx-build
|
||||
SPHINXOPTS =
|
||||
@ -62,17 +58,19 @@ serve: node_modules dist
|
||||
serve_bg: node_modules
|
||||
$(HTTPSERVE) -p $(HTTPSERVE_PORT) -c-1 -s &
|
||||
|
||||
certs:
|
||||
mkdir certs
|
||||
cd certs && openssl req -newkey rsa:4096 -x509 -sha256 -days 365 -nodes -out chat.example.org.crt -keyout chat.example.org.key
|
||||
|
||||
########################################################################
|
||||
## Translation machinery
|
||||
|
||||
dist/converse-no-dependencies.js: src webpack.common.js webpack.nodeps.js @converse/headless node_modules
|
||||
npm run nodeps
|
||||
|
||||
GETTEXT = $(XGETTEXT) --from-code=UTF-8 --language=JavaScript --keyword=__ --keyword=___ --keyword=i18n_ --force-po --output=src/i18n/converse.pot --package-name=Converse.js --copyright-holder="Jan-Carel Brand" --package-version=7.0.1 dist/converse-no-dependencies.js -c
|
||||
GETTEXT = $(XGETTEXT) --from-code=UTF-8 --language=JavaScript --keyword=__ --keyword=___ --keyword=i18n_ --force-po --output=src/i18n/converse.pot --package-name=Converse.js --copyright-holder="Jan-Carel Brand" --package-version=10.1.6 dist/converse-no-dependencies.js -c
|
||||
|
||||
src/i18n/converse.pot: dist/converse-no-dependencies.js
|
||||
$(GETTEXT) 2>&1 > /dev/null; exit $$?;
|
||||
rm dist/converse-no-dependencies.js
|
||||
rm dist/tmp.css
|
||||
|
||||
.PHONY: pot
|
||||
pot: src/i18n/converse.pot
|
||||
@ -84,9 +82,9 @@ po:
|
||||
########################################################################
|
||||
## Release management
|
||||
|
||||
.PHONY: release
|
||||
release:
|
||||
$(SED) -i '/^_converse.VERSION_NAME =/s/=.*/= "v$(VERSION)";/' src/headless/converse-core.js
|
||||
.PHONY: version
|
||||
version:
|
||||
$(SED) -i '/^export const VERSION_NAME =/s/=.*/= "v$(VERSION)";/' src/headless/shared/constants.js
|
||||
$(SED) -i '/Version:/s/:.*/: $(VERSION)/' COPYRIGHT
|
||||
$(SED) -i '/Project-Id-Version:/s/:.*/: Converse.js $(VERSION)\n"/' src/i18n/converse.pot
|
||||
$(SED) -i '/"version":/s/:.*/: "$(VERSION)",/' manifest.json
|
||||
@ -101,25 +99,47 @@ release:
|
||||
make pot
|
||||
make po
|
||||
make dist
|
||||
npm pack
|
||||
|
||||
release-checkout:
|
||||
git clone git@github.com:conversejs/converse.js.git --depth 1 --branch $(BRANCH) release-$(BRANCH)
|
||||
cd release-$(BRANCH) && make dist
|
||||
|
||||
.PHONY: publish
|
||||
publish:
|
||||
make release-checkout
|
||||
cd release-$(BRANCH) && npm pack && npm publish
|
||||
cd release-$(BRANCH)/src/headless && npm pack && npm publish
|
||||
find ./release-$(BRANCH)/ -name "converse.js-*.tgz" -exec mv {} . \;
|
||||
find ./release-$(BRANCH)/src/headless -name "converse-headless-*.tgz" -exec mv {} . \;
|
||||
rm -rf release-$(BRANCH)
|
||||
|
||||
.PHONY: postrelease
|
||||
postrelease:
|
||||
$(SED) -i '/^_converse.VERSION_NAME =/s/=.*/= "v$(VERSION)dev";/' src/headless/converse-core.js
|
||||
$(SED) -i '/^export const VERSION_NAME =/s/=.*/= "v$(VERSION)dev";/' src/headless/shared/constants.js
|
||||
|
||||
.PHONY: deploy
|
||||
deploy:
|
||||
git clone --branch v$(VERSION) git@github.com:conversejs/converse.js.git --depth 1 $(VERSION)
|
||||
cd $(VERSION) && make node && ASSET_PATH=https://cdn.conversejs.org/$(VERSION)/dist/ make dist && make doc
|
||||
cd .. && git pull && make node && ASSET_PATH=https://cdn.conversejs.org/dist/ make dist && make doc
|
||||
|
||||
########################################################################
|
||||
## Install dependencies
|
||||
|
||||
$(LERNA):
|
||||
npm install lerna
|
||||
${NVM_DIR}/nvm.sh:
|
||||
wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.38.0/install.sh | bash
|
||||
source ~/.bashrc
|
||||
|
||||
package-lock.json: package.json
|
||||
.PHONY: nvm
|
||||
nvm: ${NVM_DIR}/nvm.sh
|
||||
|
||||
.PHONY: node
|
||||
node: .nvmrc
|
||||
. $(HOME)/.nvm/nvm.sh && nvm install
|
||||
|
||||
node_modules: package.json src/headless/package.json
|
||||
npm install
|
||||
|
||||
node_modules: $(LERNA) package.json package-lock.json src/headless/package.json src/headless/package-lock.json
|
||||
npm run lerna
|
||||
npm rebuild node-sass
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
npm run clean
|
||||
@ -136,14 +156,17 @@ devserver: node_modules
|
||||
########################################################################
|
||||
## Builds
|
||||
|
||||
dist/converse-no-dependencies.js: src webpack/webpack.common.js webpack/webpack.nodeps.js @converse/headless node_modules
|
||||
npm run nodeps
|
||||
|
||||
dist/converse.js:: node_modules
|
||||
npm run dev
|
||||
npm run build
|
||||
|
||||
dist/converse.css:: node_modules
|
||||
npm run dev
|
||||
npm run build
|
||||
|
||||
dist/website.css:: node_modules sass
|
||||
$(SASS) --source-map true --include-path $(BOOTSTRAP) sass/website.scss $@
|
||||
dist/website.css:: node_modules src/shared/styles/website.scss
|
||||
$(SASS) --load-path=$(BOOTSTRAP) src/shared/styles/website.scss $@
|
||||
|
||||
dist/website.min.css:: node_modules dist/website.css
|
||||
$(CLEANCSS) dist/website.css > $@
|
||||
@ -174,11 +197,24 @@ logo/conversejs-filled%.png:: logo/conversejs-filled.svg
|
||||
|
||||
@converse/headless: src/headless
|
||||
|
||||
src/headless/dist/converse-headless.min.js: src webpack.common.js node_modules @converse/headless
|
||||
src/headless/dist/converse-headless.js: src webpack/webpack.common.js node_modules @converse/headless
|
||||
npm run headless-dev
|
||||
|
||||
src/headless/dist/converse-headless.min.js: src webpack/webpack.common.js node_modules @converse/headless
|
||||
npm run headless
|
||||
|
||||
dist:: node_modules src/* | dist/converse.js dist/converse.css dist/website.css dist/website.min.css
|
||||
npm run prod
|
||||
dist:: node_modules src/* | dist/website.css dist/website.min.css
|
||||
npm run headless
|
||||
# Ideally this should just be `npm run build`.
|
||||
# The additional steps are necessary to properly generate JSON chunk files
|
||||
# from the .po files. The nodeps config uses preset-env with IE11.
|
||||
# Somehow this is necessary.
|
||||
npm run nodeps
|
||||
$(eval TMPD := $(shell mktemp -d))
|
||||
mv dist/locales $(TMPD) && \
|
||||
npm run build && \
|
||||
mv $(TMPD)/locales/*-po.js dist/locales/ && \
|
||||
rm -rf $(TMPD)
|
||||
|
||||
.PHONY: install
|
||||
install:: dist
|
||||
@ -187,24 +223,24 @@ install:: dist
|
||||
cdn:: node_modules
|
||||
npm run cdn
|
||||
|
||||
.PHONY: types
|
||||
types:: node_modules
|
||||
npm run types
|
||||
|
||||
########################################################################
|
||||
## Tests
|
||||
|
||||
.PHONY: eslint
|
||||
eslint: node_modules
|
||||
$(ESLINT) src/*.js
|
||||
$(ESLINT) src/utils/*.js
|
||||
$(ESLINT) src/headless/*.js
|
||||
$(ESLINT) src/headless/utils/*.js
|
||||
$(ESLINT) spec/ --global converse
|
||||
npm run lint
|
||||
|
||||
.PHONY: check
|
||||
check: eslint | dist/converse.js dist/converse.css
|
||||
$(KARMA) start karma.conf.js $(ARGS)
|
||||
npm run test -- $(ARGS)
|
||||
|
||||
.PHONY: test
|
||||
test:
|
||||
$(KARMA) start karma.conf.js $(ARGS)
|
||||
npm run test -- $(ARGS)
|
||||
|
||||
########################################################################
|
||||
## Documentation
|
||||
@ -212,13 +248,10 @@ test:
|
||||
./bin/activate:
|
||||
python3 -m venv .
|
||||
|
||||
.installed.cfg: requirements.txt buildout.cfg
|
||||
.PHONY: docsdev
|
||||
docsdev: ./bin/activate requirements.txt
|
||||
./bin/pip install --upgrade pip==21.3.1
|
||||
./bin/pip install -r requirements.txt
|
||||
./bin/pip install --upgrade pip==19.2.1
|
||||
./bin/pip install --upgrade setuptools==41.0.1
|
||||
./bin/buildout -v
|
||||
|
||||
docsdev: ./bin/activate .installed.cfg
|
||||
|
||||
.PHONY: html
|
||||
html: doc
|
||||
@ -233,4 +266,4 @@ doc: node_modules docsdev apidoc
|
||||
|
||||
PHONY: apidoc
|
||||
apidoc:
|
||||
$(JSDOC) --private --readme docs/source/jsdoc_intro.md -c docs/source/conf.json -d docs/html/api src/templates/directives/*.js src/components/*.js src/*.js src/utils/*.js src/headless/*.js src/headless/utils/*.js
|
||||
find ./src -type d -name node_modules -prune -false -o -name "*.js" | xargs $(JSDOC) --private --readme docs/source/jsdoc_intro.md -c docs/source/conf.json -d docs/html/api
|
||||
|
17
README.chapril.md
Normal file
@ -0,0 +1,17 @@
|
||||
# Construire une version Chapril de ConverseJS
|
||||
|
||||
```
|
||||
cd .../conversejs
|
||||
# La première fois, installer nvm (attention, ça va modifier le .bashrc, entre autres choses)
|
||||
make nvm
|
||||
|
||||
export V=7.0.4
|
||||
git rebase v${V?}
|
||||
# [... Résoudre les conflits]
|
||||
git checkout -b v${V?}-chapril
|
||||
nvm install
|
||||
make dist
|
||||
# [... Tester les livrables présents dans dist/, et si tout est ok :]
|
||||
make version VERSION=${V?}-chapril
|
||||
rsync -av dist/ chapril-xmpp:/var/www/xmpp.chapril.org/public_html/dist-custom-chapril-${V?}/
|
||||
```
|
55
README.md
@ -5,8 +5,8 @@
|
||||
</h2>
|
||||
|
||||
|
||||
[![XMPP Chat](https://inverse.chat/badge.svg?room=discuss@conference.conversejs.org)](https://inverse.chat/#converse/room?jid=discuss@conference.conversejs.org)
|
||||
[![Travis](https://api.travis-ci.org/conversejs/converse.js.png?branch=master)](https://travis-ci.org/conversejs/converse.js)
|
||||
[![XMPP Chat](https://conference.conversejs.org/muc_badge/discuss@conference.conversejs.org)](https://inverse.chat/#converse/room?jid=discuss@conference.conversejs.org)
|
||||
[![CI Tests](https://github.com/conversejs/converse.js/actions/workflows/karma-tests.yml/badge.svg)](https://github.com/conversejs/converse.js/actions/workflows/karma-tests.yml)
|
||||
[![Bountysource bounties](https://img.shields.io/bountysource/team/converse.js/activity.svg?maxAge=2592000)](https://www.bountysource.com/teams/converse.js/issues?tracker_ids=194169)
|
||||
[![Translation status](https://hosted.weblate.org/widgets/conversejs/-/svg-badge.svg)](https://hosted.weblate.org/engage/conversejs/?utm_source=widget)
|
||||
|
||||
@ -40,19 +40,23 @@ which shows you how to use the CDN (content delivery network) to quickly get a d
|
||||
|
||||
In overlay mode, Converse appears overlayed chats on top of the website.
|
||||
|
||||
![Screenshot of Converse in overlay mode](https://opkode.com/img/Screen-Shot-2018-09-19-at-19.15.16.png)
|
||||
![Screenshot of Converse in overlay mode](https://conversejs.org/screenshots/Converse-overlayed.png)
|
||||
|
||||
### Fullpage
|
||||
|
||||
In fullpage mode, Converse behaves like a single-page app that covers the whole browser viewport.
|
||||
|
||||
![Screenshot of Converse in fullpage mode](https://opkode.com/img/Screen-Shot-2018-09-19-at-19.16.46.png)
|
||||
![Screenshot of Converse 9.0.0 in fullpage mode](https://conversejs.org/screenshots/Converse-fullscreen.png)
|
||||
|
||||
### Dark mode
|
||||
|
||||
![Screenshot of Converse 9.1.0 with a dark theme](https://conversejs.org/screenshots/Converse-Dracula-Theme.png)
|
||||
|
||||
### Embedded
|
||||
|
||||
In embedded mode, Converse can be embedded into an element in the DOM.
|
||||
|
||||
![Screenshot of Converse in embedded mode](https://opkode.com/img/Converse-embedded.png)
|
||||
![Screenshot of Converse in embedded mode](https://conversejs.org/screenshots/Converse-embedded.png)
|
||||
|
||||
## Features
|
||||
- Available as overlayed chat boxes or as a fullscreen application. See [inverse.chat](https://inverse.chat) for the fullscreen version.
|
||||
@ -61,6 +65,7 @@ In embedded mode, Converse can be embedded into an element in the DOM.
|
||||
- A [plugin architecture](https://conversejs.org/docs/html/plugin_development.html) based on [pluggable.js](https://conversejs.github.io/pluggable.js/)
|
||||
- Chat statuses (online, busy, away, offline)
|
||||
- Anonymous logins, see the [anonymous login demo](https://conversejs.org/demo/anonymous.html)
|
||||
- URL Previews (requires server support, for example [mod_ogp](https://modules.prosody.im/mod_ogp.html)
|
||||
- Translated into over 30 languages
|
||||
|
||||
### Supported XMPP Extensions
|
||||
@ -77,6 +82,7 @@ In embedded mode, Converse can be embedded into an element in the DOM.
|
||||
- [XEP-0066](https://xmpp.org/extensions/xep-0066.html) Out of Band Data
|
||||
- [XEP-0077](https://xmpp.org/extensions/xep-0077.html) In-band registration
|
||||
- [XEP-0085](https://xmpp.org/extensions/xep-0085.html) Chat State Notifications
|
||||
- [XEP-0115](https://xmpp.org/extensions/xep-0115.html) Entity Capabilities
|
||||
- [XEP-0124](https://xmpp.org/extensions/xep-0124.html) Bidirectional-streams Over Synchronous HTTP (BOSH)
|
||||
- [XEP-0144](https://xmpp.org/extensions/xep-0144.html) Roster item exchange
|
||||
- [XEP-0156](https://xmpp.org/extensions/xep-0156.html) Discovering Alternative XMPP Connection Methods
|
||||
@ -92,6 +98,7 @@ In embedded mode, Converse can be embedded into an element in the DOM.
|
||||
- [XEP-0297](https://xmpp.org/extensions/xep-0297.html) Stanza Forwarding (limited support)
|
||||
- [XEP-0308](https://xmpp.org/extensions/xep-0308.html) Last Message Correction
|
||||
- [XEP-0313](https://xmpp.org/extensions/xep-0313.html) Message Archive Management
|
||||
- [XEP-0316](https://xmpp.org/extensions/xep-0316.html) MUC Eventing protocol (limited support)
|
||||
- [XEP-0317](https://xmpp.org/extensions/xep-0317.html) Hats (limited support)
|
||||
- [XEP-0333](https://xmpp.org/extensions/xep-0333.html) Chat Markers (limited support)
|
||||
- [XEP-0352](https://xmpp.org/extensions/xep-0352.html) Client State Indication
|
||||
@ -101,21 +108,30 @@ In embedded mode, Converse can be embedded into an element in the DOM.
|
||||
- [XEP-0372](https://xmpp.org/extensions/xep-0372.html) References
|
||||
- [XEP-0382](https://xmpp.org/extensions/xep-0382.html) Spoiler messages
|
||||
- [XEP-0384](https://xmpp.org/extensions/xep-0384.html) OMEMO Encryption
|
||||
- [XEP-0393](https://xmpp.org/extensions/xep-0393.html) Message styling
|
||||
- [XEP-0422](https://xmpp.org/extensions/xep-0422.html) Message Fastening (limited support)
|
||||
- [XEP-0424](https://xmpp.org/extensions/xep-0424.html) Message Retractions
|
||||
- [XEP-0425](https://xmpp.org/extensions/xep-0425.html) Message Moderation
|
||||
|
||||
- [XEP-0437](https://xmpp.org/extensions/xep-0437.html) Room Activity Indicators
|
||||
- [XEP-0453](https://xmpp.org/extensions/xep-0453.html) DOAP Usage in XMPP
|
||||
- [XEP-0454](https://xmpp.org/extensions/xep-0454.html) OMEMO Media sharing
|
||||
|
||||
## Integration into other servers and frameworks
|
||||
|
||||
### XMPP servers
|
||||
|
||||
- **[Openfire](https://www.igniterealtime.org/projects/openfire/index.jsp)**: [inverse.jar](https://www.igniterealtime.org/projects/openfire/plugins.jsp)
|
||||
- **[Prosody](https://prosody.im/)**: [mod_conversejs](https://modules.prosody.im/mod_conversejs.html)
|
||||
- **[Ejabberd](https://ejabberd.im/)**: [mod-conversejs](https://docs.ejabberd.im/admin/configuration/modules/#mod-conversejs)
|
||||
|
||||
### Other
|
||||
|
||||
- **[Alfresco](https://www.alfresco.com)**: [alfresco-js-chat-share](https://github.com/keensoft/alfresco-js-chat-share)
|
||||
- **[Django](https://www.djangoproject.com)**: [django-conversejs](https://pypi.python.org/pypi/django-conversejs) or [django-xmpp](https://github.com/fpytloun/django-xmpp)
|
||||
- **[Elgg](https://elgg.org)**: [plugin](https://elgg.org/plugins/2997196)
|
||||
- **[Friendica](https://friendi.ca)**: [converse](https://github.com/friendica/friendica-addons/tree/master/xmpp/converse)
|
||||
- **[Openfire](https://www.igniterealtime.org/projects/openfire/index.jsp)**: [inverse.jar](https://www.igniterealtime.org/projects/openfire/plugins.jsp)
|
||||
- **[Patternslib](http://patternslib.com)**: [patterns.converse](https://github.com/jcbrand/patterns.converse)
|
||||
- **[Plone](https://plone.com)**: [collective.converse](https://github.com/collective/collective.converse)
|
||||
- **[Prosody](https://prosody.im/)**: [mod_conversejs](https://modules.prosody.im/mod_conversejs.html)
|
||||
- **[Pàdé](https://www.igniterealtime.org/projects/pade/index.jsp)**: [Pàdé](https://www.igniterealtime.org/projects/pade/index.jsp)
|
||||
- **[Roundcube](https://roundcube.net)**: [roundcube-converse.js-xmpp-plugin](https://github.com/devurandom/roundcube-converse.js-xmpp-plugin)
|
||||
- **[Ruby on Rails](https://rubyonrails.org)**: [conversejs-rails](https://github.com/mikemarsian/conversejs-rails)
|
||||
@ -147,3 +163,26 @@ A heartfelt thanks for everyone who has supported this project over the years.
|
||||
Many people have contributed testing, bugfixes, features and corrections.
|
||||
|
||||
We accept donations via [Patreon](https://www.patreon.com/jcbrand) and [Liberapay](https://liberapay.com/jcbrand).
|
||||
|
||||
## Sponsors
|
||||
|
||||
<p>
|
||||
<a href="https://bairesdev.com/sponsoring-open-source-projects/?utm_source=conversejs" target="_blank" rel="noopener">
|
||||
<img alt="BairesDev" src="https://raw.githubusercontent.com/conversejs/media/main/logos/bairesdev-primary.png" width="200">
|
||||
</a>
|
||||
</p>
|
||||
<p>
|
||||
<a href="https://blokt.com?utm_source=conversejs" target="_blank" rel="noopener">
|
||||
<img alt="Blokt Crypto & Privacy" src="https://raw.githubusercontent.com/conversejs/converse.js/541613d1fea8aef364af00180f60e959162e5e4b/logo/blokt.png" width="200">
|
||||
</a>
|
||||
</p>
|
||||
<p>
|
||||
<a href="https://primesound.org/?utm_source=conversejs" target="_blank" rel="noopener">
|
||||
<img alt="Prime Sound" src="https://raw.githubusercontent.com/conversejs/media/main/logos/primesound.png" width="200">
|
||||
</a>
|
||||
</p>
|
||||
<p>
|
||||
<a href="https://www.keycdn.com?utm_source=conversejs" target="_blank" rel="noopener">
|
||||
<img alt="KeyCDN" src="https://raw.githubusercontent.com/conversejs/converse.js/541613d1fea8aef364af00180f60e959162e5e4b/logo/keycdn.png" width="200">
|
||||
</a>
|
||||
</p>
|
||||
|
26
RELEASE.md
@ -1,20 +1,18 @@
|
||||
# Release checklist
|
||||
|
||||
1. Check that weblate translations are all merged in
|
||||
1. Merge weblate translations: https://hosted.weblate.org/projects/conversejs/translations/#repository
|
||||
2. Run `make check` to check that all tests pass.
|
||||
3. Run `make release VERSION=7.0.1`
|
||||
3. Run `make version VERSION=10.1.6`
|
||||
4. Do a `git diff` to check if things look sane.
|
||||
5. Do a quick manual test with the `dist` files (via `index.html`)
|
||||
6. `git commit -am "Release 7.0.1"`
|
||||
7. `git tag -s v7.0.1 -m "Release 7.0.1"`
|
||||
8. Run `git push && git push --tags`
|
||||
9. Update https://conversejs.org
|
||||
* `cd /home/conversejs/converse.js`
|
||||
* `git clone --branch v7.0.1 git@github.com:conversejs/converse.js.git 7.0.1`
|
||||
* `cd 7.0.1 && ASSET_PATH=https://cdn.conversejs.org/7.0.1/dist/ make dist && make doc`
|
||||
* `cd .. && git pull && ASSET_PATH=https://cdn.conversejs.org/dist/ make dist && make doc`
|
||||
6. `git commit -am "Release 10.1.6"`
|
||||
7. `git tag -s v10.1.6 -m "Release 10.1.6"`
|
||||
8. `git push && git push origin v10.1.6`
|
||||
9. `make publish BRANCH=v10.1.6`
|
||||
10. Update release page on Github
|
||||
11. Run `npm pack` to generate tarballs and upload them to the Github release page
|
||||
12. Run `npm publish && cd src/headless/ && npm publish`
|
||||
13. Update the repository on weblate
|
||||
14. Decide on next release number and run `make postrelease VERSION=7.0.2`
|
||||
* Upload tar files
|
||||
11. Update https://conversejs.org
|
||||
* `cd /home/conversejs/converse.js`
|
||||
* `make deploy VERSION=10.1.6`
|
||||
12. Update the repository on weblate
|
||||
13. Decide on next release number and run `make postrelease VERSION=10.1.7`
|
||||
|
10
babel.config.json
Normal file
@ -0,0 +1,10 @@
|
||||
{
|
||||
"presets": [
|
||||
["@babel/preset-env", {
|
||||
"targets": {
|
||||
"browsers": [">1%", "not ie 11", "not op_mini all", "not dead"]
|
||||
}
|
||||
}]
|
||||
],
|
||||
"plugins": []
|
||||
}
|
15
buildout.cfg
@ -1,15 +0,0 @@
|
||||
[buildout]
|
||||
parts =
|
||||
sphinx
|
||||
|
||||
versions = versions
|
||||
|
||||
[sphinx]
|
||||
recipe = zc.recipe.egg
|
||||
eggs =
|
||||
Sphinx
|
||||
sphinx-bootstrap-theme
|
||||
|
||||
[versions]
|
||||
Sphinx = 2.1.2
|
||||
docutils = 0.15.2
|
@ -1,23 +0,0 @@
|
||||
# How to use saved Chrome/Chromium logs to replay events
|
||||
|
||||
**NOTE**: This feature is very experimental and in many cases doesn't work
|
||||
without data massaging and ugly hacks.
|
||||
|
||||
It's possible to save the log output from Chrome/Chromium (I haven't tried this
|
||||
yet with any other browser) and then to replay that log output in the browser.
|
||||
|
||||
This can be a very helpful technique to track down bugs.
|
||||
|
||||
To do this, follow the following steps:
|
||||
|
||||
1. Save the log file (right click and then click "Save as" in the browser's console).
|
||||
2. Rename the log file, making sure it ends in `.html`
|
||||
3. Move the log file to the `converse-logs` directory in the converse.js repo.
|
||||
4. Add `<log>` to the top of the log file and `</log>` to the bottom of the log file.
|
||||
5. In `converse-logs/converse-logs.js`, add a new entry for the log file (don't
|
||||
include the `.html` part of the file name.
|
||||
6. Make sure that `spec/transcripts` is "required"-ed in `tests/main.js`
|
||||
6. Open `tests.html` in your browser.
|
||||
|
||||
Your logs will run first, and then all the other tests will run afterwards.
|
||||
|
@ -1,5 +0,0 @@
|
||||
define("transcripts", [
|
||||
"tpl!../../converse-logs/missing_messages",
|
||||
], function () {
|
||||
return arguments;
|
||||
});
|
293
conversejs.doap
Normal file
@ -0,0 +1,293 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<rdf:RDF xmlns:doap="http://usefulinc.com/ns/doap#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xmpp="https://linkmauve.fr/ns/xmpp-doap#" xmlns:schema="https://schema.org/" xml:lang="en">
|
||||
<Project xmlns="http://usefulinc.com/ns/doap#">
|
||||
<name>Converse.js</name>
|
||||
<shortdesc>Browser based XMPP chat client</shortdesc>
|
||||
<homepage rdf:resource="https://conversejs.org/"/>
|
||||
<bug-database rdf:resource="https://github.com/conversejs/converse.js/issues"/>
|
||||
<developer-forum rdf:resource="xmpp:discuss@conference.conversejs.org?join"/>
|
||||
<support-forum rdf:resource="xmpp:discuss@conference.conversejs.org?join"/>
|
||||
<category rdf:resource="https://linkmauve.fr/ns/xmpp-doap#category-client"/>
|
||||
<programming-language>JavaScript</programming-language>
|
||||
<os>Browser</os>
|
||||
<os>Linux</os>
|
||||
<os>macOS</os>
|
||||
<os>Windows</os>
|
||||
<schema:logo rdf:resource="https://raw.githubusercontent.com/conversejs/converse.js/master/logo/conversejs-filled.svg"/>
|
||||
<repository>
|
||||
<GitRepository>
|
||||
<browse rdf:resource="https://github.com/conversejs/converse.js"/>
|
||||
<location rdf:resource="https://github.com/conversejs/converse.js.git"/>
|
||||
</GitRepository>
|
||||
</repository>
|
||||
<implements rdf:resource="https://www.rfc-editor.org/info/rfc6120"/>
|
||||
<implements rdf:resource="https://www.rfc-editor.org/info/rfc6121"/>
|
||||
<implements rdf:resource="https://www.rfc-editor.org/info/rfc6122"/>
|
||||
<implements rdf:resource="https://www.rfc-editor.org/info/rfc7395"/>
|
||||
<implements rdf:resource="https://www.rfc-editor.org/info/rfc7590"/>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0004.html"/>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0030.html"/>
|
||||
<xmpp:since>0.8.2</xmpp:since>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0045.html"/>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0048.html"/>
|
||||
<xmpp:since>2.0.1</xmpp:since>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0050.html"/>
|
||||
<xmpp:since>7.0.0</xmpp:since>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0054.html"/>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0059.html"/>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0060.html"/>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0066.html"/>
|
||||
<xmpp:since>4.0.0</xmpp:since>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0077.html"/>
|
||||
<xmpp:since>0.8.5</xmpp:since>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0085.html"/>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0115.html"/>
|
||||
<xmpp:status>partial</xmpp:status>
|
||||
<xmpp:note>advertises caps but no caching</xmpp:note>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0122.html"/>
|
||||
<xmpp:status>partial</xmpp:status>
|
||||
<xmpp:note>basic string field sub-type usage</xmpp:note>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0124.html"/>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0144.html"/>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0156.html"/>
|
||||
<xmpp:since>6.0.0</xmpp:since>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0163.html"/>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0184.html"/>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0198.html"/>
|
||||
<xmpp:since>5.0.0</xmpp:since>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0199.html"/>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0203.html"/>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0206.html"/>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0245.html"/>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0249.html"/>
|
||||
<xmpp:since>0.8.2</xmpp:since>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0280.html"/>
|
||||
<xmpp:since>0.8.0</xmpp:since>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0297.html"/>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0308.html"/>
|
||||
<xmpp:since>4.0.0</xmpp:since>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0313.html"/>
|
||||
<xmpp:since>0.9.5</xmpp:since>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0317.html"/>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0319.html"/>
|
||||
<xmpp:since>4.0.5</xmpp:since>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0333.html"/>
|
||||
<xmpp:since>4.1.1</xmpp:since>
|
||||
<xmpp:status>partial</xmpp:status>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0352.html"/>
|
||||
<xmpp:since>0.9.4</xmpp:since>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0357.html"/>
|
||||
<xmpp:since>4.0.0</xmpp:since>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0359.html"/>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0363.html"/>
|
||||
<xmpp:since>4.0.0</xmpp:since>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0371.html"/>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0372.html"/>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0382.html"/>
|
||||
<xmpp:since>3.3.3</xmpp:since>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0384.html"/>
|
||||
<xmpp:since>4.0.0</xmpp:since>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0393.html"/>
|
||||
<xmpp:since>8.0.0</xmpp:since>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0410.html"/>
|
||||
<xmpp:since>5.0.0</xmpp:since>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0421.html"/>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0422.html"/>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0424.html"/>
|
||||
<xmpp:since>6.0.0</xmpp:since>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0425.html"/>
|
||||
<xmpp:since>6.0.0</xmpp:since>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0437.html"/>
|
||||
<xmpp:since>8.0.0</xmpp:since>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
<implements>
|
||||
<xmpp:SupportedXep>
|
||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0454.html"/>
|
||||
<xmpp:since>8.0.0</xmpp:since>
|
||||
</xmpp:SupportedXep>
|
||||
</implements>
|
||||
</Project>
|
||||
</rdf:RDF>
|
@ -10,20 +10,20 @@
|
||||
<meta name="keywords" content="xmpp chat webchat converse.js Converse" />
|
||||
|
||||
<!-- These files are NOT needed when using converse.js in your own project. -->
|
||||
<link rel="shortcut icon" type="image/ico" href="/dist/favicon.ico"/>
|
||||
<link type="text/css" rel="stylesheet" media="screen" href="/dist/website.min.css" />
|
||||
<noscript><p><img src="//stats.opkode.com/piwik.php?idsite=1" style="border:0;" alt="" /></p></noscript>
|
||||
<script type="text/javascript" src="analytics.js"></script>
|
||||
<link rel="shortcut icon" type="image/ico" href="../dist/favicon.ico"/>
|
||||
<link type="text/css" rel="stylesheet" media="screen" href="../dist/website.min.css" />
|
||||
<noscript><p><img src="https://stats.opkode.com/piwik.php?idsite=1" style="border:0;" alt="" /></p></noscript>
|
||||
<script type="text/javascript" src="/analytics.js"></script>
|
||||
<!-- *********************************************************************** -->
|
||||
|
||||
<link rel="manifest" href="/manifest.json">
|
||||
<link type="text/css" rel="stylesheet" media="screen" href="/dist/converse.min.css" />
|
||||
<link rel="manifest" href="../manifest.json">
|
||||
<link type="text/css" rel="stylesheet" media="screen" href="../dist/converse.min.css" />
|
||||
<script src="https://cdn.conversejs.org/3rdparty/libsignal-protocol.min.js"></script>
|
||||
<script src="/dist/converse.min.js"></script>
|
||||
<script src="../dist/converse.min.js"></script>
|
||||
|
||||
<style>
|
||||
.converse-container {
|
||||
height: 55vh;
|
||||
height: 50vh;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
@ -44,7 +44,7 @@
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<h1 class="brand-heading fade-in">
|
||||
<h1 class="brand-heading fade-in" style="margin: 1.5em 0 0 0">
|
||||
<svg class="converse-svg-logo"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
@ -72,7 +72,7 @@
|
||||
</h1>
|
||||
<p class="intro-text">Embedded MUC chat demo</p>
|
||||
<div class="converse-container">
|
||||
<div id="conversejs"></div>
|
||||
<converse-root></converse-root>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
14
dev.html
@ -10,12 +10,13 @@
|
||||
<meta name="keywords" content="xmpp chat webchat converse.js" />
|
||||
<link rel="manifest" href="./manifest.json">
|
||||
<link rel="shortcut icon" type="image/ico" href="images/favicon.ico"/>
|
||||
<link type="text/css" rel="stylesheet" media="screen" href="dist/website.css" />
|
||||
<link type="text/css" rel="stylesheet" media="screen" href="dist/converse.css" />
|
||||
<script src="https://cdn.conversejs.org/3rdparty/libsignal-protocol.min.js"></script>
|
||||
<script src="dist/converse.js"></script>
|
||||
</head>
|
||||
|
||||
<body class="reset">
|
||||
<body class="reset" style="background-color: var(--global-background-color)">
|
||||
<div id="conversejs-bg"></div>
|
||||
<script>
|
||||
|
||||
@ -27,19 +28,22 @@
|
||||
});
|
||||
|
||||
converse.initialize({
|
||||
i18n: 'af',
|
||||
theme: 'dracula',
|
||||
auto_away: 300,
|
||||
enable_smacks: true,
|
||||
i18n: 'af',
|
||||
loglevel: 'debug',
|
||||
reuse_scram_keys: true,
|
||||
prune_messages_above: 100,
|
||||
message_archiving: 'always',
|
||||
muc_respect_autojoin: true,
|
||||
muc_show_logs_before_join: true,
|
||||
notify_all_room_messages: ['discuss@conference.conversejs.org'],
|
||||
persistent_store: 'IndexedDB',
|
||||
theme: 'concord',
|
||||
view_mode: 'fullscreen',
|
||||
websocket_url: 'wss://conversejs.org/xmpp-websocket',
|
||||
// websocket_url: 'wss://conversejs.org/xmpp-websocket',
|
||||
websocket_url: 'ws://chat.example.org:5380/xmpp-websocket',
|
||||
whitelisted_plugins: ['converse-debug'],
|
||||
// connection_options: { worker: '/dist/shared-connection-worker.js' }
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
|
@ -39,7 +39,7 @@ h5 {
|
||||
}
|
||||
|
||||
.sponsors-list {
|
||||
overflow-y: hidden !important;
|
||||
overflow-y: auto !important;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
|
@ -6,11 +6,9 @@
|
||||
<script src="scripts/prettify/prettify.js"></script>
|
||||
<script src="scripts/prettify/lang-css.js"></script>
|
||||
<script src="./analytics.js"></script>
|
||||
<script src="/dist/converse.min.js"></script>
|
||||
<link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
|
||||
<link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
|
||||
<link type="text/css" rel="stylesheet" href="/docs/source/_static/api.css">
|
||||
<link type="text/css" rel="stylesheet" href="/dist/converse.min.css">
|
||||
<link rel="shortcut icon" href="/images/favicon.ico"/>
|
||||
</head>
|
||||
|
||||
@ -61,6 +59,5 @@
|
||||
|
||||
<script> prettyPrint(); </script>
|
||||
<script src="scripts/linenumber.js"> </script>
|
||||
<script>converse.initialize({'bosh_service_url': 'https://conversejs.org/http-bind/'});</script>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -2,15 +2,12 @@
|
||||
{% extends "!layout.html" %}
|
||||
|
||||
{# Custom CSS overrides #}
|
||||
{% set css_files = css_files + ['_static/style.css', "../../dist/converse.min.css"] %}
|
||||
{% set script_files = script_files + ["../../dist/converse.min.js", "../../analytics.js"] %}
|
||||
{% set css_files = css_files + ['_static/style.css'] %}
|
||||
{% set script_files = script_files + ["../../analytics.js"] %}
|
||||
|
||||
{# Add some extra stuff before and use existing with 'super()' call. #}
|
||||
{% block footer %}
|
||||
{{ super() }}
|
||||
<script>
|
||||
converse.initialize({'bosh_service_url': 'https://conversejs.org/http-bind/'});
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
|
||||
|
@ -2,17 +2,21 @@
|
||||
<h4 class="sidebar-title">Sponsored by</h4>
|
||||
</span>
|
||||
<ul class="sponsors-list">
|
||||
<li><a href="https://www.keycdn.com/?utm_source=conversejs" target="_blank" rel="noopener">
|
||||
<img style="height: 2em" src="/logo/keycdn.png" alt="KeyCDN">
|
||||
</a>
|
||||
</li>
|
||||
<li><a href="https://www.codefirst.co.uk/?utm_source=conversejs" target="_blank" rel="noopener">
|
||||
<img style="width: 9em" src="/logo/codefirst.png" alt="Codefirst">
|
||||
<li><a href="https://bairesdev.com/sponsoring-open-source-projects/?utm_source=conversejs" target="_blank" rel="noopener">
|
||||
<img style="width: 10em" src="/media/logos/bairesdev-primary.png" alt="BairesDev">
|
||||
</a>
|
||||
</li>
|
||||
<li><a href="https://blokt.com/?utm_source=conversejs" target="_blank" rel="noopener">
|
||||
<img style="width: 9em" src="/logo/blokt.png" alt="Blokt Crypto & Privacy">
|
||||
</a>
|
||||
</li>
|
||||
<li><a href="https://primesound.org/?utm_source=conversejs" target="_blank" rel="noopener">
|
||||
<img style="width: 9em" src="/media/logos/primesound.png" alt="Prime Sound">
|
||||
</a>
|
||||
</li>
|
||||
<li><a href="https://www.keycdn.com/?utm_source=conversejs" target="_blank" rel="noopener">
|
||||
<img style="height: 2.5em" src="/logo/keycdn.png" alt="KeyCDN">
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<span class="centered-text-container patreon-link-container"><a href="https://conversejs.org#sponsors">Become a sponsor</a></span>
|
||||
|
@ -1,6 +1,6 @@
|
||||
.. raw:: html
|
||||
|
||||
<div id="banner"><a href="https://github.com/jcbrand/converse.js/blob/master/docs/source/theming.rst">Edit me on GitHub</a></div>
|
||||
<div id="banner"><a href="https://github.com/jcbrand/converse.js/blob/master/docs/source/api/index.rst">Edit me on GitHub</a></div>
|
||||
|
||||
============================================
|
||||
The API documentation (generated with JSDoc)
|
||||
|
@ -48,9 +48,9 @@ copyright = u'2018, JC Brand'
|
||||
# built documents.
|
||||
#
|
||||
# The short X.Y version.
|
||||
version = '7.0.1'
|
||||
version = '10.1.6'
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = '7.0.1'
|
||||
release = '10.1.6'
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
|
@ -23,6 +23,38 @@ all the available configuration settings.
|
||||
Configuration settings
|
||||
======================
|
||||
|
||||
.. _`allowed_audio_domains`:
|
||||
|
||||
allowed_audio_domains
|
||||
---------------------
|
||||
|
||||
* Default: ``null``
|
||||
|
||||
If falsy, all domains are allowed. Set it to an array to specify a whitelist of allowed domains.
|
||||
|
||||
|
||||
.. _`allowed_image_domains`:
|
||||
|
||||
allowed_image_domains
|
||||
---------------------
|
||||
|
||||
* Default: ``null``
|
||||
|
||||
If falsy, all domains are allowed. Set it to an array to specify a whitelist of allowed domains.
|
||||
|
||||
E.g. ``['imgur.com', 'imgbb.com']``
|
||||
|
||||
.. _`allowed_video_domains`:
|
||||
|
||||
allowed_video_domains
|
||||
---------------------
|
||||
|
||||
* Default: ``null``
|
||||
|
||||
If falsy, all domains are allowed. Set it to an array to specify a whitelist of allowed domains.
|
||||
|
||||
E.g. ``['imgur.com']``
|
||||
|
||||
authentication
|
||||
--------------
|
||||
|
||||
@ -118,13 +150,6 @@ This setting is only applicable if the ``converse-bookmarks`` plugin is loaded.
|
||||
|
||||
See also: `allow_public_bookmarks`_
|
||||
|
||||
allow_chat_pending_contacts
|
||||
---------------------------
|
||||
|
||||
* Default: ``false``
|
||||
|
||||
Allow the user to chat with pending contacts.
|
||||
|
||||
allow_contact_removal
|
||||
---------------------
|
||||
|
||||
@ -149,7 +174,7 @@ allow_dragresize
|
||||
* Default: ``true``
|
||||
|
||||
Allow users to resize chats by dragging the edges. The min-height and min-width
|
||||
CSS properties set on a chatboxes (specifically on the ``#converse.js .chatbox > .box-flyout`` element)
|
||||
CSS properties set on a chatboxes (specifically on the ``.chatbox > .box-flyout`` element)
|
||||
will be honored, IF they are set in pixels.
|
||||
|
||||
allow_logout
|
||||
@ -184,14 +209,14 @@ Determines who is allowed to retract messages. If set to ``'all'``, then normal
|
||||
users may retract their own messages and ``'moderators'`` may retract the messages of
|
||||
other users.
|
||||
|
||||
|
||||
allow_muc
|
||||
---------
|
||||
allow_message_styling
|
||||
---------------------
|
||||
|
||||
* Default: ``true``
|
||||
* Possible values: ``true``, ``false``
|
||||
|
||||
Determines wehether support for XEP-0393 Message Styling hints are enabled or not.
|
||||
|
||||
Allow multi-user chat (muc) in chatrooms. Setting this to ``false`` will remove
|
||||
the ``Chatrooms`` tab from the control box.
|
||||
|
||||
allow_muc_invitations
|
||||
---------------------
|
||||
@ -243,6 +268,12 @@ Support for `XEP-0077: In band registration <https://xmpp.org/extensions/xep-007
|
||||
|
||||
Allow XMPP account registration showing the corresponding UI register form interface.
|
||||
|
||||
allow_url_history_change
|
||||
------------------------
|
||||
|
||||
* Default: ``true``
|
||||
|
||||
Allow Converse to change the browser url bar through the History API <https://developer.mozilla.org/en-US/docs/Web/API/History_API>.
|
||||
|
||||
allow_user_trust_override
|
||||
-------------------------
|
||||
@ -289,6 +320,7 @@ available) and the amount returned will be no more than the page size.
|
||||
You will be able to query for even older messages by scrolling upwards in the chatbox or room
|
||||
(the so-called infinite scrolling pattern).
|
||||
|
||||
|
||||
autocomplete_add_contact
|
||||
------------------------
|
||||
|
||||
@ -375,7 +407,6 @@ in to their XMPP account.
|
||||
So currently if EITHER ``keepalive`` or ``auto_login`` is ``true`` and
|
||||
`authentication`_ is set to ``login``, then Converse will try to log the user in.
|
||||
|
||||
|
||||
auto_away
|
||||
---------
|
||||
|
||||
@ -422,12 +453,17 @@ auto_register_muc_nickname
|
||||
--------------------------
|
||||
|
||||
* Default: ``false``
|
||||
* Allowed values: ``false``, ``true``, ``'unregister'``
|
||||
|
||||
Determines whether Converse should automatically register a user's nickname
|
||||
when they enter a groupchat.
|
||||
If truthy, Converse will automatically register a user's nickname upon entering
|
||||
a groupchat.
|
||||
|
||||
See here fore more details: https://xmpp.org/extensions/xep-0045.html#register
|
||||
|
||||
If set to ``'unregister'``, then the user's nickname will be registered
|
||||
(because it's a truthy value) and also be unregistered when the user
|
||||
permanently leaves the MUC by closing it.
|
||||
|
||||
auto_subscribe
|
||||
--------------
|
||||
|
||||
@ -657,7 +693,7 @@ appear in another.
|
||||
.. code-block:: javascript
|
||||
|
||||
converse.initialize({
|
||||
connection_options: { 'worker': true }
|
||||
connection_options: { worker: '/dist/shared-connection-worker.js' }
|
||||
});
|
||||
|
||||
|
||||
@ -716,6 +752,14 @@ loglevel
|
||||
|
||||
You can also set this value by changing a URL fragment `#converse?loglevel=debug`
|
||||
|
||||
.. _`dark_theme`:
|
||||
|
||||
dark_theme
|
||||
----------
|
||||
|
||||
* Default: ``'dracula'``
|
||||
|
||||
The theme being used in dark mode.
|
||||
|
||||
default_domain
|
||||
--------------
|
||||
@ -732,14 +776,6 @@ JIDs with other domains are still allowed but need to be provided in full.
|
||||
To specify only one domain and disallow other domains, see the `locked_domain`_
|
||||
option.
|
||||
|
||||
registration_domain
|
||||
-------------------
|
||||
|
||||
* Default: ``''``
|
||||
|
||||
Specify a domain name for which the registration form will be fetched automatically,
|
||||
without the user having to enter any XMPP server domain name.
|
||||
|
||||
default_state
|
||||
-------------
|
||||
|
||||
@ -865,7 +901,7 @@ The app servers are specified with the `push_app_servers`_ option.
|
||||
enable_smacks
|
||||
-------------
|
||||
|
||||
* Default: ``false``
|
||||
* Default: ``true``
|
||||
|
||||
Determines whether `XEP-0198 Stream Management <https://xmpp.org/extensions/xep-0198.html>`_
|
||||
support is turned on or not.
|
||||
@ -889,12 +925,6 @@ filter_url_query_params
|
||||
|
||||
Accepts a string or array of strings. Any query strings from URLs that match this setting will be removed.
|
||||
|
||||
fullname
|
||||
--------
|
||||
|
||||
If you are using prebinding, can specify the fullname of the currently
|
||||
logged in user, otherwise the user's vCard will be fetched.
|
||||
|
||||
geouri_regex
|
||||
------------
|
||||
|
||||
@ -925,22 +955,6 @@ hide_offline_users
|
||||
|
||||
If set to ``true``, then offline users aren't shown in the roster.
|
||||
|
||||
hide_open_bookmarks
|
||||
-------------------
|
||||
|
||||
* Default: ``false`` (``true`` when the `view_mode`_ is set to ``fullscreen``).
|
||||
|
||||
This setting applies to the ``converse-bookmarks`` plugin and specfically the
|
||||
list of bookmarks shown in the ``Rooms`` tab of the control box.
|
||||
|
||||
By default all bookmarks are shown in that list, if this setting is set to
|
||||
``true``, then only bookmarks for rooms not currently open (i.e. that the
|
||||
current user hasn't joined), are shown.
|
||||
|
||||
Makes sense to set this to ``true`` when also using the non-core
|
||||
``converse-roomslist`` plugin, which shows a list of currently open (i.e.
|
||||
"joined") rooms.
|
||||
|
||||
.. _`i18n`:
|
||||
|
||||
i18n
|
||||
@ -1064,8 +1078,32 @@ VCard is taken, and if that is not set but `muc_nickname_from_jid`_ is set to
|
||||
|
||||
If no nickame value is found, then an error will be raised.
|
||||
|
||||
mam_request_all_pages
|
||||
---------------------
|
||||
|
||||
* Default: ``true``
|
||||
|
||||
When requesting messages from the archive, Converse will ask only for messages
|
||||
newer than the most recent cached message.
|
||||
|
||||
When there are many archived messages since that one, the returned results will
|
||||
be broken up in to pages, set by `archived_messages_page_size`_.
|
||||
|
||||
By default Converse will request all the pages until all messages have been
|
||||
fetched, however for large archives this can slow things down dramatically.
|
||||
|
||||
This setting turns the paging off, and Converse will only fetch the latest
|
||||
page.
|
||||
|
||||
.. note::
|
||||
|
||||
If paging is turned off, there will appear gaps in the message history.
|
||||
Converse currently doesn't yet have a way to inform the user of these gaps or
|
||||
to let them be filled.
|
||||
|
||||
|
||||
muc_hats
|
||||
-------------------
|
||||
--------
|
||||
|
||||
* Default: ``['xep317']``
|
||||
|
||||
@ -1141,22 +1179,6 @@ from the XMPP server.
|
||||
|
||||
Used in conjunction with ``message_archiving`` and in context of `XEP-0313: Message Archive Management <https://xmpp.org/extensions/xep-0313.html>`_.
|
||||
|
||||
message_carbons
|
||||
---------------
|
||||
|
||||
* Default: ``true``
|
||||
|
||||
Support for `XEP-0280: Message Carbons <https://xmpp.org/extensions/xep-0280.html>`_
|
||||
|
||||
In order to keep all IM clients for a user engaged in a conversation,
|
||||
outbound messages are carbon-copied to all interested resources.
|
||||
|
||||
This is especially important with Converse, where each browser
|
||||
tab serves as a separate IM client.
|
||||
|
||||
XEP-0280 requires server support, so make sure that message carbons are enabled
|
||||
on your server.
|
||||
|
||||
|
||||
message_limit
|
||||
-------------
|
||||
@ -1190,6 +1212,16 @@ If all roles or all affiliations are disabled, then the relevant tab won't be
|
||||
showed at all.
|
||||
|
||||
|
||||
muc_clear_messages_on_leave
|
||||
---------------------------
|
||||
|
||||
* Default: ``true``
|
||||
|
||||
Starting with Converse 8.0.0, when leaving a MUC, all cached messages in the history is cleared.
|
||||
|
||||
Note: This means that you lose your history of decrypted OMEMO messages and cannot recover it.
|
||||
|
||||
|
||||
muc_disable_slash_commands
|
||||
--------------------------
|
||||
|
||||
@ -1300,8 +1332,7 @@ If set to ``true``, then whenever Converse receives a MUC message with an autho
|
||||
any information (i.e. because that user is currently not in the MUC), then Converse will send out a ``<presence>``
|
||||
stanza of type ``probe`` in order to request the authors presence data.
|
||||
|
||||
Prosody has some experimental support in it's contrib branch (hopefully soon to
|
||||
be merged to trunk).
|
||||
Prosody has support in `trunk` for this.
|
||||
|
||||
The point of sending out presence probes is in order to receive
|
||||
presence-related metadata, such as `XEP-0317 Hats <https://xmpp.org/extensions/xep-0317.html>`_.
|
||||
@ -1372,13 +1403,53 @@ Example:
|
||||
|
||||
muc_roomid_policy_hint: '<br><b>Policy for groupchat id:</b><br>- between 5 and 40 characters,<br>- lowercase from a to z (no special characters) or<br>- digits or<br>- dots (.) or<br>- underlines (_) or<br>- hyphens (-),<br>- no spaces<br>',
|
||||
|
||||
muc_show_join_leave
|
||||
-------------------
|
||||
muc_show_info_messages
|
||||
----------------------
|
||||
|
||||
* Default; ``true``
|
||||
* Default: List composed of MUC status codes, role changes, join and leave events and affiliation changes. The values of converse.MUC_INFO_CODES below are joined to build the default list:
|
||||
|
||||
Determines whether Converse will show info messages inside a chatroom
|
||||
whenever a user joins or leaves it.
|
||||
.. code-block:: javascript
|
||||
|
||||
converse.MUC_AFFILIATION_CHANGES_LIST = ['owner', 'admin', 'member', 'exowner', 'exadmin', 'exmember', 'exoutcast']
|
||||
converse.MUC_ROLE_CHANGES_LIST = ['op', 'deop', 'voice', 'mute'];
|
||||
converse.MUC_TRAFFIC_STATES_LIST = ['entered', 'exited'];
|
||||
|
||||
converse.MUC_INFO_CODES = {
|
||||
'visibility_changes': ['100', '102', '103', '172', '173', '174'],
|
||||
'self': ['110'],
|
||||
'non_privacy_changes': ['104', '201'],
|
||||
'muc_logging_changes': ['170', '171'],
|
||||
'nickname_changes': ['210', '303'],
|
||||
'disconnect_messages': ['301', '307', '321', '322', '332', '333'],
|
||||
'affiliation_changes': [...converse.AFFILIATION_CHANGES_LIST],
|
||||
'join_leave_events': [...converse.MUC_TRAFFIC_STATES_LIST],
|
||||
'role_changes': [...converse.MUC_ROLE_CHANGES_LIST],
|
||||
};
|
||||
|
||||
This setting determines which info messages will Converse show inside a chatroom.
|
||||
It is recommended to use the aforementioned Converse object in the following fashion
|
||||
to build the list of desired info messages that will be shown:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
muc_show_info_messages: [
|
||||
...converse.MUC_INFO_CODES.visibility_changes,
|
||||
...converse.MUC_INFO_CODES.self,
|
||||
...converse.MUC_INFO_CODES.non_privacy_changes,
|
||||
...converse.MUC_INFO_CODES.muc_logging_changes,
|
||||
...converse.MUC_INFO_CODES.nickname_changes,
|
||||
...converse.MUC_INFO_CODES.disconnect_messages,
|
||||
...converse.MUC_INFO_CODES.affiliation_changes,
|
||||
...converse.MUC_INFO_CODES.join_leave_events,
|
||||
...converse.MUC_INFO_CODES.role_changes,
|
||||
]
|
||||
|
||||
By default all info messages are shown.
|
||||
|
||||
The behaviour of this setting is whitelisting, so if it is overriden all the desired
|
||||
events must be specified.
|
||||
|
||||
If an empty list is provided, no info message will be displayed at all.
|
||||
|
||||
muc_show_logs_before_join
|
||||
-------------------------
|
||||
@ -1387,9 +1458,23 @@ muc_show_logs_before_join
|
||||
|
||||
If set to ``true``, when opening a MUC for the first time (or if you don't have
|
||||
a nickname configured for it), you'll see the message history (if the
|
||||
server supports [XEP-0313 Message Archive Management](https://xmpp.org/extensions/xep-0313.html))
|
||||
server supports `XEP-0313 Message Archive Management <https://xmpp.org/extensions/xep-0313.html>`_)
|
||||
and the nickname form at the bottom.
|
||||
|
||||
|
||||
muc_subscribe_to_rai
|
||||
--------------------
|
||||
|
||||
* Default: ``false``
|
||||
|
||||
This option enables support for `XEP-0437 Room Activity Indicators <https://xmpp.org/extensions/xep-0437.html>`_.
|
||||
|
||||
When a MUC is no longer visible (specifically, when the ``hidden`` flag becomes ``true``),
|
||||
then Converse will exit the MUC and subscribe to activity indicators on the MUC host.
|
||||
|
||||
When the MUC becomes visible again (``hidden`` gets set to ``false``), the MUC will be rejoined.
|
||||
|
||||
|
||||
.. _`nickname`:
|
||||
|
||||
nickname
|
||||
@ -1582,11 +1667,12 @@ compile time.
|
||||
|
||||
This configuration seting allows this value to be set at runtime as well.
|
||||
|
||||
.. _persistent-store:
|
||||
|
||||
persistent_store
|
||||
----------------
|
||||
|
||||
* Default: ``localStorage``
|
||||
* Default: ``IndexedDB``
|
||||
* Valid options: ``localStorage``, ``IndexedDB``, ``sessionStorage``, ``BrowserExtLocal``, ``BrowserExtSync``
|
||||
|
||||
Determines which store is used for storing persistent data.
|
||||
@ -1609,6 +1695,34 @@ Items in sync storage are synced by the browser and are available across all ins
|
||||
BrowserExtLocal represents the local storage area.
|
||||
Items in local storage are local to the machine the extension was installed on
|
||||
|
||||
prune_messages_above
|
||||
--------------------
|
||||
|
||||
* Default: ``undefined``
|
||||
* Valid options: Any integer value above 0.
|
||||
|
||||
If this option is set to a positive integer, the chat history will be kept to
|
||||
that number. As new messages come in, older messages will be deleted to
|
||||
maintain the history size.
|
||||
|
||||
.. note::
|
||||
When deleting locally stored decrypted OMEMO messages, you will **not** be
|
||||
able to decrypt them again after fetching them from the server archive.
|
||||
|
||||
pruning_behavior
|
||||
----------------
|
||||
|
||||
* Default: ``unscrolled``
|
||||
* Valid options: ``unscrolled``, ``scrolled``
|
||||
|
||||
By default the chat history will only be pruned when the chat window isn't
|
||||
scrolled up (``'unscrolled'``).
|
||||
|
||||
If set to ``'scrolled'``, then pruning will also happen when the chat is
|
||||
scrolled up. Be aware that this will interfere with MAM-based infinite
|
||||
scrolling, and this setting only makes sense when infinite scrolling with MAM
|
||||
is disabled.
|
||||
|
||||
|
||||
push_app_servers
|
||||
----------------
|
||||
@ -1644,6 +1758,82 @@ For example:
|
||||
});
|
||||
|
||||
|
||||
registration_domain
|
||||
-------------------
|
||||
|
||||
* Default: ``''``
|
||||
|
||||
Specify a domain name for which the registration form will be fetched automatically,
|
||||
without the user having to enter any XMPP server domain name.
|
||||
|
||||
render_media
|
||||
------------
|
||||
|
||||
* Default: ``true``
|
||||
|
||||
* Possible values: ``true``, ``false`` or an array of domains for which media
|
||||
should automatically be rendered.
|
||||
|
||||
If ``true``, media URLs (images, audio and video) will be rendered in the chat.
|
||||
|
||||
If ``false``, the URLs won't render as media, and instead only clickable links
|
||||
will be shown.
|
||||
|
||||
Setting it to an array of domains means that media will be rendered only for URLs
|
||||
matching those domains.
|
||||
|
||||
Media URLs are those URLs which appear to point to media files as well as URLs
|
||||
for which `Open Graph Protocol (OGP) <https://modules.prosody.im/mod_ogp.html>`_
|
||||
data was received (for example via Prosody's `mod_ogp <https://modules.prosody.im/mod_ogp.html>`_).
|
||||
|
||||
The OGP metadata must come from the MUC itself, metadata sent from participants
|
||||
themselves will not be shown.
|
||||
|
||||
Based on the OGP metadata Converse will render a URL preview (also known as an
|
||||
"unfurl").
|
||||
|
||||
.. note::
|
||||
|
||||
Note, even if this setting is ``false`` (or if the URL domain is not in the
|
||||
array of allowed domains), a user can still click on the message
|
||||
dropdown and click to show or hide the media for that particular message.
|
||||
|
||||
If you want to disable this ability, you can set the allowed domains for the
|
||||
media type to an empty array.
|
||||
|
||||
See:
|
||||
|
||||
* `allowed_audio_domains`_
|
||||
* `allowed_video_domains`_
|
||||
* `allowed_image_domains`_
|
||||
|
||||
.. note::
|
||||
|
||||
This setting, together with the three allowed domain settings above, obsolete
|
||||
the ``show_images_inline``, ``embed_audio`` and ``embed_videos`` settings.
|
||||
|
||||
|
||||
reuse_scram_keys
|
||||
----------------
|
||||
|
||||
* Default: ``false``
|
||||
|
||||
Most XMPP servers enable the Salted Challenge Response Authentication Mechanism
|
||||
or SCRAM for short. This allows the user and the server to mutually
|
||||
authenticate *without* the need to transmit the user's password in plaintext.
|
||||
|
||||
Assuming the server does not alter the user's password or the
|
||||
storage parameters, we can authenticate with the same SCRAM key multiple times.
|
||||
|
||||
This opens an opportunity: we can store the user's login credentials in the
|
||||
browser without storing the sensitive plaintext password, or the
|
||||
need to set up complicated third party backends, like OAuth.
|
||||
|
||||
Enabling this option will let Converse save a user's SCRAM keys upon successful
|
||||
login, and next time Converse is loaded the user will be automatically logged in
|
||||
with those SCRAM keys.
|
||||
|
||||
|
||||
.. _`roomconfig_whitelist`:
|
||||
|
||||
roomconfig_whitelist
|
||||
@ -1708,6 +1898,7 @@ send_chat_state_notifications
|
||||
-----------------------------
|
||||
|
||||
* Default: ``true``
|
||||
* Allowed values: ``'active', 'composing', 'gone' 'inactive', 'paused'``
|
||||
|
||||
Determines whether chat state notifications (see `XEP-0085 <https://xmpp.org/extensions/xep-0085.html>`_) should be sent out or not.
|
||||
|
||||
@ -1721,7 +1912,17 @@ For example:
|
||||
'send_chat_state_notifications': ['composing']
|
||||
});
|
||||
|
||||
Valid values are ``'active', 'composing', 'gone' 'inactive', 'paused'``
|
||||
|
||||
send_chat_markers
|
||||
-----------------
|
||||
|
||||
* Default: ``['received', 'displayed', 'acknowledged']``
|
||||
|
||||
Determines which (if any) of the `XEP-0333 <https://xmpp.org/extensions/xep-0333.html>`_ chat markers will be sent out.
|
||||
|
||||
It's still up to Converse to decide when to send out the relevant markers, the
|
||||
purpose of this setting is merely to turn on or off the sending of the
|
||||
individual markers.
|
||||
|
||||
|
||||
show_chat_state_notifications
|
||||
@ -1739,6 +1940,16 @@ show_client_info
|
||||
Specifies whether the info icon is shown on the controlbox which when clicked opens an
|
||||
"About" modal with more information about the version of Converse being used.
|
||||
|
||||
show_connection_url_input
|
||||
-------------------------
|
||||
|
||||
* Default: ``false``
|
||||
|
||||
Determines whether the login form should show an input element where the user
|
||||
can enter the connection URL. If it's a websocket url, then upon form
|
||||
submission the `websocket_url`_ setting will be updated with this value, and if
|
||||
it's an HTTP URL then the `bosh_service_url`_ setting will be updated.
|
||||
|
||||
show_controlbox_by_default
|
||||
--------------------------
|
||||
|
||||
@ -1793,9 +2004,9 @@ show_images_inline
|
||||
|
||||
If set to ``false``, images won't be rendered in chats, instead only their links will be shown.
|
||||
|
||||
It also accepts an array strings of whitelisted domain names to only render images that belong to those domains.
|
||||
Users will however still have the ability to render individual images via the message actions dropdown.
|
||||
If you want to disallow users from doing so, set the ``allowed_image_domains`` option to an empty array ``[]``.
|
||||
|
||||
E.g. ``['imgur.com', 'imgbb.com']``
|
||||
|
||||
show_retraction_warning
|
||||
-----------------------
|
||||
@ -1826,6 +2037,14 @@ Adds a button to the chat which can be clicked or tapped in order to send the
|
||||
message.
|
||||
|
||||
|
||||
show_tab_notifications
|
||||
----------------------
|
||||
|
||||
* Default: ``true``
|
||||
|
||||
Determines whether an unread messages counter is shown in the tab.
|
||||
|
||||
|
||||
singleton
|
||||
---------
|
||||
|
||||
@ -1851,6 +2070,7 @@ This setting relates to `XEP-0198 <https://xmpp.org/extensions/xep-0198.html>`_
|
||||
and determines the number of stanzas to be sent before Converse will ask the
|
||||
server for acknowledgement of those stanzas.
|
||||
|
||||
|
||||
sounds_path
|
||||
-----------
|
||||
|
||||
@ -1863,6 +2083,13 @@ themselves).
|
||||
In order to support all browsers we need both an MP3 and an Ogg file. Make sure
|
||||
to name your files ``msg_received.ogg`` and ``msg_received.mp3``.
|
||||
|
||||
stanza_timeout
|
||||
--------------
|
||||
|
||||
* Default: ``20000`` (20 seconds)
|
||||
|
||||
The time to wait, in milliseconds, for a response stanza (for example to an IQ
|
||||
request), before a timeout error is thrown and Converse stops waiting.
|
||||
|
||||
sticky_controlbox
|
||||
-----------------
|
||||
@ -1920,11 +2147,13 @@ If set to ``false``, this feature is disabled.
|
||||
|
||||
If set to ``a resource name``, Converse will synchronize only with a client that has that particular resource assigned to it.
|
||||
|
||||
.. _`theme`:
|
||||
|
||||
theme
|
||||
-----
|
||||
|
||||
* Default: ``default``
|
||||
* Valid options: ``default``, ``concord``
|
||||
* Valid options: ``default``, ``concord``, ``dracula``
|
||||
|
||||
Let's you set a color theme for Converse.
|
||||
|
||||
@ -1954,13 +2183,6 @@ Converse render the emojis with `Twemoji <https://twemoji.twitter.com/>`_.
|
||||
See also `emoji_image_path`_.
|
||||
|
||||
|
||||
update_title
|
||||
------------
|
||||
* Default: ``true``
|
||||
|
||||
Determines whether to shows unread messages counter in the page title.
|
||||
|
||||
|
||||
visible_toolbar_buttons
|
||||
-----------------------
|
||||
|
||||
@ -2032,7 +2254,7 @@ The ``view_mode`` setting configures Converse's mode and resulting behavior.
|
||||
|
||||
* ``overlayed`` is the original mode, in which the chats appeared as small boxes overlaying a webpage which can contain arbitrary content.
|
||||
* ``fullscreen`` is for a fullpage and single-page app.
|
||||
* ``embedded`` is used to embed a single chat into a DOM element in the page. The DOM element must have the id ``#conversejs``.
|
||||
* ``embedded`` is used to embed Converse into a particular part of the web page. Put the custom element ``<converse-root></converse-root>`` into your page HTML there were you want Converse to appear. See `conversejs.org/demo/embedded.html <https://conversejs.org/demo/embedded.html>`_ for an example of this view mode.
|
||||
* ``mobile`` is for smaller viewports. Converse is responsive, and the other views will also resize to fit a smaller viewport, but certain behavioural changes won't be made. For example, when using ``overlayed`` in a mobile view, Converse won't know which chat is currently visible and therefore won't be able to properly show notifications for chats that are obscured.
|
||||
|
||||
.. note::
|
||||
|
@ -1,48 +1,57 @@
|
||||
.. raw:: html
|
||||
|
||||
<div id="banner"><a href="https://github.com/jcbrand/converse.js/blob/master/docs/source/theming.rst">Edit me on GitHub</a></div>
|
||||
<div id="banner"><a href="https://github.com/jcbrand/converse.js/blob/master/docs/source/dependencies.rst">Edit me on GitHub</a></div>
|
||||
|
||||
============
|
||||
Dependencies
|
||||
============
|
||||
.. _`development`:
|
||||
|
||||
============================
|
||||
Setting up a dev environment
|
||||
============================
|
||||
|
||||
Installing the 3rd party dependencies
|
||||
=====================================
|
||||
|
||||
We use development tools which depend on Node.js and npm (the Node package manager).
|
||||
|
||||
If you don't have Node.js installed, you can download and install the latest
|
||||
version `here <https://nodejs.org/download>`_.
|
||||
|
||||
Alternatively you can `use your operating system's package manager to install
|
||||
Node.js <https://nodejs.org/en/download/package-manager/#debian-and-ubuntu-based-linux-distributions>`_.
|
||||
|
||||
Also make sure you have ``Git`` installed. `See here <http://git-scm.com/book/en/Getting-Started-Installing-Git>`_.
|
||||
|
||||
Now use ``git`` to check out the Converse repository:
|
||||
To develop and customize Converse, you'll first need to check out Converse's Git
|
||||
repository:
|
||||
|
||||
::
|
||||
|
||||
git clone https://github.com/conversejs/converse.js.git
|
||||
cd converse.js
|
||||
|
||||
Now go into the repository checkout and run ``make dev`` in order to set up the
|
||||
development environment.
|
||||
|
||||
We use development tools which depend on Node.js and NPM (the Node package manager).
|
||||
|
||||
It's recommended that you use `NVM <https://github.com/nvm-sh/nvm>`_ (the Node version manager)
|
||||
to make sure you have the right version of Node.
|
||||
|
||||
Refer to the `NVM Github page <https://github.com/nvm-sh/nvm#install--update-script>`_ for instructions on how to install it.
|
||||
|
||||
Once NVM is installed, you can run the following inside your checkout of the Converse Git repository:
|
||||
|
||||
::
|
||||
|
||||
nvm install
|
||||
|
||||
.. note::
|
||||
You will always have to first run ``nvm install`` in a new terminal session before working on Converse.
|
||||
|
||||
|
||||
To set up the Converse development environment, you now run ``make dev``.
|
||||
|
||||
::
|
||||
|
||||
cd converse.js
|
||||
make dev
|
||||
|
||||
If you're using Windows, or don't have GNU Make installed, you can run the
|
||||
Alternatively, if you're using Windows, or don't have GNU Make installed, you can run the
|
||||
following:
|
||||
|
||||
::
|
||||
|
||||
cd converse.js
|
||||
npm install
|
||||
npm run lerna
|
||||
|
||||
This will install the Node.js development tools and Converse's dependencies.
|
||||
This will install the Node development tools and Converse's dependencies.
|
||||
|
||||
The front-end dependencies are those JavaScript files on which
|
||||
Converse directly depends and which will be loaded in the browser as part of
|
||||
@ -64,30 +73,12 @@ the list under the ``devDependencies`` in `package.json <https://github.com/jcbr
|
||||
where you can log in and be taken directly to the chatroom.
|
||||
|
||||
|
||||
Brief description of Converse's dependencies
|
||||
===============================================
|
||||
|
||||
Converse relies on the following dependencies:
|
||||
|
||||
* `DayJS <https://github.com/iamkun/dayjs>`_ provides a better API for handling dates and times.
|
||||
* `Strophe.js <http://strophe.im/>`_ maintains the XMPP session, is used to
|
||||
build XMPP stanzas, to send them, and to register handlers for received stanzas.
|
||||
* `lodash <https://lodash.com/>`_ provides very useful utility functions.
|
||||
* `Skeletor <https://github.com/skeletorjs/skeletor/>`_, a `Backbone <http://backbonejs.org/>`_ fork
|
||||
which is used to model the data as Models and Collections and to create Views that render the UI.
|
||||
* `pluggable.js <https://github.com/jcbrand/pluggable.js>`_ provides the plugin
|
||||
architecture for Converse. It registers and initializes plugins and
|
||||
allows existing attributes, functions and objects on Converse to be
|
||||
overridden inside plugins.
|
||||
|
||||
.. _`dependency-libsignal`:
|
||||
|
||||
Libsignal
|
||||
---------
|
||||
|
||||
If you want OMEMO encryption, you need to load `libsignal
|
||||
<https://github.com/signalapp/libsignal-protocol-javascript>`_ separately in
|
||||
your page.
|
||||
If you want OMEMO encryption, you need to load `libsignal <https://github.com/signalapp/libsignal-protocol-javascript>`_ separately in your page.
|
||||
|
||||
For example::
|
||||
|
||||
@ -98,3 +89,51 @@ under the `GPLv3 <https://github.com/signalapp/libsignal-protocol-javascript/blo
|
||||
which requires all other dependent JavaScript code to also be open sourced under the same
|
||||
license. You might not be willing to adhere to those terms, which is why you
|
||||
need to decide for yourself whether you're going to load libsignal or not.
|
||||
|
||||
|
||||
.. _`webserver`:
|
||||
|
||||
Setting up a webserver
|
||||
======================
|
||||
|
||||
When making changes to Converse, either development or theming changes,
|
||||
you'll want to preview them in your browser.
|
||||
|
||||
For this, you'll need to serve the development files via a web server,
|
||||
so that you can see your local changes in the browser.
|
||||
|
||||
Manually starting a web server
|
||||
------------------------------
|
||||
|
||||
To both set up the development environment and also start up a web browser to
|
||||
serve the files for you, you can run::
|
||||
|
||||
make serve
|
||||
|
||||
.. note::
|
||||
To run the "make" commands, you'll need `GNUMake <https://www.gnu.org/software/make>`_
|
||||
installed on your computer. If you use GNU/Linux or \*BSD, it should be installed or
|
||||
available via your package manager. For Mac, you'll need to install XCode and in
|
||||
Windows you can use `Chocolatey <https://chocolatey.org/>`_.
|
||||
|
||||
After running ``make serve`` you can open http://localhost:8000 in your webbrowser to see the Converse website.
|
||||
|
||||
When developing or changing the theme, you'll want to load all the
|
||||
unminified JS and CSS resources as separate files. To do this, open http://localhost:8000/dev.html instead.
|
||||
|
||||
You might want to open `dev.html <https://github.com/conversejs/converse.js/blob/master/dev.html>`_ in your text editor or IDE as well, to see
|
||||
how ``converse.initialize`` is called and to potentially change any of the
|
||||
settings.
|
||||
|
||||
Starting a web server with live reloading
|
||||
-----------------------------------------
|
||||
|
||||
Alternatively, if you want to have live reloading whenever any of the source files change, you
|
||||
can run ``make devserver`` (which will use `webpack-dev-server <https://github.com/webpack/webpack-dev-server>`_).
|
||||
|
||||
Instead of ``dev.html`` being used, `webpack.html <https://github.com/conversejs/converse.js/blob/master/webpack.html>`_
|
||||
is now being used as the HTML template, and you'll need to modify that file if
|
||||
you want to change the settings passed to ``converse.initialize``.
|
||||
|
||||
If you're running ``make devserver``, you need to open http://localhost:8080.
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
<div id="banner"><a href="https://github.com/jcbrand/converse.js/blob/master/docs/source/development.rst">Edit me on GitHub</a></div>
|
||||
|
||||
.. _development:
|
||||
.. _`development`:
|
||||
|
||||
===========
|
||||
Development
|
||||
@ -23,10 +23,10 @@ to fix a bug or to add new functionality.
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
dependencies
|
||||
style_guide
|
||||
setup_dev_environment
|
||||
plugin_development
|
||||
api/index
|
||||
testing
|
||||
other_frameworks
|
||||
builds
|
||||
style_guide
|
||||
|
@ -31,10 +31,16 @@ End to end message encryption (`XEP-0384 OMEMO <https://xmpp.org/extensions/xep-
|
||||
=============================================================================================
|
||||
|
||||
.. note::
|
||||
Converse.js (as of version 4.1.2) does NOT support encryption or decryption
|
||||
Converse versions older than 8.0.0 do NOT support encryption or decryption
|
||||
of uploaded files. Files will be uploaded WITHOUT ENCRYPTION, even when
|
||||
OMEMO is enabled.
|
||||
|
||||
.. note::
|
||||
For end-to-end encryption via OMEMO, you'll need to load `libsignal-protocol.js
|
||||
<https://github.com/signalapp/libsignal-protocol-javascript>`_ separately in
|
||||
your page. Take a look at the section on :ref:`libsignal <dependency-libsignal>` and the
|
||||
:ref:`security considerations around OMEMO <feature-omemo>`.
|
||||
|
||||
Converse supports OMEMO encryption based on the
|
||||
`Signal Protocol <https://github.com/signalapp/libsignal-protocol-javascript>`_.
|
||||
|
||||
@ -44,7 +50,9 @@ ever tear down a session once one has been established.
|
||||
|
||||
This means that a session needs to be stored permanently after logging out.
|
||||
|
||||
Converse stores this session information in the browser's `localStorage <https://developer.mozilla.org/en-US/docs/Web/API/Storage/LocalStorage>`_.
|
||||
Converse stores this session information in the browser's `IndexedDB <https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API>`_
|
||||
or `localStorage <https://developer.mozilla.org/en-US/docs/Web/API/Storage/LocalStorage>`_
|
||||
database, depending on the value provided to :ref:`persistent-store`.
|
||||
|
||||
If you've checked the "This is not a trusted device" checkbox when logging in,
|
||||
then `sessionStorage <https://developer.mozilla.org/en-US/docs/Web/API/Window/sessionStorage>`_
|
||||
@ -88,10 +96,7 @@ headers.
|
||||
Due to these reasons, it's NOT a good idea to use encrypted messaging with a
|
||||
browser-based solution in life-threatening situations.
|
||||
|
||||
Security can be increased by using an installable app (like one based on `Electron <https://electronjs.org/>`_)
|
||||
with a strict Content Security Policy.
|
||||
|
||||
Look out for an Electron based version of Converse coming in the following months.
|
||||
Security can be increased by using an installable app (like `Converse Desktop <https://github.com/conversejs/converse-desktop>`_).
|
||||
|
||||
For further reading on the challenges of web-based crypto, take a look at these
|
||||
articles:
|
||||
|
@ -47,8 +47,8 @@ Table of Contents
|
||||
session
|
||||
configuration
|
||||
development
|
||||
security
|
||||
theming
|
||||
security
|
||||
translations
|
||||
troubleshooting
|
||||
documentation
|
||||
|
@ -1,6 +1,6 @@
|
||||
.. raw:: html
|
||||
|
||||
<div id="banner"><a href="https://github.com/jcbrand/converse.js/blob/master/docs/source/theming.rst">Edit me on GitHub</a></div>
|
||||
<div id="banner"><a href="https://github.com/jcbrand/converse.js/blob/master/docs/source/other_frameworks.rst">Edit me on GitHub</a></div>
|
||||
|
||||
Integrating converse.js into other frameworks
|
||||
=============================================
|
||||
|
@ -1,6 +1,6 @@
|
||||
.. raw:: html
|
||||
|
||||
<div id="banner"><a href="https://github.com/jcbrand/converse.js/blob/master/docs/source/theming.rst">Edit me on GitHub</a></div>
|
||||
<div id="banner"><a href="https://github.com/jcbrand/converse.js/blob/master/docs/source/plugin_development.rst">Edit me on GitHub</a></div>
|
||||
|
||||
.. _`writing-a-plugin`:
|
||||
|
||||
@ -16,7 +16,7 @@ and is itself composed out of plugins.
|
||||
There are only a few files that are included in the default build of Converse
|
||||
which aren't plugins.
|
||||
|
||||
An important one is `converse-core.js <https://github.com/conversejs/converse.js/blob/master/src/headless/converse-core.js>`_,
|
||||
An important one is `core.js <https://github.com/conversejs/.js/blob/master/src/headless/core.js>`_,
|
||||
which is responsible for bootstrapping the plugin architecture,
|
||||
setting up and maintaining the connection to the XMPP
|
||||
server and declaring the public (`window.converse </docs/html/api/converse.html>`_) and protected (`_converse.api </docs/html/api/-_converse.api.html>`_) APIs.
|
||||
@ -167,7 +167,7 @@ Accessing 3rd party libraries
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Immediately inside the module shown above you can access 3rd party libraries (such
|
||||
dayjs and lodash) via the ``converse.env`` map.
|
||||
dayjs) via the ``converse.env`` map.
|
||||
|
||||
The code for it could look something like this:
|
||||
|
||||
@ -175,13 +175,61 @@ The code for it could look something like this:
|
||||
|
||||
// Commonly used utilities and variables can be found under the "env"
|
||||
// namespace of the "converse" global.
|
||||
const { Promise, Strophe, dayjs, sizzle, _, $build, $iq, $msg, $pres } = converse.env;
|
||||
const { Promise, Strophe, dayjs, sizzle, $build, $iq, $msg, $pres } = converse.env;
|
||||
|
||||
These dependencies are closured so that they don't pollute the global
|
||||
namespace, that's why you need to access them in such a way inside the module.
|
||||
|
||||
Overrides
|
||||
---------
|
||||
Overriding templates
|
||||
--------------------
|
||||
|
||||
Converse uses `lit-html <https://lit-html.polymer-project.org/guide>`_
|
||||
templates and templates are imported as separate files.
|
||||
|
||||
It's possible to configure your module bundler (e.g. Webpack) in such as way that a
|
||||
different file is loaded when a template is imported.
|
||||
|
||||
This allows you to create your own templates that are used instead of the ones
|
||||
that would have originally been imported.
|
||||
|
||||
With Webpack (which Converse uses internally), you can specify an
|
||||
``alias`` for the template you want to override. This alias then points to your
|
||||
own custom template.
|
||||
|
||||
For example, in your webpack config file, you could add the following to the
|
||||
``config`` object that gets exported:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
resolve: {
|
||||
extensions: ['.js'],
|
||||
modules: [
|
||||
path.join(__dirname, 'node_modules'),
|
||||
path.join(__dirname, 'node_modules/converse.js/src')
|
||||
],
|
||||
alias: {
|
||||
'plugins/profile/templates/profile.js$': path.resolve(__dirname, 'templates/custom-profile.js')
|
||||
}
|
||||
}
|
||||
|
||||
This will override the template that gets imported at the path ``plugins/profile/templates/profile.js``
|
||||
with your own template at the path ``templates/custom-profile.js`` (relative to your webpack config file).
|
||||
|
||||
|
||||
Object and class Overrides
|
||||
--------------------------
|
||||
|
||||
.. note:: Using the `overrides` feature from pluggable.js is discouraged. It's
|
||||
much better to use events, promises and `hooks`_ to modify the behaviour of
|
||||
Converse.
|
||||
|
||||
The pluggable.js `overrides` will only work on objects and classes that are
|
||||
set as attributes on the `_converse` object, which doesn't apply to many
|
||||
newer classes and objects, such as the web components. For these clasess,
|
||||
overrides won't work at all.
|
||||
|
||||
This section is left here for completeness, because in some special cases
|
||||
overrides are still used.
|
||||
|
||||
Plugins can override core code or code from other plugins. You can specify
|
||||
overrides in the object passed to ``converse.plugins.add``.
|
||||
@ -242,7 +290,7 @@ monkey patching which pollutes the call stack and can make your code fragile
|
||||
and prone to bugs when Converse gets updated. Too much use of ``overrides``
|
||||
is therefore a "code smell" which should ideally be avoided.
|
||||
|
||||
A better approach is to listen to the events emitted by Converse, and to add
|
||||
A better approach is to use the events and `hooks`_ emitted by Converse, and to add
|
||||
your code in event handlers. This is however not always possible, in which case
|
||||
the overrides are a powerful tool.
|
||||
|
||||
@ -260,63 +308,6 @@ For example:
|
||||
Object.assign(_converse.ChatBoxView.prototype, { doSomething });
|
||||
|
||||
|
||||
Overriding a template
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Converse uses various templates, loaded with lodash, to generate its HTML.
|
||||
|
||||
It's not possible to override a template with the plugin's ``overrides``
|
||||
feature, instead you should configure a new path to your own template via your
|
||||
module bundler.
|
||||
|
||||
For example, with Webpack (which Converse uses internall), you can specify an
|
||||
``alias`` for the template you want to override. This alias then points to your
|
||||
own custom template.
|
||||
|
||||
For example, in your webpack config file, you could add the following to the
|
||||
``config`` object that gets exported:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
module: {
|
||||
{
|
||||
test: /templates\/.*\.(html|svg)$/,
|
||||
use: [{
|
||||
loader: 'lodash-template-webpack-loader',
|
||||
options: {
|
||||
escape: /\{\{\{([\s\S]+?)\}\}\}/g,
|
||||
evaluate: /\{\[([\s\S]+?)\]\}/g,
|
||||
interpolate: /\{\{([\s\S]+?)\}\}/g,
|
||||
// By default, template places the values from your data in the
|
||||
// local scope via the with statement. However, you can specify
|
||||
// a single variable name with the variable setting. This can
|
||||
// significantly improve the speed at which a template is able
|
||||
// to render.
|
||||
variable: 'o',
|
||||
prependFilenameComment: __dirname
|
||||
}
|
||||
}]
|
||||
}
|
||||
},
|
||||
resolve: {
|
||||
extensions: ['.js'],
|
||||
modules: [
|
||||
path.join(__dirname, 'node_modules'),
|
||||
path.join(__dirname, 'node_modules/converse.js/src')
|
||||
],
|
||||
alias: {
|
||||
'templates/profile_view.html$': path.resolve(__dirname, 'templates/profile_view.html')
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
You'll need to install ``lodash-template-webpack-loader``.
|
||||
|
||||
Currently Converse uses a fork of `lodash-template-webpack-loader <https://github.com/jcbrand/lodash-template-webpack-loader>`_.
|
||||
|
||||
To install it, you can add ``"lodash-template-webpack-loader": "jcbrand/lodash-template-webpack-loader"``
|
||||
to your package.json's ``devDependencies``.
|
||||
|
||||
|
||||
.. _`dependencies`:
|
||||
|
||||
@ -459,8 +450,87 @@ Please refer to the `API documentation </docs/html/api/http://localhost:8008/doc
|
||||
for an overview of what's available to you. If you need new events or promises, then
|
||||
`please open an issue or make a pull request on Github <https://github.com/jcbrand/converse.js>`_
|
||||
|
||||
A full example plugin
|
||||
---------------------
|
||||
|
||||
Hooks
|
||||
-----
|
||||
|
||||
Converse has the concept of ``hooks``, which are special events that allow you
|
||||
to modify it's behaviour at runtime.
|
||||
|
||||
A hook is similar to an event, but it differs in two meaningful ways:
|
||||
|
||||
1. Converse will wait for all handlers of a hook to finish before continuing inside the function from where the hook was triggered.
|
||||
2. Each hook contains a payload, which the handlers can modify or extend, before returning it (either to the function that triggered the hook or to subsequent handlers).
|
||||
|
||||
These two properties of hooks makes it possible for 3rd party plugins to
|
||||
intercept and update data, allowing them to modify Converse without the need of
|
||||
resorting to `overrides`_.
|
||||
|
||||
A hook is triggered in the following way:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
async function hookTriggerExample () {
|
||||
const payload = { foo: 'bar' };
|
||||
const updated_payload = await api.hook('hookName', this, payload);
|
||||
return updated_payload;
|
||||
}
|
||||
|
||||
The above could be shortened:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
async function hookTriggerExample () {
|
||||
return await api.hook('hookName', this, { foo: 'bar' });
|
||||
}
|
||||
|
||||
The ``async/await`` syntax could also be removed, but then it's less clear to
|
||||
the reader that this function returns a promise.
|
||||
|
||||
Let's assume that in a plugin somewhere a listener is registered for this hook:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
function hookListenerExample () {
|
||||
|
||||
api.listen.on('hookname', (context, payload) => {
|
||||
return {...payload, 'baz': 'buzz'};
|
||||
});
|
||||
}
|
||||
|
||||
The ``context`` parameter in our listener is usually the ``this`` of the function
|
||||
that triggered the hook (as is the case in ``hookTriggerExample``),
|
||||
but could also be a ``Model`` instance.
|
||||
|
||||
The ``payload`` parameter is the same payload that was passed in in
|
||||
``hookTriggerExample``.
|
||||
|
||||
The ``hookListenerExample`` function accepts the payload and returns a new one
|
||||
which contains the original payload together with a new key and value.
|
||||
|
||||
The ``updated_payload`` that is now returned from ``hookTriggerExample`` looks
|
||||
as follows:
|
||||
|
||||
::
|
||||
|
||||
{ foo: 'bar', bazz: 'buzz' }
|
||||
|
||||
Our plugin was able to add data to the payload without requiring any kind of
|
||||
knowledge from ``hookTriggerExample`` about ``hookListenerExample`` and
|
||||
without any kind of coupling betwee the code.
|
||||
|
||||
A good example of a real-world hook in Converse, is the
|
||||
`getMessageActionButtons <https://conversejs.org/docs/html/api/-_converse.html#event:getMessageActionButtons>`_
|
||||
which allows you to add, modify or delete the actions you can take on a message
|
||||
in a chat.
|
||||
|
||||
The `Actions <https://github.com/conversejs/community-plugins/tree/master/packages/actions>`_
|
||||
3rd party community plugin makes use of this hook to add extra actions such as
|
||||
``like`` or ``dislike`` to chat messages.
|
||||
|
||||
|
||||
An example plugin
|
||||
-----------------
|
||||
|
||||
Below follows a documented example of a plugin. This is the same code that gets
|
||||
generated by `generator-conversejs <https://github.com/jcbrand/generator-conversejs>`_.
|
||||
@ -534,8 +604,8 @@ generated by `generator-conversejs <https://github.com/jcbrand/generator-convers
|
||||
* _converse.api.promises.add('myPromise');
|
||||
*
|
||||
* Your plugin should then, when appropriate, resolve the
|
||||
* promise by calling `_converse.api.emit`, which will also
|
||||
* emit an event with the same name as the promise.
|
||||
* promise by calling `_converse.api.trigger`, which will also
|
||||
* trigger an event with the same name as the promise.
|
||||
* For example:
|
||||
*
|
||||
* _converse.api.trigger('operationCompleted');
|
||||
@ -549,53 +619,22 @@ generated by `generator-conversejs <https://github.com/jcbrand/generator-convers
|
||||
*
|
||||
* _converse.api.waitUntil('operationCompleted', function { ... });
|
||||
*/
|
||||
},
|
||||
|
||||
/* If you want to override some function or a model or
|
||||
* view defined elsewhere in Converse, then you do that under
|
||||
* the "overrides" namespace.
|
||||
|
||||
/* In your plugin, you can also listen for hooks.
|
||||
* Hooks allow you to add or modify data and properties used by
|
||||
* Converse.
|
||||
*
|
||||
* For example, the getToolbarButtons hook allows you to add new buttons to the chat toolbar.
|
||||
* https://conversejs.org/docs/html/api/-_converse.html#event:getToolbarButtons
|
||||
*/
|
||||
overrides: {
|
||||
/* For example, the private *_converse* object has a
|
||||
* method "onConnected". You can override that method as follows:
|
||||
*/
|
||||
onConnected: function () {
|
||||
// Overrides the onConnected method in Converse
|
||||
|
||||
// Top-level functions in "overrides" are bound to the
|
||||
// inner "_converse" object.
|
||||
const _converse = this;
|
||||
|
||||
// Your custom code can come here ...
|
||||
|
||||
// You can access the original function being overridden
|
||||
// via the __super__ attribute.
|
||||
// Make sure to pass on the arguments supplied to this
|
||||
// function and also to apply the proper "this" object.
|
||||
_converse.__super__.onConnected.apply(this, arguments);
|
||||
|
||||
// Your custom code can come here ...
|
||||
},
|
||||
|
||||
/* Override Converse's XMPPStatus model so that we can override the
|
||||
* function that sends out the presence stanza.
|
||||
*/
|
||||
XMPPStatus: {
|
||||
sendPresence: function (type, status_message, jid) {
|
||||
// The "_converse" object is available via the __super__
|
||||
// attribute.
|
||||
const _converse = this.__super__._converse;
|
||||
|
||||
// Custom code can come here ...
|
||||
|
||||
// You can call the original overridden method, by
|
||||
// accessing it via the __super__ attribute.
|
||||
// When calling it, you need to apply the proper
|
||||
// context as reference by the "this" variable.
|
||||
this.__super__.sendPresence.apply(this, arguments);
|
||||
|
||||
// Custom code can come here ...
|
||||
}
|
||||
}
|
||||
api.listen.on('getToolbarButtons', (toolbar_el, buttons) => {
|
||||
buttons.push(html`
|
||||
<button class="my-button" @click=${alert('hello world!')}>
|
||||
<converse-icon class="fa fa-eye" size="1em" color="blue"></converse-icon>
|
||||
</button>
|
||||
`);
|
||||
return buttons;
|
||||
});
|
||||
}
|
||||
});
|
||||
|
@ -21,8 +21,9 @@ Let your XMPP server serve Converse for you
|
||||
If you run your own XMPP server, you might first want to check whether it has
|
||||
a plugin or module for hosting Converse.
|
||||
|
||||
* OpenFire has the `inverse <https://www.igniterealtime.org/projects/openfire/plugin-archive.jsp?plugin=inverse>`_ plugin.
|
||||
* Prosody has `mod_conversejs <https://modules.prosody.im/mod_conversejs.html>`_.
|
||||
* `Openfire <http://www.igniterealtime.org/projects/openfire/>`_ has the `inverse <https://www.igniterealtime.org/projects/openfire/plugin-archive.jsp?plugin=inverse>`_ plugin.
|
||||
* `Prosody <https://prosody.im/>`_ has `mod_conversejs <https://modules.prosody.im/mod_conversejs.html>`_.
|
||||
* `ejabberd <http://www.ejabberd.im/>`_ has `mod_conversejs <https://docs.ejabberd.im/admin/configuration/modules/#mod-conversejs>`_.
|
||||
|
||||
|
||||
Serving Converse yourself
|
||||
@ -55,16 +56,16 @@ might break when a new backwards-incompatible version of Converse is released.
|
||||
|
||||
To load a specific version of Converse you can put the version in the URL:
|
||||
|
||||
* https://cdn.conversejs.org/7.0.1/dist/converse.min.js
|
||||
* https://cdn.conversejs.org/7.0.1/dist/converse.min.css
|
||||
* https://cdn.conversejs.org/10.1.6/dist/converse.min.js
|
||||
* https://cdn.conversejs.org/10.1.6/dist/converse.min.css
|
||||
|
||||
You can include these two URLs inside the *<head>* element of your website
|
||||
via the *script* and *link* tags:
|
||||
|
||||
.. code-block:: html
|
||||
|
||||
<link rel="stylesheet" type="text/css" media="screen" href="https://cdn.conversejs.org/7.0.1/dist/converse.min.css">
|
||||
<script src="https://cdn.conversejs.org/7.0.1/dist/converse.min.js" charset="utf-8"></script>
|
||||
<link rel="stylesheet" type="text/css" media="screen" href="https://cdn.conversejs.org/10.1.6/dist/converse.min.css">
|
||||
<script src="https://cdn.conversejs.org/10.1.6/dist/converse.min.js" charset="utf-8"></script>
|
||||
|
||||
|
||||
Option 2: Download the builds from Github
|
||||
|
@ -1,6 +1,6 @@
|
||||
.. raw:: html
|
||||
|
||||
<div id="banner"><a href="https://github.com/jcbrand/converse.js/blob/master/docs/source/theming.rst">Edit me on GitHub</a></div>
|
||||
<div id="banner"><a href="https://github.com/jcbrand/converse.js/blob/master/docs/source/security.rst">Edit me on GitHub</a></div>
|
||||
|
||||
=======================
|
||||
Security considerations
|
||||
|
@ -1,8 +1,6 @@
|
||||
.. raw:: html
|
||||
|
||||
<div id="banner"><a href="https://github.com/jcbrand/converse.js/blob/master/docs/source/setup.rst">Edit me on GitHub</a></div>
|
||||
|
||||
.. _what-you-will-need:
|
||||
<div id="banner"><a href="https://github.com/jcbrand/converse.js/blob/master/docs/source/session.rst">Edit me on GitHub</a></div>
|
||||
|
||||
==================
|
||||
Session Management
|
||||
@ -204,5 +202,4 @@ Storing the SASL SCRAM-SHA1 hash in IndexedDB
|
||||
Another suggestion that's been suggested is to store the SCRAM-SHA1 computed
|
||||
``clientKey`` in localStorage and to use that upon page reload to log the user in again.
|
||||
|
||||
We might implement this feature in core Converse.js eventually.
|
||||
As always, contributions welcome!
|
||||
This has been implemented since version 10, see documentation on `reuse_scram_keys <https://conversejs.org/docs/html/configuration.html#reuse-scram-keys>`_
|
||||
|
140
docs/source/setup_dev_environment.rst
Normal file
@ -0,0 +1,140 @@
|
||||
.. raw:: html
|
||||
|
||||
<div id="banner"><a href="https://github.com/jcbrand/converse.js/blob/master/docs/source/setup_dev_environment.rst">Edit me on GitHub</a></div>
|
||||
|
||||
.. _`setup_dev_environment`:
|
||||
|
||||
============================
|
||||
Setting up a dev environment
|
||||
============================
|
||||
|
||||
Installing the 3rd party dependencies
|
||||
=====================================
|
||||
|
||||
To develop and customize Converse, you'll first need to check out Converse's Git
|
||||
repository:
|
||||
|
||||
::
|
||||
|
||||
git clone https://github.com/conversejs/converse.js.git
|
||||
cd converse.js
|
||||
|
||||
|
||||
We use development tools which depend on Node.js and NPM (the Node package manager).
|
||||
|
||||
It's recommended that you use `NVM <https://github.com/nvm-sh/nvm>`_ (the Node version manager)
|
||||
to make sure you have the right version of Node.
|
||||
|
||||
Refer to the `NVM Github page <https://github.com/nvm-sh/nvm#install--update-script>`_ for instructions on how to install it.
|
||||
|
||||
Once NVM is installed, you can run the following inside your checkout of the Converse Git repository:
|
||||
|
||||
::
|
||||
|
||||
nvm install
|
||||
|
||||
.. note::
|
||||
You will always have to first run ``nvm install`` in a new terminal session in order to use the
|
||||
recommended version of Node before working on Converse.
|
||||
|
||||
|
||||
To set up the Converse development environment, you now run ``make dev``.
|
||||
|
||||
::
|
||||
|
||||
make dev
|
||||
|
||||
Alternatively, if you're using Windows, or don't have GNU Make installed, you can run the
|
||||
following:
|
||||
|
||||
::
|
||||
|
||||
npm install
|
||||
npm run lerna
|
||||
|
||||
This will install the Node development tools and Converse's dependencies.
|
||||
|
||||
The front-end dependencies are those JavaScript files on which
|
||||
Converse directly depends and which will be loaded in the browser as part of
|
||||
the bundle in ``dist/converse.js`` (or ``dist/converse.min.js``).
|
||||
|
||||
To see the 3rd party dependencies (not just the front-end dependencies, but
|
||||
also ones necessary for development tasks like making builds), take a look at
|
||||
the list under the ``devDependencies`` in `package.json <https://github.com/jcbrand/converse.js/blob/master/package.json>`_.
|
||||
|
||||
.. note::
|
||||
After running ```make dev```, you should now have a new *node_modules* directory
|
||||
which contains all the external dependencies of Converse.
|
||||
If this directory does NOT exist, something must have gone wrong.
|
||||
Double-check the output of ```make dev``` to see if there are any errors
|
||||
listed. For support, you can ask in our chatroom: `dicuss@conference.conversejs.org <xmpp:discuss@conference.conversejs.org>`_.
|
||||
|
||||
If you don't have an XMPP client installed, follow this link to
|
||||
`conversejs.org <https://conversejs.org/fullscreen#converse/room?jid=discuss@conference.conversejs.org>`_
|
||||
where you can log in and be taken directly to the chatroom.
|
||||
|
||||
|
||||
.. _`dependency-libsignal`:
|
||||
|
||||
Libsignal
|
||||
---------
|
||||
|
||||
If you want OMEMO encryption, you need to load `libsignal <https://github.com/signalapp/libsignal-protocol-javascript>`_ separately in your page.
|
||||
|
||||
For example::
|
||||
|
||||
<script src="3rdparty/libsignal-protocol-javascript/dist/libsignal-protocol.js"></script>
|
||||
|
||||
The reason libsignal needs to be loaded separately is because it's released
|
||||
under the `GPLv3 <https://github.com/signalapp/libsignal-protocol-javascript/blob/master/LICENSE>`_
|
||||
which requires all other dependent JavaScript code to also be open sourced under the same
|
||||
license. You might not be willing to adhere to those terms, which is why you
|
||||
need to decide for yourself whether you're going to load libsignal or not.
|
||||
|
||||
|
||||
.. _`webserver`:
|
||||
|
||||
Setting up a webserver
|
||||
======================
|
||||
|
||||
When making changes to Converse, either development or theming changes,
|
||||
you'll want to preview them in your browser.
|
||||
|
||||
For this, you'll need to serve the development files via a web server,
|
||||
so that you can see your local changes in the browser.
|
||||
|
||||
Manually starting a web server
|
||||
------------------------------
|
||||
|
||||
To both set up the development environment and also start up a web browser to
|
||||
serve the files for you, you can run::
|
||||
|
||||
make serve
|
||||
|
||||
.. note::
|
||||
To run the "make" commands, you'll need `GNUMake <https://www.gnu.org/software/make>`_
|
||||
installed on your computer. If you use GNU/Linux or \*BSD, it should be installed or
|
||||
available via your package manager. For Mac, you'll need to install XCode and in
|
||||
Windows you can use `Chocolatey <https://chocolatey.org/>`_.
|
||||
|
||||
After running ``make serve`` you can open http://localhost:8000 in your webbrowser to see the Converse website.
|
||||
|
||||
When developing or changing the theme, you'll want to load all the
|
||||
unminified JS and CSS resources as separate files. To do this, open http://localhost:8000/dev.html instead.
|
||||
|
||||
You might want to open `dev.html <https://github.com/conversejs/converse.js/blob/master/dev.html>`_ in your text editor or IDE as well, to see
|
||||
how ``converse.initialize`` is called and to potentially change any of the
|
||||
settings.
|
||||
|
||||
Starting a web server with live reloading
|
||||
-----------------------------------------
|
||||
|
||||
Alternatively, if you want to have live reloading whenever any of the source files change, you
|
||||
can run ``make devserver`` (which will use `webpack-dev-server <https://github.com/webpack/webpack-dev-server>`_).
|
||||
|
||||
Instead of ``dev.html`` being used, `webpack.html <https://github.com/conversejs/converse.js/blob/master/webpack.html>`_
|
||||
is now being used as the HTML template, and you'll need to modify that file if
|
||||
you want to change the settings passed to ``converse.initialize``.
|
||||
|
||||
If you're running ``make devserver``, you need to open http://localhost:8080.
|
||||
|
@ -1,6 +1,6 @@
|
||||
.. raw:: html
|
||||
|
||||
<div id="banner"><a href="https://github.com/jcbrand/converse.js/blob/master/docs/source/theming.rst">Edit me on GitHub</a></div>
|
||||
<div id="banner"><a href="https://github.com/jcbrand/converse.js/blob/master/docs/source/style_guide.rst">Edit me on GitHub</a></div>
|
||||
|
||||
Software Style Guide
|
||||
====================
|
||||
@ -11,7 +11,7 @@ Most of the style guide recommendations here come from Douglas Crockford's book
|
||||
Tabs or spaces?
|
||||
---------------
|
||||
|
||||
We always indent 4 spaces. Proper indentation is important for readability.
|
||||
We always indent 4 spaces.
|
||||
|
||||
Underscores or camelCase?
|
||||
-------------------------
|
||||
@ -27,6 +27,12 @@ For example:
|
||||
...
|
||||
}
|
||||
|
||||
const versus let
|
||||
----------------
|
||||
|
||||
Try to use `const` whenever possible. If a variable won't be reassigned, use
|
||||
`const`, otherwise use `let`.
|
||||
|
||||
Spaces around operators
|
||||
-----------------------
|
||||
|
||||
@ -51,6 +57,19 @@ An exception is when they appear inside for-loop expressions, for example:
|
||||
Generally though, rather err on the side of adding spaces, since they make the
|
||||
code much more readable.
|
||||
|
||||
destructuring
|
||||
-------------
|
||||
|
||||
When assigning to a variable via destructuring, add spaces between the curly
|
||||
brackets.
|
||||
|
||||
For example:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
const { foo } = bar;
|
||||
|
||||
|
||||
Global constants are written in ALL_CAPS
|
||||
----------------------------------------
|
||||
|
||||
|
@ -29,21 +29,17 @@ Automatically run tests on file changes
|
||||
***************************************
|
||||
|
||||
To automatically run the tests whenever you make a change to any of the
|
||||
Converse source code, you can run ``make watch`` in one terminal, and ``make
|
||||
tests`` or ``make check`` in another.
|
||||
Converse source code, you can run ``make watch`` in one terminal, and ``make tests`` in another.
|
||||
|
||||
``make watch`` will build development bundles of Converse.js (in
|
||||
``dist/converse.js`` and ``dist/converse.css``) and automatically rebuild them
|
||||
whenever a source file is modified.
|
||||
|
||||
Similarly, Karma will make sure that the tests are re-executed when the
|
||||
bundle files are rebuilt.
|
||||
``make watch`` will build development bundles of Converse (in ``dist/converse.js`` and ``dist/converse.css``)
|
||||
and automatically rebuild them whenever a source file is modified.
|
||||
|
||||
Similarly, Karma will make sure that the tests are re-executed when the bundle files are rebuilt.
|
||||
|
||||
Running individual tests
|
||||
************************
|
||||
|
||||
Converse has over 400 tests, and it can take a few minutes to run through all of them.
|
||||
Converse has over 400 tests, and it can take a while to run through all of them.
|
||||
|
||||
When developing on Converse, it's often preferable to have a more rapid
|
||||
turnaround time between editing a file and checking whether the most relevant
|
||||
|
@ -11,61 +11,135 @@ Theming
|
||||
Setting up your environment
|
||||
===========================
|
||||
|
||||
In order to theme Converse, you first need to set up a :ref:`development` environment.
|
||||
In order to theme Converse, you first need to follow the steps for :ref:`setup_dev_environment`, including :ref:`webserver`.
|
||||
|
||||
You'll also want to preview the changes you make in your browser, for which a
|
||||
webserver will be useful.
|
||||
Creating a custom theme
|
||||
=======================
|
||||
|
||||
To both set up the development environment and also start up a web browser to
|
||||
serve the files for you, simply run::
|
||||
Converse can be themed via CSS custom properties (aka CSS variables) and it has
|
||||
some themes available in its source repository.
|
||||
|
||||
make serve
|
||||
A theme is a CSS file with a specific rule that defines the theme's CSS properties.
|
||||
The rule has a specific selector that must include (and determines) the theme name.
|
||||
|
||||
.. note::
|
||||
To run the "make" commands, you'll need `GNUMake <https://www.gnu.org/software/make>`_
|
||||
installed on your computer. If you use GNU/Linux or \*BSD, it should be installed or
|
||||
available via your package manager. For Mac, I think you need to install XCode and in
|
||||
Windows you can use `Chocolatey <https://chocolatey.org/>`_.
|
||||
Inside this CSS rule, various CSS variables are assigned values.
|
||||
The CSS variables mainly refer to the colors that comprise the theme.
|
||||
If you don't specify a value for a specific CSS variable, then the value from
|
||||
the ``classic`` theme is used, as defined in `classic.scss <https://github.com/conversejs/converse.js/tree/master/src/shared/styles/themes/classic.scss>`_.
|
||||
|
||||
After running ``make serve`` you can open http://localhost:8000 in your webbrowser you'll
|
||||
see the Converse website.
|
||||
The native theme files can be found in `shared/styles/themes <https://github.com/conversejs/converse.js/tree/master/src/shared/styles/themes>`_.
|
||||
|
||||
However, when developing or changing the theme, you'll want to load all the
|
||||
unminified JS and CSS resources as separate files. To do this, open http://localhost:8000/dev.html
|
||||
instead.
|
||||
Note, the Converse theme files have a ``.scss`` extension because they are compiled
|
||||
by the Sass compiler into normal CSS files. It's however not necessary to use
|
||||
Sass, basic CSS files will also suffice.
|
||||
|
||||
The theme that Converse uses can be set via the :ref:`theme` configuration
|
||||
setting (and the :ref:`dark_theme` configuration setting for dark mode).
|
||||
|
||||
How are themes applied?
|
||||
-----------------------
|
||||
|
||||
When you set a value for the :ref:`theme` configuration setting, Converse will add
|
||||
a class ``theme-${api.settings.get('theme')}`` on the ``converse-root`` DOM
|
||||
element.
|
||||
|
||||
So, for example, if you set the ``theme`` setting to ``"dracula"``, then the
|
||||
``converse-root`` element will get the class ``theme-dracula``.
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
converse.initialize({ theme: "dracula" });
|
||||
|
||||
|
||||
Modifying the HTML templates of Converse
|
||||
========================================
|
||||
.. code-block:: html
|
||||
|
||||
The HTML markup of Converse is contained in small ``.html`` files in the
|
||||
``./src/templates`` directory.
|
||||
<converse-root class="conversejs theme-dracula"></converse-root>
|
||||
|
||||
You can modify HTML markup that Converse generates by modifying these files.
|
||||
|
||||
The apply a theme, there then needs to be a CSS rule with a selector that matches the
|
||||
``theme-dracula`` class on the ``converse-root`` element.
|
||||
|
||||
If you take a look at the theme file `dracula.scss <https://github.com/conversejs/converse.js/tree/master/src/shared/styles/themes/dracula.scss>`_
|
||||
you'll see that it defines a CSS rule with the selector
|
||||
``.conversejs.theme-dracula``.
|
||||
|
||||
This selector matches any DOM element with both the classes ``.conversejs`` and
|
||||
``.theme-dracula``. The ``converse-root`` element will already have the class
|
||||
``.conversejs`` and it will have the class ``.theme-dracula`` if the ``theme``
|
||||
(or ``dark_theme`` in dark mode) configuration setting is set to ``"dracula"``.
|
||||
|
||||
This is how themes are applied, by defining a CSS selector that matches the
|
||||
class ``.theme-${name}`` (where ``name`` is a variable containing the name of
|
||||
the theme), and then setting the ``theme`` (and/or ``dark_theme``) configuration
|
||||
setting.
|
||||
|
||||
To create your own theme, you can create a similar CSS rule that matches
|
||||
your theme's name and then you set the ``theme`` configuration setting to that
|
||||
name. This CSS rule can be in any CSS file that is loaded in your website, or
|
||||
you can even put it in the DOM as an inline style.
|
||||
|
||||
Modifying the CSS
|
||||
=================
|
||||
|
||||
The CSS files are generated from `Sass <http://sass-lang.com>`_ files in the ``./sass`` directory.
|
||||
To create a new theme with different colors, it should be enough to create a
|
||||
theme file that sets the various CSS variables (as described above).
|
||||
|
||||
To generate the CSS you can run::
|
||||
For other CSS-related changes, you can make a specific
|
||||
CSS rule with that matches the element you want to change.
|
||||
|
||||
Sometimes it might however be neccessary to modify the core CSS files from
|
||||
Converse, for example if you're developing new features or fixing styling bugs.
|
||||
|
||||
The CSS files are generated from `Sass <http://sass-lang.com>`_ files that end in ``.scss`` and
|
||||
which are distributed throughout the source code.
|
||||
|
||||
The CSS that is relevant to a particular plugin
|
||||
is usually inside the ``./styles`` directory inside the relevant plugin directory.
|
||||
|
||||
For example: `src/plugins/controlbox/styles <https://github.com/conversejs/converse.js/tree/master/src/plugins/controlbox/styles>`_.
|
||||
|
||||
If you're running ``make watch``, then the CSS will automatically be
|
||||
regenerated when you've changed any of the ``.scss``.
|
||||
|
||||
You can also manually generate the CSS::
|
||||
|
||||
make css
|
||||
|
||||
Testing your changes
|
||||
====================
|
||||
Modifying the HTML templates of Converse
|
||||
========================================
|
||||
|
||||
The recommended way to test your changes is to run the tests that are part of the Converse source code.
|
||||
By executing ``make test`` you'll run all tests (which live in the ``spec`` folder) which will open a browser window in which tests are processed.
|
||||
Converse uses `lit-html <https://lit.dev/docs/libraries/standalone-templates/>`_ as HTML
|
||||
templating library, and the HTML source code is contained in JavaScript ``.js``
|
||||
files in various ``./template`` directories in the source code.
|
||||
|
||||
You can run a single test by changing ``it(`` to ``fit(`` so that only that one test runs. Then you click the "debug" button in the browser when the tests run. After the test has run, the opened chats will still be visible.
|
||||
Some top-level templates are also in the ``./src/templates`` directory, but
|
||||
the templates that are relevant to a specific plugin should be inside that plugin's subdirectory.
|
||||
|
||||
For example: `src/plugins/chatview/templates <https://github.com/conversejs/converse.js/tree/master/src/plugins/chatview/templates>`_.
|
||||
|
||||
Creating dist files
|
||||
===================
|
||||
You can modify HTML markup that Converse generates by modifying these files.
|
||||
|
||||
Once you've themed Converse, you'll want to create new minified distribution
|
||||
files of all the JavaScript and CSS.
|
||||
Use webpack aliases to modify templates without changing the original files
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
Please refer to the :doc:`builds` section for information on how this is done.
|
||||
Generally what I do when creating a modified version of Converse for a project
|
||||
or customer, is that I create a new JavaScript package with its own
|
||||
``package.json`` and I then add ``converse.js`` as a dependency (e.g. via ``npm
|
||||
install --save converse.js``) to the ``package.json``.
|
||||
|
||||
Then I add a Webpack configuration and use `webpack aliases <https://webpack.js.org/configuration/resolve/#resolvealias>`_
|
||||
to resolve template paths to my own modified files.
|
||||
|
||||
For example, in the webpack configuration snippet below, I add two aliases, so
|
||||
that the ``message-body.js`` and ``message.js`` templates can be replaced with
|
||||
two of my own custom templates.
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
resolve: {
|
||||
extensions: ['.js'],
|
||||
alias: {
|
||||
'./message-body.js': path.resolve(__dirname, 'path/to/my/custom/message-body.js'),
|
||||
'./templates/message.js': path.resolve(__dirname, 'path/to/my/custom/chat_message.js'),
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
.. raw:: html
|
||||
|
||||
<div id="banner"><a href="https://github.com/jcbrand/converse.js/blob/master/docs/source/setup.rst">Edit me on GitHub</a></div>
|
||||
<div id="banner"><a href="https://github.com/jcbrand/converse.js/blob/master/docs/source/troubleshooting.rst">Edit me on GitHub</a></div>
|
||||
|
||||
=============================
|
||||
Troubleshooting and debugging
|
||||
@ -114,6 +114,89 @@ what you're using as the HTTP file server.
|
||||
CORS is enabled by adding an ``Access-Control-Allow-Origin`` header, so you'll
|
||||
have to configure your file server to add this header.
|
||||
|
||||
Users don't stay logged in across page reloads
|
||||
==============================================
|
||||
|
||||
A common complaint in the Converse chat room (`<xmpp:discuss@conference.conversejs.org?join>`_)
|
||||
is that users are logged out when they reload the page.
|
||||
|
||||
The main way in which websites and web apps maintain a user's login session is via
|
||||
authentication cookies, which are included in every HTTP request sent to the server.
|
||||
|
||||
XMPP is however not HTTP, cookies aren't automatically included in traffic to
|
||||
the XMPP server and XMPP servers don't rely on cookies for authentication.
|
||||
|
||||
Instead, an XMPP client is expected to store the user credentials (username and
|
||||
password, either plaintext or hashed and salted if
|
||||
`SCRAM <https://en.wikipedia.org/wiki/Salted_Challenge_Response_Authentication_Mechanism>`_
|
||||
is being used) and to then present those credentials to the XMPP server when authenticating.
|
||||
|
||||
This works well for non-web XMPP clients, but Converse has so far avoided
|
||||
storing user credentials in browser storage, since they can then be accessed by
|
||||
any scripts running in the browser under the same domain.
|
||||
|
||||
So what does Converse do to keep users logged in?
|
||||
-------------------------------------------------
|
||||
|
||||
Use the Web Auth API
|
||||
********************
|
||||
|
||||
Converse supports the `Web Authentication API <https://developer.mozilla.org/en-US/docs/Web/API/Web_Authentication_API>`_
|
||||
which let's it use the secure credential management of the browser to get the
|
||||
uesr credentials to automatically log the user in. This however requires that
|
||||
the user saves his or her username and password in the browser. Often the user
|
||||
is automatically asked by the browser whether he/she wants to store the
|
||||
credentials. If that doesn't happen, the user has to do so manually, usually by
|
||||
clicking the key icon in the address bar. This works well on most modern browsers,
|
||||
but not on Firefox, which has insufficient support for the Web Authentication API.
|
||||
|
||||
What can users do to stay logged in?
|
||||
------------------------------------
|
||||
|
||||
Outsource credential management to something else
|
||||
*************************************************
|
||||
|
||||
The issues mentioned above mostly related to users logging in manually, and not
|
||||
to integrations where Converse automatically fetches user credentials from the
|
||||
backend via the :ref:`credentials_url` setting.
|
||||
|
||||
Use BOSH instead of websocket
|
||||
*****************************
|
||||
|
||||
`BOSH <https://xmpp.org/extensions/xep-0206.html>`_ can be thought of
|
||||
XMPP-over-HTTP and because HTTP is stateless, BOSH needs to maintain login
|
||||
sessions for a certain amount of time (usually 60 seconds) even if there is no
|
||||
HTTP traffic between the client and server. This means that if you have a BOSH
|
||||
session running, you can reload the page and you will stay logged in.
|
||||
|
||||
Note, Websocket connections are however faster and have less overhead than BOSH.
|
||||
|
||||
User a browser with adequate support for the Web Auth API
|
||||
*********************************************************
|
||||
|
||||
Another option is to only use a browser with proper support for the Web Auth
|
||||
API (which mainly means avoiding Firefox) and then to save your credentials in the browser.
|
||||
|
||||
Use Converse Desktop
|
||||
********************
|
||||
|
||||
The `desktop version of Converse <https://github.com/conversejs/converse-desktop>`_
|
||||
also doesn't have this problem, since the credentials are stored in Electron
|
||||
and there is no significant risk of other malicious scripts running.
|
||||
|
||||
What else can Converse do to keep users logged in?
|
||||
--------------------------------------------------
|
||||
|
||||
This problem could also potentially be fixed by storing the
|
||||
XMPP credentials securely with web crypto and IndexedDB. This could be done by
|
||||
generating a private encryption key in non-exportable format, and then using that
|
||||
to encrypt the credentials before storing them in IndexedDB.
|
||||
|
||||
This would protect the credentials from someone who has access to your
|
||||
computer (or harddrive), but it still won't protect them from malicious scripts
|
||||
running in the same domain as Converse is being hosted, since they would have the
|
||||
same level of access as Converse itself (which legitimately needs access to the
|
||||
credentials).
|
||||
|
||||
Common errors
|
||||
=============
|
||||
|
@ -3,6 +3,8 @@
|
||||
<head>
|
||||
<title>Converse</title>
|
||||
<meta charset="utf-8"/>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||
<meta name="description" content="Converse XMPP/Jabber Chat"/>
|
||||
<meta name="author" content="JC Brand" />
|
||||
|
220
images/icons.svg
@ -1,220 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Font Awesome Free 5.13.0 by @fontawesome - https://fontawesome.com
|
||||
License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
|
||||
-->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
|
||||
<symbol id="icon-address-book" viewBox="0 0 448 512">
|
||||
<path d="M436 160c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-20V48c0-26.5-21.5-48-48-48H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h320c26.5 0 48-21.5 48-48v-48h20c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-20v-64h20c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-20v-64h20zm-228-32c35.3 0 64 28.7 64 64s-28.7 64-64 64-64-28.7-64-64 28.7-64 64-64zm112 236.8c0 10.6-10 19.2-22.4 19.2H118.4C106 384 96 375.4 96 364.8v-19.2c0-31.8 30.1-57.6 67.2-57.6h5c12.3 5.1 25.7 8 39.8 8s27.6-2.9 39.8-8h5c37.1 0 67.2 25.8 67.2 57.6v19.2z"></path>
|
||||
</symbol>
|
||||
<symbol id="icon-angle-double-down" viewBox="0 0 320 512">
|
||||
<path d="M143 256.3L7 120.3c-9.4-9.4-9.4-24.6 0-33.9l22.6-22.6c9.4-9.4 24.6-9.4 33.9 0l96.4 96.4 96.4-96.4c9.4-9.4 24.6-9.4 33.9 0L313 86.3c9.4 9.4 9.4 24.6 0 33.9l-136 136c-9.4 9.5-24.6 9.5-34 .1zm34 192l136-136c9.4-9.4 9.4-24.6 0-33.9l-22.6-22.6c-9.4-9.4-24.6-9.4-33.9 0L160 352.1l-96.4-96.4c-9.4-9.4-24.6-9.4-33.9 0L7 278.3c-9.4 9.4-9.4 24.6 0 33.9l136 136c9.4 9.5 24.6 9.5 34 .1z"></path>
|
||||
</symbol>
|
||||
<symbol id="icon-angle-double-left" viewBox="0 0 448 512">
|
||||
<path d="M223.7 239l136-136c9.4-9.4 24.6-9.4 33.9 0l22.6 22.6c9.4 9.4 9.4 24.6 0 33.9L319.9 256l96.4 96.4c9.4 9.4 9.4 24.6 0 33.9L393.7 409c-9.4 9.4-24.6 9.4-33.9 0l-136-136c-9.5-9.4-9.5-24.6-.1-34zm-192 34l136 136c9.4 9.4 24.6 9.4 33.9 0l22.6-22.6c9.4-9.4 9.4-24.6 0-33.9L127.9 256l96.4-96.4c9.4-9.4 9.4-24.6 0-33.9L201.7 103c-9.4-9.4-24.6-9.4-33.9 0l-136 136c-9.5 9.4-9.5 24.6-.1 34z"></path>
|
||||
</symbol>
|
||||
<symbol id="icon-angle-double-right" viewBox="0 0 448 512">
|
||||
<path d="M224.3 273l-136 136c-9.4 9.4-24.6 9.4-33.9 0l-22.6-22.6c-9.4-9.4-9.4-24.6 0-33.9l96.4-96.4-96.4-96.4c-9.4-9.4-9.4-24.6 0-33.9L54.3 103c9.4-9.4 24.6-9.4 33.9 0l136 136c9.5 9.4 9.5 24.6.1 34zm192-34l-136-136c-9.4-9.4-24.6-9.4-33.9 0l-22.6 22.6c-9.4 9.4-9.4 24.6 0 33.9l96.4 96.4-96.4 96.4c-9.4 9.4-9.4 24.6 0 33.9l22.6 22.6c9.4 9.4 24.6 9.4 33.9 0l136-136c9.4-9.2 9.4-24.4 0-33.8z"></path>
|
||||
</symbol>
|
||||
<symbol id="icon-angle-double-up" viewBox="0 0 320 512">
|
||||
<path d="M177 255.7l136 136c9.4 9.4 9.4 24.6 0 33.9l-22.6 22.6c-9.4 9.4-24.6 9.4-33.9 0L160 351.9l-96.4 96.4c-9.4 9.4-24.6 9.4-33.9 0L7 425.7c-9.4-9.4-9.4-24.6 0-33.9l136-136c9.4-9.5 24.6-9.5 34-.1zm-34-192L7 199.7c-9.4 9.4-9.4 24.6 0 33.9l22.6 22.6c9.4 9.4 24.6 9.4 33.9 0l96.4-96.4 96.4 96.4c9.4 9.4 24.6 9.4 33.9 0l22.6-22.6c9.4-9.4 9.4-24.6 0-33.9l-136-136c-9.2-9.4-24.4-9.4-33.8 0z"></path>
|
||||
</symbol>
|
||||
<symbol id="icon-angle-down" viewBox="0 0 320 512">
|
||||
<path d="M143 352.3L7 216.3c-9.4-9.4-9.4-24.6 0-33.9l22.6-22.6c9.4-9.4 24.6-9.4 33.9 0l96.4 96.4 96.4-96.4c9.4-9.4 24.6-9.4 33.9 0l22.6 22.6c9.4 9.4 9.4 24.6 0 33.9l-136 136c-9.2 9.4-24.4 9.4-33.8 0z"></path>
|
||||
</symbol>
|
||||
<symbol id="icon-angle-left" viewBox="0 0 256 512">
|
||||
<path d="M31.7 239l136-136c9.4-9.4 24.6-9.4 33.9 0l22.6 22.6c9.4 9.4 9.4 24.6 0 33.9L127.9 256l96.4 96.4c9.4 9.4 9.4 24.6 0 33.9L201.7 409c-9.4 9.4-24.6 9.4-33.9 0l-136-136c-9.5-9.4-9.5-24.6-.1-34z"></path>
|
||||
</symbol>
|
||||
<symbol id="icon-angle-right" viewBox="0 0 256 512">
|
||||
<path d="M224.3 273l-136 136c-9.4 9.4-24.6 9.4-33.9 0l-22.6-22.6c-9.4-9.4-9.4-24.6 0-33.9l96.4-96.4-96.4-96.4c-9.4-9.4-9.4-24.6 0-33.9L54.3 103c9.4-9.4 24.6-9.4 33.9 0l136 136c9.5 9.4 9.5 24.6.1 34z"></path>
|
||||
</symbol>
|
||||
<symbol id="icon-angle-up" viewBox="0 0 320 512">
|
||||
<path d="M177 159.7l136 136c9.4 9.4 9.4 24.6 0 33.9l-22.6 22.6c-9.4 9.4-24.6 9.4-33.9 0L160 255.9l-96.4 96.4c-9.4 9.4-24.6 9.4-33.9 0L7 329.7c-9.4-9.4-9.4-24.6 0-33.9l136-136c9.4-9.5 24.6-9.5 34-.1z"></path>
|
||||
</symbol>
|
||||
<symbol id="icon-arrow-alt-circle-down" viewBox="0 0 512 512">
|
||||
<path d="M504 256c0 137-111 248-248 248S8 393 8 256 119 8 256 8s248 111 248 248zM212 140v116h-70.9c-10.7 0-16.1 13-8.5 20.5l114.9 114.3c4.7 4.7 12.2 4.7 16.9 0l114.9-114.3c7.6-7.6 2.2-20.5-8.5-20.5H300V140c0-6.6-5.4-12-12-12h-64c-6.6 0-12 5.4-12 12z"></path>
|
||||
</symbol>
|
||||
<symbol id="icon-arrow-alt-circle-left" viewBox="0 0 512 512">
|
||||
<path d="M256 504C119 504 8 393 8 256S119 8 256 8s248 111 248 248-111 248-248 248zm116-292H256v-70.9c0-10.7-13-16.1-20.5-8.5L121.2 247.5c-4.7 4.7-4.7 12.2 0 16.9l114.3 114.9c7.6 7.6 20.5 2.2 20.5-8.5V300h116c6.6 0 12-5.4 12-12v-64c0-6.6-5.4-12-12-12z"></path>
|
||||
</symbol>
|
||||
<symbol id="icon-arrow-alt-circle-right" viewBox="0 0 512 512">
|
||||
<path d="M256 8c137 0 248 111 248 248S393 504 256 504 8 393 8 256 119 8 256 8zM140 300h116v70.9c0 10.7 13 16.1 20.5 8.5l114.3-114.9c4.7-4.7 4.7-12.2 0-16.9l-114.3-115c-7.6-7.6-20.5-2.2-20.5 8.5V212H140c-6.6 0-12 5.4-12 12v64c0 6.6 5.4 12 12 12z"></path>
|
||||
</symbol>
|
||||
<symbol id="icon-arrow-alt-circle-up" viewBox="0 0 512 512">
|
||||
<path d="M8 256C8 119 119 8 256 8s248 111 248 248-111 248-248 248S8 393 8 256zm292 116V256h70.9c10.7 0 16.1-13 8.5-20.5L264.5 121.2c-4.7-4.7-12.2-4.7-16.9 0l-115 114.3c-7.6 7.6-2.2 20.5 8.5 20.5H212v116c0 6.6 5.4 12 12 12h64c6.6 0 12-5.4 12-12z"></path>
|
||||
</symbol>
|
||||
<symbol id="icon-arrow-circle-down" viewBox="0 0 512 512">
|
||||
<path d="M504 256c0 137-111 248-248 248S8 393 8 256 119 8 256 8s248 111 248 248zm-143.6-28.9L288 302.6V120c0-13.3-10.7-24-24-24h-16c-13.3 0-24 10.7-24 24v182.6l-72.4-75.5c-9.3-9.7-24.8-9.9-34.3-.4l-10.9 11c-9.4 9.4-9.4 24.6 0 33.9L239 404.3c9.4 9.4 24.6 9.4 33.9 0l132.7-132.7c9.4-9.4 9.4-24.6 0-33.9l-10.9-11c-9.5-9.5-25-9.3-34.3.4z"></path>
|
||||
</symbol>
|
||||
<symbol id="icon-arrow-circle-left" viewBox="0 0 512 512">
|
||||
<path d="M256 504C119 504 8 393 8 256S119 8 256 8s248 111 248 248-111 248-248 248zm28.9-143.6L209.4 288H392c13.3 0 24-10.7 24-24v-16c0-13.3-10.7-24-24-24H209.4l75.5-72.4c9.7-9.3 9.9-24.8.4-34.3l-11-10.9c-9.4-9.4-24.6-9.4-33.9 0L107.7 239c-9.4 9.4-9.4 24.6 0 33.9l132.7 132.7c9.4 9.4 24.6 9.4 33.9 0l11-10.9c9.5-9.5 9.3-25-.4-34.3z"></path>
|
||||
</symbol>
|
||||
<symbol id="icon-arrow-circle-right" viewBox="0 0 512 512">
|
||||
<path d="M256 8c137 0 248 111 248 248S393 504 256 504 8 393 8 256 119 8 256 8zm-28.9 143.6l75.5 72.4H120c-13.3 0-24 10.7-24 24v16c0 13.3 10.7 24 24 24h182.6l-75.5 72.4c-9.7 9.3-9.9 24.8-.4 34.3l11 10.9c9.4 9.4 24.6 9.4 33.9 0L404.3 273c9.4-9.4 9.4-24.6 0-33.9L271.6 106.3c-9.4-9.4-24.6-9.4-33.9 0l-11 10.9c-9.5 9.6-9.3 25.1.4 34.4z"></path>
|
||||
</symbol>
|
||||
<symbol id="icon-arrow-circle-up" viewBox="0 0 512 512">
|
||||
<path d="M8 256C8 119 119 8 256 8s248 111 248 248-111 248-248 248S8 393 8 256zm143.6 28.9l72.4-75.5V392c0 13.3 10.7 24 24 24h16c13.3 0 24-10.7 24-24V209.4l72.4 75.5c9.3 9.7 24.8 9.9 34.3.4l10.9-11c9.4-9.4 9.4-24.6 0-33.9L273 107.7c-9.4-9.4-24.6-9.4-33.9 0L106.3 240.4c-9.4 9.4-9.4 24.6 0 33.9l10.9 11c9.6 9.5 25.1 9.3 34.4-.4z"></path>
|
||||
</symbol>
|
||||
<symbol id="icon-arrow-down" viewBox="0 0 448 512">
|
||||
<path d="M413.1 222.5l22.2 22.2c9.4 9.4 9.4 24.6 0 33.9L241 473c-9.4 9.4-24.6 9.4-33.9 0L12.7 278.6c-9.4-9.4-9.4-24.6 0-33.9l22.2-22.2c9.5-9.5 25-9.3 34.3.4L184 343.4V56c0-13.3 10.7-24 24-24h32c13.3 0 24 10.7 24 24v287.4l114.8-120.5c9.3-9.8 24.8-10 34.3-.4z"></path>
|
||||
</symbol>
|
||||
<symbol id="icon-arrow-left" viewBox="0 0 448 512">
|
||||
<path d="M257.5 445.1l-22.2 22.2c-9.4 9.4-24.6 9.4-33.9 0L7 273c-9.4-9.4-9.4-24.6 0-33.9L201.4 44.7c9.4-9.4 24.6-9.4 33.9 0l22.2 22.2c9.5 9.5 9.3 25-.4 34.3L136.6 216H424c13.3 0 24 10.7 24 24v32c0 13.3-10.7 24-24 24H136.6l120.5 114.8c9.8 9.3 10 24.8.4 34.3z"></path>
|
||||
</symbol>
|
||||
<symbol id="icon-arrow-right" viewBox="0 0 448 512">
|
||||
<path d="M190.5 66.9l22.2-22.2c9.4-9.4 24.6-9.4 33.9 0L441 239c9.4 9.4 9.4 24.6 0 33.9L246.6 467.3c-9.4 9.4-24.6 9.4-33.9 0l-22.2-22.2c-9.5-9.5-9.3-25 .4-34.3L311.4 296H24c-13.3 0-24-10.7-24-24v-32c0-13.3 10.7-24 24-24h287.4L190.9 101.2c-9.8-9.3-10-24.8-.4-34.3z"></path>
|
||||
</symbol>
|
||||
<symbol id="icon-arrow-up" viewBox="0 0 448 512">
|
||||
<path d="M34.9 289.5l-22.2-22.2c-9.4-9.4-9.4-24.6 0-33.9L207 39c9.4-9.4 24.6-9.4 33.9 0l194.3 194.3c9.4 9.4 9.4 24.6 0 33.9L413 289.4c-9.5 9.5-25 9.3-34.3-.4L264 168.6V456c0 13.3-10.7 24-24 24h-32c-13.3 0-24-10.7-24-24V168.6L69.2 289.1c-9.3 9.8-24.8 10-34.3.4z"></path>
|
||||
</symbol>
|
||||
<symbol id="icon-arrows-alt" viewBox="0 0 512 512">
|
||||
<path d="M352.201 425.775l-79.196 79.196c-9.373 9.373-24.568 9.373-33.941 0l-79.196-79.196c-15.119-15.119-4.411-40.971 16.971-40.97h51.162L228 284H127.196v51.162c0 21.382-25.851 32.09-40.971 16.971L7.029 272.937c-9.373-9.373-9.373-24.569 0-33.941L86.225 159.8c15.119-15.119 40.971-4.411 40.971 16.971V228H228V127.196h-51.23c-21.382 0-32.09-25.851-16.971-40.971l79.196-79.196c9.373-9.373 24.568-9.373 33.941 0l79.196 79.196c15.119 15.119 4.411 40.971-16.971 40.971h-51.162V228h100.804v-51.162c0-21.382 25.851-32.09 40.97-16.971l79.196 79.196c9.373 9.373 9.373 24.569 0 33.941L425.773 352.2c-15.119 15.119-40.971 4.411-40.97-16.971V284H284v100.804h51.23c21.382 0 32.09 25.851 16.971 40.971z"></path>
|
||||
</symbol>
|
||||
<symbol id="icon-arrows-alt-h" viewBox="0 0 512 512">
|
||||
<path d="M377.941 169.941V216H134.059v-46.059c0-21.382-25.851-32.09-40.971-16.971L7.029 239.029c-9.373 9.373-9.373 24.568 0 33.941l86.059 86.059c15.119 15.119 40.971 4.411 40.971-16.971V296h243.882v46.059c0 21.382 25.851 32.09 40.971 16.971l86.059-86.059c9.373-9.373 9.373-24.568 0-33.941l-86.059-86.059c-15.119-15.12-40.971-4.412-40.971 16.97z"></path>
|
||||
</symbol>
|
||||
<symbol id="icon-arrows-alt-v" viewBox="0 0 256 512">
|
||||
<path d="M214.059 377.941H168V134.059h46.059c21.382 0 32.09-25.851 16.971-40.971L144.971 7.029c-9.373-9.373-24.568-9.373-33.941 0L24.971 93.088c-15.119 15.119-4.411 40.971 16.971 40.971H88v243.882H41.941c-21.382 0-32.09 25.851-16.971 40.971l86.059 86.059c9.373 9.373 24.568 9.373 33.941 0l86.059-86.059c15.12-15.119 4.412-40.971-16.97-40.971z"></path>
|
||||
</symbol>
|
||||
<symbol id="icon-bars" viewBox="0 0 448 512">
|
||||
<path d="M16 132h416c8.837 0 16-7.163 16-16V76c0-8.837-7.163-16-16-16H16C7.163 60 0 67.163 0 76v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16z"></path>
|
||||
</symbol>
|
||||
<symbol id="icon-bookmark" viewBox="0 0 384 512">
|
||||
<path d="M0 512V48C0 21.49 21.49 0 48 0h288c26.51 0 48 21.49 48 48v464L192 400 0 512z"></path>
|
||||
</symbol>
|
||||
<symbol id="icon-caret-down" viewBox="0 0 320 512">
|
||||
<path d="M31.3 192h257.3c17.8 0 26.7 21.5 14.1 34.1L174.1 354.8c-7.8 7.8-20.5 7.8-28.3 0L17.2 226.1C4.6 213.5 13.5 192 31.3 192z"></path>
|
||||
</symbol>
|
||||
<symbol id="icon-caret-right" viewBox="0 0 192 512">
|
||||
<path d="M0 384.662V127.338c0-17.818 21.543-26.741 34.142-14.142l128.662 128.662c7.81 7.81 7.81 20.474 0 28.284L34.142 398.804C21.543 411.404 0 402.48 0 384.662z"></path>
|
||||
</symbol>
|
||||
<symbol id="icon-check" viewBox="0 0 512 512">
|
||||
<path d="M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z"></path>
|
||||
</symbol>
|
||||
<symbol id="icon-circle" viewBox="0 0 512 512">
|
||||
<path d="M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8z"></path>
|
||||
</symbol>
|
||||
<symbol id="icon-cog" viewBox="0 0 512 512">
|
||||
<path d="M487.4 315.7l-42.6-24.6c4.3-23.2 4.3-47 0-70.2l42.6-24.6c4.9-2.8 7.1-8.6 5.5-14-11.1-35.6-30-67.8-54.7-94.6-3.8-4.1-10-5.1-14.8-2.3L380.8 110c-17.9-15.4-38.5-27.3-60.8-35.1V25.8c0-5.6-3.9-10.5-9.4-11.7-36.7-8.2-74.3-7.8-109.2 0-5.5 1.2-9.4 6.1-9.4 11.7V75c-22.2 7.9-42.8 19.8-60.8 35.1L88.7 85.5c-4.9-2.8-11-1.9-14.8 2.3-24.7 26.7-43.6 58.9-54.7 94.6-1.7 5.4.6 11.2 5.5 14L67.3 221c-4.3 23.2-4.3 47 0 70.2l-42.6 24.6c-4.9 2.8-7.1 8.6-5.5 14 11.1 35.6 30 67.8 54.7 94.6 3.8 4.1 10 5.1 14.8 2.3l42.6-24.6c17.9 15.4 38.5 27.3 60.8 35.1v49.2c0 5.6 3.9 10.5 9.4 11.7 36.7 8.2 74.3 7.8 109.2 0 5.5-1.2 9.4-6.1 9.4-11.7v-49.2c22.2-7.9 42.8-19.8 60.8-35.1l42.6 24.6c4.9 2.8 11 1.9 14.8-2.3 24.7-26.7 43.6-58.9 54.7-94.6 1.5-5.5-.7-11.3-5.6-14.1zM256 336c-44.1 0-80-35.9-80-80s35.9-80 80-80 80 35.9 80 80-35.9 80-80 80z"></path>
|
||||
</symbol>
|
||||
<symbol id="icon-database" viewBox="0 0 448 512">
|
||||
<path d="M448 73.143v45.714C448 159.143 347.667 192 224 192S0 159.143 0 118.857V73.143C0 32.857 100.333 0 224 0s224 32.857 224 73.143zM448 176v102.857C448 319.143 347.667 352 224 352S0 319.143 0 278.857V176c48.125 33.143 136.208 48.572 224 48.572S399.874 209.143 448 176zm0 160v102.857C448 479.143 347.667 512 224 512S0 479.143 0 438.857V336c48.125 33.143 136.208 48.572 224 48.572S399.874 369.143 448 336z"></path>
|
||||
</symbol>
|
||||
<symbol id="icon-edit" viewBox="0 0 576 512">
|
||||
<path d="M402.6 83.2l90.2 90.2c3.8 3.8 3.8 10 0 13.8L274.4 405.6l-92.8 10.3c-12.4 1.4-22.9-9.1-21.5-21.5l10.3-92.8L388.8 83.2c3.8-3.8 10-3.8 13.8 0zm162-22.9l-48.8-48.8c-15.2-15.2-39.9-15.2-55.2 0l-35.4 35.4c-3.8 3.8-3.8 10 0 13.8l90.2 90.2c3.8 3.8 10 3.8 13.8 0l35.4-35.4c15.2-15.3 15.2-40 0-55.2zM384 346.2V448H64V128h229.8c3.2 0 6.2-1.3 8.5-3.5l40-40c7.6-7.6 2.2-20.5-8.5-20.5H48C21.5 64 0 85.5 0 112v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V306.2c0-10.7-12.9-16-20.5-8.5l-40 40c-2.2 2.3-3.5 5.3-3.5 8.5z"></path>
|
||||
</symbol>
|
||||
<symbol id="icon-eye" viewBox="0 0 576 512">
|
||||
<path d="M572.52 241.4C518.29 135.59 410.93 64 288 64S57.68 135.64 3.48 241.41a32.35 32.35 0 0 0 0 29.19C57.71 376.41 165.07 448 288 448s230.32-71.64 284.52-177.41a32.35 32.35 0 0 0 0-29.19zM288 400a144 144 0 1 1 144-144 143.93 143.93 0 0 1-144 144zm0-240a95.31 95.31 0 0 0-25.31 3.79 47.85 47.85 0 0 1-66.9 66.9A95.78 95.78 0 1 0 288 160z"></path>
|
||||
</symbol>
|
||||
<symbol id="icon-eye-slash" viewBox="0 0 640 512">
|
||||
<path d="M320 400c-75.85 0-137.25-58.71-142.9-133.11L72.2 185.82c-13.79 17.3-26.48 35.59-36.72 55.59a32.35 32.35 0 0 0 0 29.19C89.71 376.41 197.07 448 320 448c26.91 0 52.87-4 77.89-10.46L346 397.39a144.13 144.13 0 0 1-26 2.61zm313.82 58.1l-110.55-85.44a331.25 331.25 0 0 0 81.25-102.07 32.35 32.35 0 0 0 0-29.19C550.29 135.59 442.93 64 320 64a308.15 308.15 0 0 0-147.32 37.7L45.46 3.37A16 16 0 0 0 23 6.18L3.37 31.45A16 16 0 0 0 6.18 53.9l588.36 454.73a16 16 0 0 0 22.46-2.81l19.64-25.27a16 16 0 0 0-2.82-22.45zm-183.72-142l-39.3-30.38A94.75 94.75 0 0 0 416 256a94.76 94.76 0 0 0-121.31-92.21A47.65 47.65 0 0 1 304 192a46.64 46.64 0 0 1-1.54 10l-73.61-56.89A142.31 142.31 0 0 1 320 112a143.92 143.92 0 0 1 144 144c0 21.63-5.29 41.79-13.9 60.11z"></path>
|
||||
</symbol>
|
||||
<symbol id="icon-gavel" viewBox="0 0 512 512">
|
||||
<path d="M504.971 199.362l-22.627-22.627c-9.373-9.373-24.569-9.373-33.941 0l-5.657 5.657L329.608 69.255l5.657-5.657c9.373-9.373 9.373-24.569 0-33.941L312.638 7.029c-9.373-9.373-24.569-9.373-33.941 0L154.246 131.48c-9.373 9.373-9.373 24.569 0 33.941l22.627 22.627c9.373 9.373 24.569 9.373 33.941 0l5.657-5.657 39.598 39.598-81.04 81.04-5.657-5.657c-12.497-12.497-32.758-12.497-45.255 0L9.373 412.118c-12.497 12.497-12.497 32.758 0 45.255l45.255 45.255c12.497 12.497 32.758 12.497 45.255 0l114.745-114.745c12.497-12.497 12.497-32.758 0-45.255l-5.657-5.657 81.04-81.04 39.598 39.598-5.657 5.657c-9.373 9.373-9.373 24.569 0 33.941l22.627 22.627c9.373 9.373 24.569 9.373 33.941 0l124.451-124.451c9.372-9.372 9.372-24.568 0-33.941z"></path>
|
||||
</symbol>
|
||||
<symbol id="icon-globe" viewBox="0 0 496 512">
|
||||
<path d="M336.5 160C322 70.7 287.8 8 248 8s-74 62.7-88.5 152h177zM152 256c0 22.2 1.2 43.5 3.3 64h185.3c2.1-20.5 3.3-41.8 3.3-64s-1.2-43.5-3.3-64H155.3c-2.1 20.5-3.3 41.8-3.3 64zm324.7-96c-28.6-67.9-86.5-120.4-158-141.6 24.4 33.8 41.2 84.7 50 141.6h108zM177.2 18.4C105.8 39.6 47.8 92.1 19.3 160h108c8.7-56.9 25.5-107.8 49.9-141.6zM487.4 192H372.7c2.1 21 3.3 42.5 3.3 64s-1.2 43-3.3 64h114.6c5.5-20.5 8.6-41.8 8.6-64s-3.1-43.5-8.5-64zM120 256c0-21.5 1.2-43 3.3-64H8.6C3.2 212.5 0 233.8 0 256s3.2 43.5 8.6 64h114.6c-2-21-3.2-42.5-3.2-64zm39.5 96c14.5 89.3 48.7 152 88.5 152s74-62.7 88.5-152h-177zm159.3 141.6c71.4-21.2 129.4-73.7 158-141.6h-108c-8.8 56.9-25.6 107.8-50 141.6zM19.3 352c28.6 67.9 86.5 120.4 158 141.6-24.4-33.8-41.2-84.7-50-141.6h-108z"></path>
|
||||
</symbol>
|
||||
<symbol id="icon-id-card" viewBox="0 0 576 512">
|
||||
<path d="M528 32H48C21.5 32 0 53.5 0 80v16h576V80c0-26.5-21.5-48-48-48zM0 432c0 26.5 21.5 48 48 48h480c26.5 0 48-21.5 48-48V128H0v304zm352-232c0-4.4 3.6-8 8-8h144c4.4 0 8 3.6 8 8v16c0 4.4-3.6 8-8 8H360c-4.4 0-8-3.6-8-8v-16zm0 64c0-4.4 3.6-8 8-8h144c4.4 0 8 3.6 8 8v16c0 4.4-3.6 8-8 8H360c-4.4 0-8-3.6-8-8v-16zm0 64c0-4.4 3.6-8 8-8h144c4.4 0 8 3.6 8 8v16c0 4.4-3.6 8-8 8H360c-4.4 0-8-3.6-8-8v-16zM176 192c35.3 0 64 28.7 64 64s-28.7 64-64 64-64-28.7-64-64 28.7-64 64-64zM67.1 396.2C75.5 370.5 99.6 352 128 352h8.2c12.3 5.1 25.7 8 39.8 8s27.6-2.9 39.8-8h8.2c28.4 0 52.5 18.5 60.9 44.2 3.2 9.9-5.2 19.8-15.6 19.8H82.7c-10.4 0-18.8-10-15.6-19.8z"></path>
|
||||
</symbol>
|
||||
<symbol id="icon-id-card-alt" viewBox="0 0 576 512">
|
||||
<path d="M528 64H384v96H192V64H48C21.5 64 0 85.5 0 112v352c0 26.5 21.5 48 48 48h480c26.5 0 48-21.5 48-48V112c0-26.5-21.5-48-48-48zM288 224c35.3 0 64 28.7 64 64s-28.7 64-64 64-64-28.7-64-64 28.7-64 64-64zm93.3 224H194.7c-10.4 0-18.8-10-15.6-19.8 8.3-25.6 32.4-44.2 60.9-44.2h8.2c12.3 5.1 25.7 8 39.8 8s27.6-2.9 39.8-8h8.2c28.4 0 52.5 18.5 60.9 44.2 3.2 9.8-5.2 19.8-15.6 19.8zM352 32c0-17.7-14.3-32-32-32h-64c-17.7 0-32 14.3-32 32v96h128V32z"></path>
|
||||
</symbol>
|
||||
<symbol id="icon-info" viewBox="0 0 192 512">
|
||||
<path d="M20 424.229h20V279.771H20c-11.046 0-20-8.954-20-20V212c0-11.046 8.954-20 20-20h112c11.046 0 20 8.954 20 20v212.229h20c11.046 0 20 8.954 20 20V492c0 11.046-8.954 20-20 20H20c-11.046 0-20-8.954-20-20v-47.771c0-11.046 8.954-20 20-20zM96 0C56.235 0 24 32.235 24 72s32.235 72 72 72 72-32.235 72-72S135.764 0 96 0z"></path>
|
||||
</symbol>
|
||||
<symbol id="icon-info-circle" viewBox="0 0 512 512">
|
||||
<path d="M256 8C119.043 8 8 119.083 8 256c0 136.997 111.043 248 248 248s248-111.003 248-248C504 119.083 392.957 8 256 8zm0 110c23.196 0 42 18.804 42 42s-18.804 42-42 42-42-18.804-42-42 18.804-42 42-42zm56 254c0 6.627-5.373 12-12 12h-88c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h12v-64h-12c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h64c6.627 0 12 5.373 12 12v100h12c6.627 0 12 5.373 12 12v24z"></path>
|
||||
</symbol>
|
||||
<symbol id="icon-list-ul" viewBox="0 0 512 512">
|
||||
<path d="M48 48a48 48 0 1 0 48 48 48 48 0 0 0-48-48zm0 160a48 48 0 1 0 48 48 48 48 0 0 0-48-48zm0 160a48 48 0 1 0 48 48 48 48 0 0 0-48-48zm448 16H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm0-320H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16V80a16 16 0 0 0-16-16zm0 160H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16z"></path>
|
||||
</symbol>
|
||||
<symbol id="icon-lock" viewBox="0 0 448 512">
|
||||
<path d="M400 224h-24v-72C376 68.2 307.8 0 224 0S72 68.2 72 152v72H48c-26.5 0-48 21.5-48 48v192c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V272c0-26.5-21.5-48-48-48zm-104 0H152v-72c0-39.7 32.3-72 72-72s72 32.3 72 72v72z"></path>
|
||||
</symbol>
|
||||
<symbol id="icon-lock-open" viewBox="0 0 576 512">
|
||||
<path d="M423.5 0C339.5.3 272 69.5 272 153.5V224H48c-26.5 0-48 21.5-48 48v192c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V272c0-26.5-21.5-48-48-48h-48v-71.1c0-39.6 31.7-72.5 71.3-72.9 40-.4 72.7 32.1 72.7 72v80c0 13.3 10.7 24 24 24h32c13.3 0 24-10.7 24-24v-80C576 68 507.5-.3 423.5 0z"></path>
|
||||
</symbol>
|
||||
<symbol id="icon-minus" viewBox="0 0 448 512">
|
||||
<path d="M416 208H32c-17.67 0-32 14.33-32 32v32c0 17.67 14.33 32 32 32h384c17.67 0 32-14.33 32-32v-32c0-17.67-14.33-32-32-32z"></path>
|
||||
</symbol>
|
||||
<symbol id="icon-minus-circle" viewBox="0 0 512 512">
|
||||
<path d="M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zM124 296c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h264c6.6 0 12 5.4 12 12v56c0 6.6-5.4 12-12 12H124z"></path>
|
||||
</symbol>
|
||||
<symbol id="icon-minus-square" viewBox="0 0 448 512">
|
||||
<path d="M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM92 296c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h264c6.6 0 12 5.4 12 12v56c0 6.6-5.4 12-12 12H92z"></path>
|
||||
</symbol>
|
||||
<symbol id="icon-paper-plane" viewBox="0 0 512 512">
|
||||
<path d="M476 3.2L12.5 270.6c-18.1 10.4-15.8 35.6 2.2 43.2L121 358.4l287.3-253.2c5.5-4.9 13.3 2.6 8.6 8.3L176 407v80.5c0 23.6 28.5 32.9 42.5 15.8L282 426l124.6 52.2c14.2 6 30.4-2.9 33-18.2l72-432C515 7.8 493.3-6.8 476 3.2z"></path>
|
||||
</symbol>
|
||||
<symbol id="icon-paperclip" viewBox="0 0 448 512">
|
||||
<path d="M43.246 466.142c-58.43-60.289-57.341-157.511 1.386-217.581L254.392 34c44.316-45.332 116.351-45.336 160.671 0 43.89 44.894 43.943 117.329 0 162.276L232.214 383.128c-29.855 30.537-78.633 30.111-107.982-.998-28.275-29.97-27.368-77.473 1.452-106.953l143.743-146.835c6.182-6.314 16.312-6.422 22.626-.241l22.861 22.379c6.315 6.182 6.422 16.312.241 22.626L171.427 319.927c-4.932 5.045-5.236 13.428-.648 18.292 4.372 4.634 11.245 4.711 15.688.165l182.849-186.851c19.613-20.062 19.613-52.725-.011-72.798-19.189-19.627-49.957-19.637-69.154 0L90.39 293.295c-34.763 35.56-35.299 93.12-1.191 128.313 34.01 35.093 88.985 35.137 123.058.286l172.06-175.999c6.177-6.319 16.307-6.433 22.626-.256l22.877 22.364c6.319 6.177 6.434 16.307.256 22.626l-172.06 175.998c-59.576 60.938-155.943 60.216-214.77-.485z"></path>
|
||||
</symbol>
|
||||
<symbol id="icon-pencil-alt" viewBox="0 0 512 512">
|
||||
<path d="M497.9 142.1l-46.1 46.1c-4.7 4.7-12.3 4.7-17 0l-111-111c-4.7-4.7-4.7-12.3 0-17l46.1-46.1c18.7-18.7 49.1-18.7 67.9 0l60.1 60.1c18.8 18.7 18.8 49.1 0 67.9zM284.2 99.8L21.6 362.4.4 483.9c-2.9 16.4 11.4 30.6 27.8 27.8l121.5-21.3 262.6-262.6c4.7-4.7 4.7-12.3 0-17l-111-111c-4.8-4.7-12.4-4.7-17.1 0zM124.1 339.9c-5.5-5.5-5.5-14.3 0-19.8l154-154c5.5-5.5 14.3-5.5 19.8 0s5.5 14.3 0 19.8l-154 154c-5.5 5.5-14.3 5.5-19.8 0zM88 424h48v36.3l-64.5 11.3-31.1-31.1L51.7 376H88v48z"></path>
|
||||
</symbol>
|
||||
<symbol id="icon-phone" viewBox="0 0 512 512">
|
||||
<path d="M493.4 24.6l-104-24c-11.3-2.6-22.9 3.3-27.5 13.9l-48 112c-4.2 9.8-1.4 21.3 6.9 28l60.6 49.6c-36 76.7-98.9 140.5-177.2 177.2l-49.6-60.6c-6.8-8.3-18.2-11.1-28-6.9l-112 48C3.9 366.5-2 378.1.6 389.4l24 104C27.1 504.2 36.7 512 48 512c256.1 0 464-207.5 464-464 0-11.2-7.7-20.9-18.6-23.4z"></path>
|
||||
</symbol>
|
||||
<symbol id="icon-plus" viewBox="0 0 448 512">
|
||||
<path d="M416 208H272V64c0-17.67-14.33-32-32-32h-32c-17.67 0-32 14.33-32 32v144H32c-17.67 0-32 14.33-32 32v32c0 17.67 14.33 32 32 32h144v144c0 17.67 14.33 32 32 32h32c17.67 0 32-14.33 32-32V304h144c17.67 0 32-14.33 32-32v-32c0-17.67-14.33-32-32-32z"></path>
|
||||
</symbol>
|
||||
<symbol id="icon-plus-circle" viewBox="0 0 512 512">
|
||||
<path d="M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm144 276c0 6.6-5.4 12-12 12h-92v92c0 6.6-5.4 12-12 12h-56c-6.6 0-12-5.4-12-12v-92h-92c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h92v-92c0-6.6 5.4-12 12-12h56c6.6 0 12 5.4 12 12v92h92c6.6 0 12 5.4 12 12v56z"></path>
|
||||
</symbol>
|
||||
<symbol id="icon-plus-square" viewBox="0 0 448 512">
|
||||
<path d="M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-32 252c0 6.6-5.4 12-12 12h-92v92c0 6.6-5.4 12-12 12h-56c-6.6 0-12-5.4-12-12v-92H92c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h92v-92c0-6.6 5.4-12 12-12h56c6.6 0 12 5.4 12 12v92h92c6.6 0 12 5.4 12 12v56z"></path>
|
||||
</symbol>
|
||||
<symbol id="icon-save" viewBox="0 0 448 512">
|
||||
<path d="M433.941 129.941l-83.882-83.882A48 48 0 0 0 316.118 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V163.882a48 48 0 0 0-14.059-33.941zM224 416c-35.346 0-64-28.654-64-64 0-35.346 28.654-64 64-64s64 28.654 64 64c0 35.346-28.654 64-64 64zm96-304.52V212c0 6.627-5.373 12-12 12H76c-6.627 0-12-5.373-12-12V108c0-6.627 5.373-12 12-12h228.52c3.183 0 6.235 1.264 8.485 3.515l3.48 3.48A11.996 11.996 0 0 1 320 111.48z"></path>
|
||||
</symbol>
|
||||
<symbol id="icon-sign-out-alt" viewBox="0 0 512 512">
|
||||
<path d="M497 273L329 441c-15 15-41 4.5-41-17v-96H152c-13.3 0-24-10.7-24-24v-96c0-13.3 10.7-24 24-24h136V88c0-21.4 25.9-32 41-17l168 168c9.3 9.4 9.3 24.6 0 34zM192 436v-40c0-6.6-5.4-12-12-12H96c-17.7 0-32-14.3-32-32V160c0-17.7 14.3-32 32-32h84c6.6 0 12-5.4 12-12V76c0-6.6-5.4-12-12-12H96c-53 0-96 43-96 96v192c0 53 43 96 96 96h84c6.6 0 12-5.4 12-12z"></path>
|
||||
</symbol>
|
||||
<symbol id="icon-smile" viewBox="0 0 496 512">
|
||||
<path d="M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm80 168c17.7 0 32 14.3 32 32s-14.3 32-32 32-32-14.3-32-32 14.3-32 32-32zm-160 0c17.7 0 32 14.3 32 32s-14.3 32-32 32-32-14.3-32-32 14.3-32 32-32zm194.8 170.2C334.3 380.4 292.5 400 248 400s-86.3-19.6-114.8-53.8c-13.6-16.3 11-36.7 24.6-20.5 22.4 26.9 55.2 42.2 90.2 42.2s67.8-15.4 90.2-42.2c13.4-16.2 38.1 4.2 24.6 20.5z"></path>
|
||||
</symbol>
|
||||
<symbol id="icon-snowflake" viewBox="0 0 448 512">
|
||||
<path d="M440.3 345.2l-33.8-19.5 26-7c8.2-2.2 13.1-10.7 10.9-18.9l-4-14.9c-2.2-8.2-10.7-13.1-18.9-10.9l-70.8 19-63.9-37 63.8-36.9 70.8 19c8.2 2.2 16.7-2.7 18.9-10.9l4-14.9c2.2-8.2-2.7-16.7-10.9-18.9l-26-7 33.8-19.5c7.4-4.3 9.9-13.7 5.7-21.1L430.4 119c-4.3-7.4-13.7-9.9-21.1-5.7l-33.8 19.5 7-26c2.2-8.2-2.7-16.7-10.9-18.9l-14.9-4c-8.2-2.2-16.7 2.7-18.9 10.9l-19 70.8-62.8 36.2v-77.5l53.7-53.7c6.2-6.2 6.2-16.4 0-22.6l-11.3-11.3c-6.2-6.2-16.4-6.2-22.6 0L256 56.4V16c0-8.8-7.2-16-16-16h-32c-8.8 0-16 7.2-16 16v40.4l-19.7-19.7c-6.2-6.2-16.4-6.2-22.6 0L138.3 48c-6.3 6.2-6.3 16.4 0 22.6l53.7 53.7v77.5l-62.8-36.2-19-70.8c-2.2-8.2-10.7-13.1-18.9-10.9l-14.9 4c-8.2 2.2-13.1 10.7-10.9 18.9l7 26-33.8-19.5c-7.4-4.3-16.8-1.7-21.1 5.7L2.1 145.7c-4.3 7.4-1.7 16.8 5.7 21.1l33.8 19.5-26 7c-8.3 2.2-13.2 10.7-11 19l4 14.9c2.2 8.2 10.7 13.1 18.9 10.9l70.8-19 63.8 36.9-63.8 36.9-70.8-19c-8.2-2.2-16.7 2.7-18.9 10.9l-4 14.9c-2.2 8.2 2.7 16.7 10.9 18.9l26 7-33.8 19.6c-7.4 4.3-9.9 13.7-5.7 21.1l15.5 26.8c4.3 7.4 13.7 9.9 21.1 5.7l33.8-19.5-7 26c-2.2 8.2 2.7 16.7 10.9 18.9l14.9 4c8.2 2.2 16.7-2.7 18.9-10.9l19-70.8 62.8-36.2v77.5l-53.7 53.7c-6.3 6.2-6.3 16.4 0 22.6l11.3 11.3c6.2 6.2 16.4 6.2 22.6 0l19.7-19.7V496c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16v-40.4l19.7 19.7c6.2 6.2 16.4 6.2 22.6 0l11.3-11.3c6.2-6.2 6.2-16.4 0-22.6L256 387.7v-77.5l62.8 36.2 19 70.8c2.2 8.2 10.7 13.1 18.9 10.9l14.9-4c8.2-2.2 13.1-10.7 10.9-18.9l-7-26 33.8 19.5c7.4 4.3 16.8 1.7 21.1-5.7l15.5-26.8c4.3-7.3 1.8-16.8-5.6-21z"></path>
|
||||
</symbol>
|
||||
<symbol id="icon-spinner" viewBox="0 0 512 512">
|
||||
<path d="M304 48c0 26.51-21.49 48-48 48s-48-21.49-48-48 21.49-48 48-48 48 21.49 48 48zm-48 368c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.49-48-48-48zm208-208c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.49-48-48-48zM96 256c0-26.51-21.49-48-48-48S0 229.49 0 256s21.49 48 48 48 48-21.49 48-48zm12.922 99.078c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48c0-26.509-21.491-48-48-48zm294.156 0c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48c0-26.509-21.49-48-48-48zM108.922 60.922c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.491-48-48-48z"></path>
|
||||
</symbol>
|
||||
<symbol id="icon-sync" viewBox="0 0 512 512">
|
||||
<path d="M440.65 12.57l4 82.77A247.16 247.16 0 0 0 255.83 8C134.73 8 33.91 94.92 12.29 209.82A12 12 0 0 0 24.09 224h49.05a12 12 0 0 0 11.67-9.26 175.91 175.91 0 0 1 317-56.94l-101.46-4.86a12 12 0 0 0-12.57 12v47.41a12 12 0 0 0 12 12H500a12 12 0 0 0 12-12V12a12 12 0 0 0-12-12h-47.37a12 12 0 0 0-11.98 12.57zM255.83 432a175.61 175.61 0 0 1-146-77.8l101.8 4.87a12 12 0 0 0 12.57-12v-47.4a12 12 0 0 0-12-12H12a12 12 0 0 0-12 12V500a12 12 0 0 0 12 12h47.35a12 12 0 0 0 12-12.6l-4.15-82.57A247.17 247.17 0 0 0 255.83 504c121.11 0 221.93-86.92 243.55-201.82a12 12 0 0 0-11.8-14.18h-49.05a12 12 0 0 0-11.67 9.26A175.86 175.86 0 0 1 255.83 432z"></path>
|
||||
</symbol>
|
||||
<symbol id="icon-times" viewBox="0 0 352 512">
|
||||
<path d="M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z"></path>
|
||||
</symbol>
|
||||
<symbol id="icon-times-circle" viewBox="0 0 512 512">
|
||||
<path d="M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm121.6 313.1c4.7 4.7 4.7 12.3 0 17L338 377.6c-4.7 4.7-12.3 4.7-17 0L256 312l-65.1 65.6c-4.7 4.7-12.3 4.7-17 0L134.4 338c-4.7-4.7-4.7-12.3 0-17l65.6-65-65.6-65.1c-4.7-4.7-4.7-12.3 0-17l39.6-39.6c4.7-4.7 12.3-4.7 17 0l65 65.7 65.1-65.6c4.7-4.7 12.3-4.7 17 0l39.6 39.6c4.7 4.7 4.7 12.3 0 17L312 256l65.6 65.1z"></path>
|
||||
</symbol>
|
||||
<symbol id="icon-trash" viewBox="0 0 448 512">
|
||||
<path d="M432 32H312l-9.4-18.7A24 24 0 0 0 281.1 0H166.8a23.72 23.72 0 0 0-21.4 13.3L136 32H16A16 16 0 0 0 0 48v32a16 16 0 0 0 16 16h416a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16zM53.2 467a48 48 0 0 0 47.9 45h245.8a48 48 0 0 0 47.9-45L416 128H32z"></path>
|
||||
</symbol>
|
||||
<symbol id="icon-trash-alt" viewBox="0 0 448 512">
|
||||
<path d="M32 464a48 48 0 0 0 48 48h288a48 48 0 0 0 48-48V128H32zm272-256a16 16 0 0 1 32 0v224a16 16 0 0 1-32 0zm-96 0a16 16 0 0 1 32 0v224a16 16 0 0 1-32 0zm-96 0a16 16 0 0 1 32 0v224a16 16 0 0 1-32 0zM432 32H312l-9.4-18.7A24 24 0 0 0 281.1 0H166.8a23.72 23.72 0 0 0-21.4 13.3L136 32H16A16 16 0 0 0 0 48v32a16 16 0 0 0 16 16h416a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16z"></path>
|
||||
</symbol>
|
||||
<symbol id="icon-unlock" viewBox="0 0 448 512">
|
||||
<path d="M400 256H152V152.9c0-39.6 31.7-72.5 71.3-72.9 40-.4 72.7 32.1 72.7 72v16c0 13.3 10.7 24 24 24h32c13.3 0 24-10.7 24-24v-16C376 68 307.5-.3 223.5 0 139.5.3 72 69.5 72 153.5V256H48c-26.5 0-48 21.5-48 48v160c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V304c0-26.5-21.5-48-48-48z"></path>
|
||||
</symbol>
|
||||
<symbol id="icon-user" viewBox="0 0 448 512">
|
||||
<path d="M224 256c70.7 0 128-57.3 128-128S294.7 0 224 0 96 57.3 96 128s57.3 128 128 128zm89.6 32h-16.7c-22.2 10.2-46.9 16-72.9 16s-50.6-5.8-72.9-16h-16.7C60.2 288 0 348.2 0 422.4V464c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48v-41.6c0-74.2-60.2-134.4-134.4-134.4z"></path>
|
||||
</symbol>
|
||||
<symbol id="icon-user-cog" viewBox="0 0 640 512">
|
||||
<path d="M610.5 373.3c2.6-14.1 2.6-28.5 0-42.6l25.8-14.9c3-1.7 4.3-5.2 3.3-8.5-6.7-21.6-18.2-41.2-33.2-57.4-2.3-2.5-6-3.1-9-1.4l-25.8 14.9c-10.9-9.3-23.4-16.5-36.9-21.3v-29.8c0-3.4-2.4-6.4-5.7-7.1-22.3-5-45-4.8-66.2 0-3.3.7-5.7 3.7-5.7 7.1v29.8c-13.5 4.8-26 12-36.9 21.3l-25.8-14.9c-2.9-1.7-6.7-1.1-9 1.4-15 16.2-26.5 35.8-33.2 57.4-1 3.3.4 6.8 3.3 8.5l25.8 14.9c-2.6 14.1-2.6 28.5 0 42.6l-25.8 14.9c-3 1.7-4.3 5.2-3.3 8.5 6.7 21.6 18.2 41.1 33.2 57.4 2.3 2.5 6 3.1 9 1.4l25.8-14.9c10.9 9.3 23.4 16.5 36.9 21.3v29.8c0 3.4 2.4 6.4 5.7 7.1 22.3 5 45 4.8 66.2 0 3.3-.7 5.7-3.7 5.7-7.1v-29.8c13.5-4.8 26-12 36.9-21.3l25.8 14.9c2.9 1.7 6.7 1.1 9-1.4 15-16.2 26.5-35.8 33.2-57.4 1-3.3-.4-6.8-3.3-8.5l-25.8-14.9zM496 400.5c-26.8 0-48.5-21.8-48.5-48.5s21.8-48.5 48.5-48.5 48.5 21.8 48.5 48.5-21.7 48.5-48.5 48.5zM224 256c70.7 0 128-57.3 128-128S294.7 0 224 0 96 57.3 96 128s57.3 128 128 128zm201.2 226.5c-2.3-1.2-4.6-2.6-6.8-3.9l-7.9 4.6c-6 3.4-12.8 5.3-19.6 5.3-10.9 0-21.4-4.6-28.9-12.6-18.3-19.8-32.3-43.9-40.2-69.6-5.5-17.7 1.9-36.4 17.9-45.7l7.9-4.6c-.1-2.6-.1-5.2 0-7.8l-7.9-4.6c-16-9.2-23.4-28-17.9-45.7.9-2.9 2.2-5.8 3.2-8.7-3.8-.3-7.5-1.2-11.4-1.2h-16.7c-22.2 10.2-46.9 16-72.9 16s-50.6-5.8-72.9-16h-16.7C60.2 288 0 348.2 0 422.4V464c0 26.5 21.5 48 48 48h352c10.1 0 19.5-3.2 27.2-8.5-1.2-3.8-2-7.7-2-11.8v-9.2z"></path>
|
||||
</symbol>
|
||||
<symbol id="icon-user-plus" viewBox="0 0 640 512">
|
||||
<path d="M624 208h-64v-64c0-8.8-7.2-16-16-16h-32c-8.8 0-16 7.2-16 16v64h-64c-8.8 0-16 7.2-16 16v32c0 8.8 7.2 16 16 16h64v64c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16v-64h64c8.8 0 16-7.2 16-16v-32c0-8.8-7.2-16-16-16zm-400 48c70.7 0 128-57.3 128-128S294.7 0 224 0 96 57.3 96 128s57.3 128 128 128zm89.6 32h-16.7c-22.2 10.2-46.9 16-72.9 16s-50.6-5.8-72.9-16h-16.7C60.2 288 0 348.2 0 422.4V464c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48v-41.6c0-74.2-60.2-134.4-134.4-134.4z"></path>
|
||||
</symbol>
|
||||
<symbol id="icon-user-secret" viewBox="0 0 448 512">
|
||||
<path d="M383.9 308.3l23.9-62.6c4-10.5-3.7-21.7-15-21.7h-58.5c11-18.9 17.8-40.6 17.8-64v-.3c39.2-7.8 64-19.1 64-31.7 0-13.3-27.3-25.1-70.1-33-9.2-32.8-27-65.8-40.6-82.8-9.5-11.9-25.9-15.6-39.5-8.8l-27.6 13.8c-9 4.5-19.6 4.5-28.6 0L182.1 3.4c-13.6-6.8-30-3.1-39.5 8.8-13.5 17-31.4 50-40.6 82.8-42.7 7.9-70 19.7-70 33 0 12.6 24.8 23.9 64 31.7v.3c0 23.4 6.8 45.1 17.8 64H56.3c-11.5 0-19.2 11.7-14.7 22.3l25.8 60.2C27.3 329.8 0 372.7 0 422.4v44.8C0 491.9 20.1 512 44.8 512h358.4c24.7 0 44.8-20.1 44.8-44.8v-44.8c0-48.4-25.8-90.4-64.1-114.1zM176 480l-41.6-192 49.6 32 24 40-32 120zm96 0l-32-120 24-40 49.6-32L272 480zm41.7-298.5c-3.9 11.9-7 24.6-16.5 33.4-10.1 9.3-48 22.4-64-25-2.8-8.4-15.4-8.4-18.3 0-17 50.2-56 32.4-64 25-9.5-8.8-12.7-21.5-16.5-33.4-.8-2.5-6.3-5.7-6.3-5.8v-10.8c28.3 3.6 61 5.8 96 5.8s67.7-2.1 96-5.8v10.8c-.1.1-5.6 3.2-6.4 5.8z"></path>
|
||||
</symbol>
|
||||
<symbol id="icon-users" viewBox="0 0 640 512">
|
||||
<path d="M96 224c35.3 0 64-28.7 64-64s-28.7-64-64-64-64 28.7-64 64 28.7 64 64 64zm448 0c35.3 0 64-28.7 64-64s-28.7-64-64-64-64 28.7-64 64 28.7 64 64 64zm32 32h-64c-17.6 0-33.5 7.1-45.1 18.6 40.3 22.1 68.9 62 75.1 109.4h66c17.7 0 32-14.3 32-32v-32c0-35.3-28.7-64-64-64zm-256 0c61.9 0 112-50.1 112-112S381.9 32 320 32 208 82.1 208 144s50.1 112 112 112zm76.8 32h-8.3c-20.8 10-43.9 16-68.5 16s-47.6-6-68.5-16h-8.3C179.6 288 128 339.6 128 403.2V432c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48v-28.8c0-63.6-51.6-115.2-115.2-115.2zm-223.7-13.4C161.5 263.1 145.6 256 128 256H64c-35.3 0-64 28.7-64 64v32c0 17.7 14.3 32 32 32h65.9c6.3-47.4 34.9-87.3 75.2-109.4z"></path>
|
||||
</symbol>
|
||||
<symbol id="icon-wrench" viewBox="0 0 512 512">
|
||||
<path d="M507.73 109.1c-2.24-9.03-13.54-12.09-20.12-5.51l-74.36 74.36-67.88-11.31-11.31-67.88 74.36-74.36c6.62-6.62 3.43-17.9-5.66-20.16-47.38-11.74-99.55.91-136.58 37.93-39.64 39.64-50.55 97.1-34.05 147.2L18.74 402.76c-24.99 24.99-24.99 65.51 0 90.5 24.99 24.99 65.51 24.99 90.5 0l213.21-213.21c50.12 16.71 107.47 5.68 147.37-34.22 37.07-37.07 49.7-89.32 37.91-136.73zM64 472c-13.25 0-24-10.75-24-24 0-13.26 10.75-24 24-24s24 10.74 24 24c0 13.25-10.75 24-24 24z"></path>
|
||||
</symbol>
|
||||
</svg>
|
Before Width: | Height: | Size: 33 KiB |
26
index.html
@ -4,6 +4,7 @@
|
||||
<title>Converse</title>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta name="description" content="Converse XMPP/Jabber Chat"/>
|
||||
<meta name="author" content="JC Brand" />
|
||||
@ -53,6 +54,9 @@
|
||||
<li class="nav-item page-scroll">
|
||||
<a class="nav-link" href="#hosting">Hosting</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="https://github.com/conversejs/converse.js" target="_blank" rel="noopener">Github <i class="fa fa-external-link-alt"></i></a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/docs/html/index.html">Documentation <i class="fa fa-external-link-alt"></i></a>
|
||||
</li>
|
||||
@ -96,22 +100,13 @@
|
||||
<p class="intro-text">Try the <a href="/fullscreen.html">fullpage</a> and <a href="https://github.com/conversejs/converse-desktop/releases" target="_blank" rel="noopener">desktop</a> versions<p>
|
||||
<p style="padding-top: 1.5em">
|
||||
<a href="https://inverse.chat/#converse/room?jid=discuss@conference.conversejs.org"
|
||||
target="_blank" rel="noopener"><img src="https://inverse.chat/badge.svg?room=discuss@conference.conversejs.org"/></a>
|
||||
target="_blank" rel="noopener"><img src="https://conference.conversejs.org/muc_badge/discuss@conference.conversejs.org"/></a>
|
||||
</p>
|
||||
<div class="page-scroll">
|
||||
<a href="#about" class="btn btn-default btn-lg"><span class="btn-text">Learn More</span></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-12 col-md-offset-2 banner-social-buttons">
|
||||
<ul class="list-inline">
|
||||
<li class="list-inline-item"><a href="https://twitter.com/jcopkode" class="btn btn-circle btn-lg" title="Twitter" target="_blank" rel="noopener"><i class="fab fa-twitter"></i></a></li>
|
||||
<li class="list-inline-item"><a href="https://mastodon.xyz/@jcbrand" class="btn btn-lg" title="Mastodon" target="_blank" rel="noopener"><img class="mastodon" src="/logo/mastodon.svg"/></a></li>
|
||||
<li class="list-inline-item"><a href="https://github.com/jcbrand/converse.js" class="btn btn-circle btn-lg" title="GitHub" target="_blank" rel="noopener"><i class="fab fa-github"></i></a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="about" class="container content-section text-center">
|
||||
@ -149,6 +144,7 @@
|
||||
<li style="list-style: none">XMPP Servers</li>
|
||||
<li><a href="https://www.igniterealtime.org/projects/openfire/plugins.jsp" target="_blank" rel="noopener">Openfire</a></li>
|
||||
<li><a href="https://modules.prosody.im/mod_conversejs.html" target="_blank" rel="noopener">Prosody</a></li>
|
||||
<li><a href="https://docs.ejabberd.im/admin/configuration/modules/#mod-conversejs" target="_blank" rel="noopener">Ejabberd</a></li>
|
||||
</ul>
|
||||
<ul class="integration">
|
||||
<li style="list-style: none">Frameworks</li>
|
||||
@ -185,6 +181,7 @@
|
||||
<li>A <a href="https://conversejs.org/docs/html/plugin_development.html" target="_blank" rel="noopener">plugin architecture</a> based on <a href="https://conversejs.github.io/pluggable.js/" target="_blank" rel="noopener">pluggable.js</a></li>
|
||||
<li>Chat statuses (online, busy, away, offline)</li>
|
||||
<li>Desktop notifications</li>
|
||||
<li>URL Previews (requires server support, for example <a href="https://modules.prosody.im/mod_ogp.html" target="_blank" rel="noopener">mod_ogp</a></li>
|
||||
<li>Multi-user chatrooms (<a href="https://xmpp.org/extensions/xep-0045.html" target="_blank" rel="noopener">XEP 45</a>)</li>
|
||||
<li>Chatroom bookmarks (<a href="https://xmpp.org/extensions/xep-0048.html" target="_blank" rel="noopener">XEP 48</a>)</li>
|
||||
<li>Direct invitations to chat rooms (<a href="https://xmpp.org/extensions/xep-0249.html" target="_blank" rel="noopener">XEP 249</a>)</li>
|
||||
@ -197,6 +194,7 @@
|
||||
<li>Hidden messages (aka Spoilers) (<a href="https://xmpp.org/extensions/xep-0382.html" target="_blank" rel="noopener">XEP 382</a>)</li>
|
||||
<li>Client state indication (<a href="https://xmpp.org/extensions/xep-0352.html" target="_blank" rel="noopener">XEP 352</a>)</li>
|
||||
<li>OMEMO encrypted messaging (<a href="https://xmpp.org/extensions/xep-0384.html" target="_blank" rel="noopener">XEP 384</a>)</li>
|
||||
<li>Message Styling (<a href="https://xmpp.org/extensions/xep-0384.html" target="_blank" rel="noopener">XEP 393</a>)</li>
|
||||
<li>Anonymous logins, see the <a href="/demo/anonymous.html" target="_blank" rel="noopener">anonymous login demo</a></li>
|
||||
<li>Message corrections, retractions and moderation</li>
|
||||
<li>Translated into over 30 languages</li>
|
||||
@ -212,8 +210,7 @@
|
||||
<div class="col-lg-12 col-lg-offset-2">
|
||||
<h2>Contact</h2>
|
||||
<ul class="contact">
|
||||
<li>Follow on <a href="https://twitter.com/jcopkode" target="_blank" rel="noopener">Twitter</a>
|
||||
or <a href="https://mastodon.xyz/@jcbrand" target="_blank" rel="noopener">Mastodon</a>
|
||||
<li>Follow on <a href="https://mastodon.xyz/@jcbrand" target="_blank" rel="noopener">the fediverse</a>
|
||||
<li>Chat via XMPP at <a href="xmpp:jc@opkode.com" class="xmpp JSnocheck" title="XMPP/Jabber">jc@opkode.com</a></li>
|
||||
<li>For technical support, you can ask on <a href="https://stackoverflow.com/questions/tagged/converse.js">Stack Overflow</a>
|
||||
<li>The Converse XMPP chatroom: <a href="xmpp:discuss@conference.conversejs.org?join" class="xmpp JSnocheck chatroom-name" title="Converse chat room">discuss@conference.conversejs.org</a></li>
|
||||
@ -243,10 +240,11 @@
|
||||
<div class="sponsors">
|
||||
<h2>Converse is supported by:</h2>
|
||||
<ul >
|
||||
<li><a href="https://bairesdev.com/sponsoring-open-source-projects/?utm_source=conversejs" target="_blank" rel="noopener"><img style="width: 13em" src="/media/logos/bairesdev-primary.png" alt="BairesDev"></a></li>
|
||||
<li><a href="https://blokt.com?utm_source=conversejs" target="_blank" rel="noopener"><img style="width: 12em" src="/logo/blokt.png" alt="Blokt Crypto & Privacy"></a></li>
|
||||
<li><a href="https://primesound.org/?utm_source=conversejs" target="_blank" rel="noopener"><img style="width: 10em" src="/media/logos/primesound.png" alt="Prime Sound"></a></li>
|
||||
<li><a href="https://www.keycdn.com?utm_source=conversejs" target="_blank" rel="noopener"><img style="height: 3em" src="/logo/keycdn.svg" alt="KeyCDN"></a></li>
|
||||
<li><a href="https://weblate.org?utm_source=conversejs" target="_blank" rel="noopener"><img style="height: 2.6em" src="/logo/weblate-button.svg" alt="Weblate"></a></li>
|
||||
<li><a href="https://www.codefirst.co.uk?utm_source=conversejs" target="_blank" rel="noopener"><img style="width: 12em; padding-top: 0.5em" src="/logo/codefirst.png" alt="Codefirst"></a></li>
|
||||
<li><a href="https://blokt.com?utm_source=conversejs" target="_blank" rel="noopener"><img style="width: 12em" src="/logo/blokt.png" alt="Blokt Crypto & Privacy"></a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
|
@ -11,17 +11,17 @@
|
||||
|
||||
<!-- These files are NOT needed when using converse.js in your own project. -->
|
||||
<link rel="shortcut icon" type="image/ico" href="images/favicon.ico"/>
|
||||
<link type="text/css" rel="stylesheet" media="screen" href="https://cdn.conversejs.org/7.0.1/css/font-awesome.min.css" />
|
||||
<link type="text/css" rel="stylesheet" media="screen" href="https://cdn.conversejs.org/7.0.1/css/website.min.css" />
|
||||
<link type="text/css" rel="stylesheet" media="screen" href="https://cdn.conversejs.org/10.1.6/css/font-awesome.min.css" />
|
||||
<link type="text/css" rel="stylesheet" media="screen" href="https://cdn.conversejs.org/10.1.6/css/website.min.css" />
|
||||
<noscript><p><img src="//stats.opkode.com/piwik.php?idsite=1" style="border:0;" alt="" /></p></noscript>
|
||||
<script type="text/javascript" src="/src/website.js"></script>
|
||||
<script type="text/javascript" src="analytics.js"></script>
|
||||
<!-- *********************************************************************** -->
|
||||
|
||||
<![if gte IE 11]>
|
||||
<link type="text/css" rel="stylesheet" media="screen" href="https://cdn.conversejs.org/7.0.1/css/converse.min.css" />
|
||||
<link type="text/css" rel="stylesheet" media="screen" href="https://cdn.conversejs.org/10.1.6/css/converse.min.css" />
|
||||
<script src="https://cdn.conversejs.org/3rdparty/libsignal-protocol.min.js"></script>
|
||||
<script src="https://cdn.conversejs.org/7.0.1/dist/converse.min.js"></script>
|
||||
<script src="https://cdn.conversejs.org/10.1.6/dist/converse.min.js"></script>
|
||||
<![endif]>
|
||||
</head>
|
||||
|
||||
@ -66,7 +66,7 @@
|
||||
<table id="jslicense-labels1" style="width: 100%">
|
||||
<tr>
|
||||
<td>
|
||||
<a href="https://cdn.conversejs.org/7.0.1/dist/converse.min.js">converse.min.js</a>
|
||||
<a href="https://cdn.conversejs.org/10.1.6/dist/converse.min.js">converse.min.js</a>
|
||||
</td>
|
||||
<td>
|
||||
<a href="https://www.mozilla.org/en-US/MPL/2.0/">MPL-2.0</a>
|
||||
|
137
karma.conf.js
@ -3,14 +3,16 @@ const path = require('path');
|
||||
|
||||
module.exports = function(config) {
|
||||
config.set({
|
||||
|
||||
// base path that will be used to resolve all patterns (eg. files, exclude)
|
||||
basePath: '',
|
||||
frameworks: ['jasmine'],
|
||||
files: [
|
||||
{ pattern: 'dist/*.js.map', included: false },
|
||||
{ pattern: 'dist/*.css.map', included: false },
|
||||
{ pattern: "dist/icons.js", served: true },
|
||||
{ pattern: "dist/emojis.js", served: true },
|
||||
"src/shared/tests/tests.css",
|
||||
"node_modules/lodash/lodash.min.js",
|
||||
"dist/converse.js",
|
||||
"dist/converse.css",
|
||||
{ pattern: "dist/images/**/*.*", included: false },
|
||||
@ -21,47 +23,100 @@ module.exports = function(config) {
|
||||
served: true,
|
||||
nocache: false
|
||||
},
|
||||
{ pattern: "node_modules/sinon/pkg/sinon.js", type: 'module' },
|
||||
{ pattern: "spec/mock.js", type: 'module' },
|
||||
{ pattern: "src/shared/tests/mock.js", type: 'module' },
|
||||
|
||||
{ pattern: "spec/spoilers.js", type: 'module' },
|
||||
{ pattern: "spec/emojis.js", type: 'module' },
|
||||
{ pattern: "spec/muclist.js", type: 'module' },
|
||||
{ pattern: "spec/utils.js", type: 'module' },
|
||||
{ pattern: "spec/converse.js", type: 'module' },
|
||||
{ pattern: "spec/bookmarks.js", type: 'module' },
|
||||
{ pattern: "spec/headline.js", type: 'module' },
|
||||
{ pattern: "spec/disco.js", type: 'module' },
|
||||
{ pattern: "spec/protocol.js", type: 'module' },
|
||||
{ pattern: "spec/presence.js", type: 'module' },
|
||||
{ pattern: "spec/eventemitter.js", type: 'module' },
|
||||
{ pattern: "spec/smacks.js", type: 'module' },
|
||||
{ pattern: "spec/ping.js", type: 'module' },
|
||||
{ pattern: "spec/push.js", type: 'module' },
|
||||
{ pattern: "spec/xmppstatus.js", type: 'module' },
|
||||
{ pattern: "spec/mam.js", type: 'module' },
|
||||
{ pattern: "spec/omemo.js", type: 'module' },
|
||||
{ pattern: "spec/controlbox.js", type: 'module' },
|
||||
{ pattern: "spec/roster.js", type: 'module' },
|
||||
{ pattern: "spec/chatbox.js", type: 'module' },
|
||||
{ pattern: "spec/user-details-modal.js", type: 'module' },
|
||||
{ pattern: "spec/messages.js", type: 'module' },
|
||||
{ pattern: "spec/corrections.js", type: 'module' },
|
||||
{ pattern: "spec/receipts.js", type: 'module' },
|
||||
{ pattern: "spec/muc_messages.js", type: 'module' },
|
||||
{ pattern: "spec/mentions.js", type: 'module' },
|
||||
{ pattern: "spec/retractions.js", type: 'module' },
|
||||
{ pattern: "spec/muc.js", type: 'module' },
|
||||
{ pattern: "spec/modtools.js", type: 'module' },
|
||||
{ pattern: "spec/room_registration.js", type: 'module' },
|
||||
{ pattern: "spec/autocomplete.js", type: 'module' },
|
||||
{ pattern: "spec/minchats.js", type: 'module' },
|
||||
{ pattern: "spec/notification.js", type: 'module' },
|
||||
{ pattern: "spec/login.js", type: 'module' },
|
||||
{ pattern: "spec/register.js", type: 'module' },
|
||||
{ pattern: "spec/hats.js", type: 'module' },
|
||||
{ pattern: "spec/http-file-upload.js", type: 'module' },
|
||||
{ pattern: "spec/xss.js", type: 'module' }
|
||||
{ pattern: "src/headless/plugins/caps/tests/caps.js", type: 'module' },
|
||||
{ pattern: "src/headless/plugins/chat/tests/api.js", type: 'module' },
|
||||
{ pattern: "src/headless/plugins/disco/tests/disco.js", type: 'module' },
|
||||
{ pattern: "src/headless/plugins/muc/tests/affiliations.js", type: 'module' },
|
||||
{ pattern: "src/headless/plugins/muc/tests/messages.js", type: 'module' },
|
||||
{ pattern: "src/headless/plugins/muc/tests/muc.js", type: 'module' },
|
||||
{ pattern: "src/headless/plugins/muc/tests/occupants.js", type: 'module' },
|
||||
{ pattern: "src/headless/plugins/muc/tests/pruning.js", type: 'module' },
|
||||
{ pattern: "src/headless/plugins/muc/tests/registration.js", type: 'module' },
|
||||
{ pattern: "src/headless/plugins/ping/tests/ping.js", type: 'module' },
|
||||
{ pattern: "src/headless/plugins/roster/tests/presence.js", type: 'module' },
|
||||
{ pattern: "src/headless/plugins/smacks/tests/smacks.js", type: 'module' },
|
||||
{ pattern: "src/headless/plugins/status/tests/status.js", type: 'module' },
|
||||
{ pattern: "src/headless/shared/settings/tests/settings.js", type: 'module' },
|
||||
{ pattern: "src/headless/tests/converse.js", type: 'module' },
|
||||
{ pattern: "src/headless/tests/eventemitter.js", type: 'module' },
|
||||
{ pattern: "src/modals/tests/user-details-modal.js", type: 'module' },
|
||||
{ pattern: "src/plugins/adhoc-views/tests/adhoc.js", type: 'module' },
|
||||
{ pattern: "src/plugins/bookmark-views/tests/bookmarks-list.js", type: 'module' },
|
||||
{ pattern: "src/plugins/bookmark-views/tests/bookmarks.js", type: 'module' },
|
||||
{ pattern: "src/plugins/chatview/tests/chatbox.js", type: 'module' },
|
||||
{ pattern: "src/plugins/chatview/tests/corrections.js", type: 'module' },
|
||||
{ pattern: "src/plugins/chatview/tests/emojis.js", type: 'module' },
|
||||
{ pattern: "src/plugins/chatview/tests/http-file-upload.js", type: 'module' },
|
||||
{ pattern: "src/plugins/chatview/tests/markers.js", type: 'module' },
|
||||
{ pattern: "src/plugins/chatview/tests/me-messages.js", type: 'module' },
|
||||
{ pattern: "src/plugins/chatview/tests/message-audio.js", type: 'module' },
|
||||
{ pattern: "src/plugins/chatview/tests/message-gifs.js", type: 'module' },
|
||||
{ pattern: "src/plugins/chatview/tests/message-images.js", type: 'module' },
|
||||
{ pattern: "src/plugins/chatview/tests/message-videos.js", type: 'module' },
|
||||
{ pattern: "src/plugins/chatview/tests/messages.js", type: 'module' },
|
||||
{ pattern: "src/plugins/chatview/tests/oob.js", type: 'module' },
|
||||
{ pattern: "src/plugins/chatview/tests/receipts.js", type: 'module' },
|
||||
{ pattern: "src/plugins/chatview/tests/spoilers.js", type: 'module' },
|
||||
{ pattern: "src/plugins/chatview/tests/styling.js", type: 'module' },
|
||||
{ pattern: "src/plugins/chatview/tests/unreads.js", type: 'module' },
|
||||
{ pattern: "src/plugins/chatview/tests/xss.js", type: 'module' },
|
||||
{ pattern: "src/plugins/controlbox/tests/controlbox.js", type: 'module' },
|
||||
{ pattern: "src/plugins/controlbox/tests/login.js", type: 'module' },
|
||||
{ pattern: "src/plugins/headlines-view/tests/headline.js", type: 'module' },
|
||||
{ pattern: "src/plugins/mam-views/tests/mam.js", type: 'module' },
|
||||
{ pattern: "src/plugins/mam-views/tests/placeholder.js", type: 'module' },
|
||||
{ pattern: "src/plugins/minimize/tests/minchats.js", type: 'module' },
|
||||
{ pattern: "src/plugins/muc-views/tests/autocomplete.js", type: 'module' },
|
||||
{ pattern: "src/plugins/muc-views/tests/component.js", type: 'module' },
|
||||
{ pattern: "src/plugins/muc-views/tests/corrections.js", type: 'module' },
|
||||
{ pattern: "src/plugins/muc-views/tests/disco.js", type: 'module' },
|
||||
{ pattern: "src/plugins/muc-views/tests/emojis.js", type: 'module' },
|
||||
{ pattern: "src/plugins/muc-views/tests/hats.js", type: 'module' },
|
||||
{ pattern: "src/plugins/muc-views/tests/http-file-upload.js", type: 'module' },
|
||||
{ pattern: "src/plugins/muc-views/tests/info-messages.js", type: 'module' },
|
||||
{ pattern: "src/plugins/muc-views/tests/mam.js", type: 'module' },
|
||||
{ pattern: "src/plugins/muc-views/tests/markers.js", type: 'module' },
|
||||
{ pattern: "src/plugins/muc-views/tests/me-messages.js", type: 'module' },
|
||||
{ pattern: "src/plugins/muc-views/tests/member-lists.js", type: 'module' },
|
||||
{ pattern: "src/plugins/muc-views/tests/mentions.js", type: 'module' },
|
||||
{ pattern: "src/plugins/muc-views/tests/mep.js", type: 'module' },
|
||||
{ pattern: "src/plugins/muc-views/tests/modtools.js", type: 'module' },
|
||||
{ pattern: "src/plugins/muc-views/tests/muc-add-modal.js", type: 'module' },
|
||||
{ pattern: "src/plugins/muc-views/tests/muc-api.js", type: 'module' },
|
||||
{ pattern: "src/plugins/muc-views/tests/muc-list-modal.js", type: 'module' },
|
||||
{ pattern: "src/plugins/muc-views/tests/muc-mentions.js", type: 'module' },
|
||||
{ pattern: "src/plugins/muc-views/tests/muc-messages.js", type: 'module' },
|
||||
{ pattern: "src/plugins/muc-views/tests/muc-registration.js", type: 'module' },
|
||||
{ pattern: "src/plugins/muc-views/tests/muc.js", type: 'module' },
|
||||
{ pattern: "src/plugins/muc-views/tests/nickname.js", type: 'module' },
|
||||
{ pattern: "src/plugins/muc-views/tests/occupants.js", type: 'module' },
|
||||
{ pattern: "src/plugins/muc-views/tests/rai.js", type: 'module' },
|
||||
{ pattern: "src/plugins/muc-views/tests/retractions.js", type: 'module' },
|
||||
{ pattern: "src/plugins/muc-views/tests/styling.js", type: 'module' },
|
||||
{ pattern: "src/plugins/muc-views/tests/toolbar.js", type: 'module' },
|
||||
{ pattern: "src/plugins/muc-views/tests/unfurls.js", type: 'module' },
|
||||
{ pattern: "src/plugins/muc-views/tests/xss.js", type: 'module' },
|
||||
{ pattern: "src/plugins/notifications/tests/notification.js", type: 'module' },
|
||||
{ pattern: "src/plugins/omemo/tests/corrections.js", type: 'module' },
|
||||
{ pattern: "src/plugins/omemo/tests/media-sharing.js", type: 'module' },
|
||||
{ pattern: "src/plugins/omemo/tests/muc.js", type: 'module' },
|
||||
{ pattern: "src/plugins/omemo/tests/omemo.js", type: 'module' },
|
||||
{ pattern: "src/plugins/profile/tests/password-reset.js", type: 'module' },
|
||||
{ pattern: "src/plugins/profile/tests/profile.js", type: 'module' },
|
||||
{ pattern: "src/plugins/profile/tests/status.js", type: 'module' },
|
||||
{ pattern: "src/plugins/push/tests/push.js", type: 'module' },
|
||||
{ pattern: "src/plugins/register/tests/register.js", type: 'module' },
|
||||
{ pattern: "src/plugins/roomslist/tests/roomslist.js", type: 'module' },
|
||||
{ pattern: "src/plugins/rootview/tests/root.js", type: 'module' },
|
||||
{ pattern: "src/plugins/rosterview/tests/add-contact-modal.js", type: 'module' },
|
||||
{ pattern: "src/plugins/rosterview/tests/presence.js", type: 'module' },
|
||||
{ pattern: "src/plugins/rosterview/tests/protocol.js", type: 'module' },
|
||||
{ pattern: "src/plugins/rosterview/tests/roster.js", type: 'module' },
|
||||
|
||||
// For some reason this test causes issues when its run earlier
|
||||
{ pattern: "src/headless/tests/persistence.js", type: 'module' },
|
||||
],
|
||||
|
||||
proxies: {
|
||||
|
@ -1,7 +0,0 @@
|
||||
{
|
||||
"packages": [
|
||||
".",
|
||||
"src/*"
|
||||
],
|
||||
"version": "4.0.3"
|
||||
}
|
Before Width: | Height: | Size: 12 KiB |
@ -1,19 +1,34 @@
|
||||
<svg class="converse-svg-logo"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
viewBox="0 0 364 364">
|
||||
<title>Converse</title>
|
||||
<g class="cls-1" id="g904">
|
||||
<g data-name="Layer 2">
|
||||
<g data-name="Layer 7">
|
||||
<path
|
||||
class="cls-3"
|
||||
d="M221.46,103.71c0,18.83-29.36,18.83-29.12,0C192.1,84.88,221.46,84.88,221.46,103.71Z" />
|
||||
<path
|
||||
class="cls-4"
|
||||
d="M179.9,4.15A175.48,175.48,0,1,0,355.38,179.63,175.48,175.48,0,0,0,179.9,4.15Zm-40.79,264.5c-.23-17.82,27.58-17.82,27.58,0S138.88,286.48,139.11,268.65ZM218.6,168.24A79.65,79.65,0,0,1,205.15,174a12.76,12.76,0,0,0-6.29,4.65L167.54,222a1.36,1.36,0,0,1-2.46-.8v-35.8a2.58,2.58,0,0,0-3.06-2.53c-15.43,3-30.23,7.7-42.73,19.94-38.8,38-29.42,105.69,16.09,133.16a162.25,162.25,0,0,1-91.47-67.27C-3.86,182.26,34.5,47.25,138.37,25.66c46.89-9.75,118.25,5.16,123.73,62.83C265.15,120.64,246.56,152.89,218.6,168.24Z" />
|
||||
</g>
|
||||
</g>
|
||||
<svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" id="svg108" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:1.41421;"
|
||||
xml:space="preserve" version="1.1"
|
||||
viewBox="0 0 376 311" height="20%" width="10rem"
|
||||
sodipodi:docname="chapril-logo.svg" inkscape:version="0.92.1 r15371">
|
||||
<sodipodi:namedview pagecolor="#ffffff" bordercolor="#666666" borderopacity="1" objecttolerance="10" gridtolerance="10" guidetolerance="10" inkscape:pageopacity="0" inkscape:pageshadow="2" inkscape:window-width="640" inkscape:window-height="480" id="namedview16" showgrid="false" inkscape:zoom="0.75884244" inkscape:cx="188" inkscape:cy="155.5" inkscape:window-x="0" inkscape:window-y="24" inkscape:window-maximized="0" inkscape:current-layer="svg108"/>
|
||||
<metadata id="metadata114">
|
||||
<rdf:RDF>
|
||||
<cc:Work rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
|
||||
<dc:title/>
|
||||
<cc:license rdf:resource="GFDL version 1.3 ou ultérieure, Creative Commons By Sa version 2.0 ou ultérieure, Licence Art Libre version 1.3 ou ultérieure"/>
|
||||
<dc:creator>
|
||||
<cc:Agent>
|
||||
<dc:title>Antoine BARDELLI</dc:title>
|
||||
</cc:Agent>
|
||||
</dc:creator>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs id="defs112"/>
|
||||
<g id="g250" style="clip-rule:evenodd;fill-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:1.41420996" transform="translate(4.6079614e-7,-4.4571451e-6)">
|
||||
<path id="path124" style="clip-rule:evenodd;fill:#005184;fill-rule:nonzero;stroke-linejoin:round;stroke-miterlimit:1.41420996" d="m 96.70711,209.69029 c -2.742,1.114 -5.399,1.8 -7.885,2.057 -0.771,0.085 -1.629,0.171 -2.4,0.171 -2.571,0 -5.314,-0.428 -8.228,-1.286 -2.486,-0.857 -4.628,-2.314 -6.514,-4.371 -1.886,-1.8 -3.343,-3.942 -4.371,-6.428 -0.943,-2.486 -1.457,-5.057 -1.543,-7.714 0,-0.086 0,-0.257 0,-0.343 0,-2.485 0.514,-4.971 1.543,-7.371 1.028,-2.314 2.485,-4.457 4.371,-6.428 1.886,-2.057 4.028,-3.514 6.514,-4.371 2.828,-1.029 5.571,-1.543 8.142,-1.543 0.257,0 0.6,0 0.857,0 3.686,0.171 6.857,1.028 9.686,2.657 -0.086,1.457 -0.343,3.514 -0.6,6.343 -2.743,-1.372 -5.4,-2.143 -7.971,-2.315 -1.972,-0.171 -3.943,0.086 -6,0.772 -1.629,0.514 -3.171,1.457 -4.457,2.914 -1.286,1.371 -2.228,2.828 -2.914,4.457 -0.772,1.628 -1.114,3.342 -1.114,5.142 0.085,1.886 0.428,3.6 1.114,5.229 0.686,1.714 1.628,3.171 2.914,4.457 1.286,1.285 2.828,2.228 4.457,2.914 2.486,0.685 4.543,1.028 6.343,1.028 3.342,-0.343 5.999,-1.2 8.056,-2.657 0,1.457 0,3.686 0,6.686 z"/>
|
||||
<path id="path126" style="clip-rule:evenodd;fill:#005184;fill-rule:nonzero;stroke-linejoin:round;stroke-miterlimit:1.41420996" d="m 137.33411,184.91929 c 0,1.8 0,3.515 0,5.314 0,2.657 0,5.4 -0.086,8.057 0,4.457 0,8.743 0,12.771 -1.714,0 -4.285,0 -7.799,0 0,-3.857 0,-11.571 0.085,-23.142 0.086,-1.114 -0.171,-2.228 -0.6,-3.257 -0.428,-1.028 -1.028,-1.971 -1.8,-2.742 -0.942,-0.943 -2.142,-1.715 -3.599,-2.143 -1.029,-0.257 -2.229,-0.429 -3.6,-0.343 -1.115,0.086 -2.229,0.343 -3.257,0.686 -1.029,0.428 -2.143,1.028 -3.343,1.8 -0.6,0.6 -1.029,1.2 -1.457,1.8 v 27.341 h -8.057 v -62.997 h 8.057 v 29.313 c 0.943,-1.114 1.8,-1.971 2.571,-2.486 1.629,-0.942 3,-1.542 4.2,-1.885 1.971,-0.429 3.771,-0.6 5.571,-0.6 2.143,0.085 3.943,0.343 5.4,0.943 1.543,0.6 2.914,1.542 4.028,2.742 2.4,2.572 3.6,5.486 3.686,8.828 z"/>
|
||||
<path id="path128" style="clip-rule:evenodd;fill-rule:nonzero;stroke-linejoin:round;stroke-miterlimit:1.41420996" d="m 169.38911,146.86429 c 4.714,10.714 14.228,32.056 28.37,64.111 -1.371,0 -4.114,0 -8.313,0 -1.286,-2.657 -3.772,-7.971 -7.543,-15.942 -4.028,0 -12.085,0 -24.17,0 -1.114,2.657 -3.514,7.971 -7.028,15.942 -1.457,0 -4.2,0 -8.4,0 4.543,-10.713 13.542,-32.055 27.084,-64.111 z m 9.171,40.884 c -1.457,-3.686 -4.542,-10.885 -9.085,-21.77 -1.457,3.599 -4.285,10.885 -8.571,21.77 3,0 8.828,0 17.656,0 z"/>
|
||||
<path id="path130" style="clip-rule:evenodd;fill-rule:nonzero;stroke-linejoin:round;stroke-miterlimit:1.41420996" d="m 212.15911,199.83329 c 0.257,0.429 0.6,0.771 0.857,1.114 1.114,1.457 2.657,2.743 4.457,3.686 1.457,0.685 3.085,1.028 4.8,1.028 0.085,0 0.257,0 0.428,0 1.8,0.086 3.514,-0.257 5.143,-1.028 1.628,-0.6 3.171,-1.629 4.457,-2.914 1.285,-1.286 2.228,-2.743 2.914,-4.457 0.685,-1.543 1.028,-3.343 1.028,-5.314 0.086,-1.715 -0.257,-3.429 -1.028,-5.057 -0.6,-1.629 -1.629,-3.171 -2.914,-4.457 -1.286,-1.286 -2.743,-2.229 -4.457,-2.914 -1.115,-0.515 -2.572,-0.772 -4.2,-0.772 -0.172,0 -0.343,0 -0.429,0 -2.657,0.086 -4.714,0.429 -5.999,1.2 -3.429,1.8 -5.143,3.857 -5.143,6.171 0,3 0,7.629 0.086,13.714 z m 0,8.314 c -0.086,3.343 -0.086,10.028 -0.086,20.056 -1.286,0 -4.028,0 -8.057,0 v -54.769 c 2.657,0 5.4,0 8.057,0 0.086,1.286 0.086,2.4 0.086,3.257 0.857,-1.114 2.314,-2.142 4.457,-3.085 2.4,-1.029 4.971,-1.543 7.714,-1.543 2.657,0 5.228,0.514 7.628,1.543 2.485,1.028 4.714,2.485 6.514,4.371 1.971,1.886 3.428,4.028 4.371,6.428 1.028,2.486 1.543,4.971 1.543,7.543 0,0.085 0,0.085 0,0.171 0,2.657 -0.515,5.228 -1.543,7.714 -1.029,2.486 -2.486,4.628 -4.371,6.428 -1.886,1.972 -4.029,3.429 -6.514,4.371 -2.486,1.029 -5.057,1.543 -7.628,1.543 -2.657,-0.085 -5.229,-0.6 -7.714,-1.543 -1.372,-0.514 -2.829,-1.371 -4.457,-2.485 z"/>
|
||||
<path id="path132" style="clip-rule:evenodd;fill-rule:nonzero;stroke-linejoin:round;stroke-miterlimit:1.41420996" d="m 271.04211,180.46329 c 0,-0.086 -0.686,-0.172 -2.143,-0.429 -2.743,-0.086 -5.228,0.857 -7.371,2.828 -0.857,0.772 -1.543,1.886 -2.057,3.343 -0.343,1.371 -0.515,2.829 -0.6,4.457 0,4.543 0,11.399 0,20.399 -1.286,0 -3.943,0 -7.971,0 0,-6.257 0,-18.856 -0.086,-37.627 1.286,0 3.943,0 7.8,0 0.085,0.772 0.085,2.4 0.085,4.8 0,0.514 0,1.543 -0.085,3.171 1.028,-4.199 3.085,-6.856 6.085,-7.971 1.2,-0.343 2.4,-0.514 3.686,-0.514 0.857,-0.086 1.714,0 2.657,0.171 0,1.629 0,4.115 0,7.372 z"/>
|
||||
<path id="path134" style="clip-rule:evenodd;fill:#005184;fill-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:1.41420996" d="m 277.47011,163.23529 c 0,-1.372 0.514,-2.4 1.457,-3.171 0.943,-0.772 1.971,-1.2 3.085,-1.2 0.086,0 0.172,0 0.258,0 1.114,0 2.057,0.342 2.999,1.028 0.943,0.771 1.372,1.8 1.372,3.257 0,1.457 -0.429,2.571 -1.372,3.428 -0.942,0.858 -2.057,1.286 -3.257,1.286 -1.114,0 -2.142,-0.428 -3.085,-1.2 -0.943,-0.771 -1.457,-1.971 -1.457,-3.428 z"/>
|
||||
<path style="clip-rule:evenodd;fill-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:1.41420996" id="path136" d="m 278.15611,173.34929 c 1.371,0 4.028,0 8.056,0 0,6.342 0,18.942 0,37.883 -1.285,0 -3.942,0 -7.885,0 0,-6.256 -0.086,-18.941 -0.171,-37.883 z"/>
|
||||
<path id="path138" style="clip-rule:evenodd;fill-rule:nonzero;stroke-linejoin:round;stroke-miterlimit:1.41420996" d="m 295.55511,146.26429 v 64.797 c 1.285,0 3.942,0 7.885,0 0,-10.799 0,-32.398 0,-64.797 -1.286,0 -3.943,0 -7.885,0 z"/>
|
||||
<path id="path144" style="clip-rule:evenodd;fill:#005184;fill-rule:nonzero;stroke-linejoin:round;stroke-miterlimit:1.41420996" d="m 79.90511,45.008286 c 0.902,0.305 0.903,0.306 1.74,0.76 0,0 2.36,1.6 3.541,2.399 16.192,11.056 46.905,36.807 46.905,36.807 l -0.62,0.933 c 0,0 -30.962,-17.269 -47.812,-25.837 -0.154,2.104 -0.309,4.208 -0.465,6.312 l -0.126,1.689 c -0.635,7.993 -1.295,15.97 -2,23.945 l -0.096,1.076 c -0.824,8.583004 -1.124,17.369004 -3.069,25.573004 -1.802,7.601 -10.27,13.477 -15.485,20.114 -10.856,13.816 -19.361,29.582 -21.64,47.603 -2.579,20.389 5.773,40.853 21.062,55.815 5.92,5.794 12.534,10.853 19.323,15.617 l -3.768,5.852 c -20.581,-12.139 -40.182,-28.618 -47.181,-51.981 -6.615,-22.081 -1.608,-47.917 10.144,-67.278 6.689,-11.02 14.834,-21.098 23.413,-30.201 0,0 0.585,-2.521 0.874,-4.27 3.14,-19.016004 5.383,-38.057004 7.92,-57.227004 l 0.274,-2.074 0.28,-1.686 c 0.307,-0.8 0.337,-1.033 0.841,-1.737 1.119,-1.562 2.062,-2.818 5.945,-2.204 z"/>
|
||||
<path id="path146" style="clip-rule:evenodd;fill:#005184;fill-rule:nonzero;stroke-linejoin:round;stroke-miterlimit:1.41420996" d="m 300.65411,44.858286 c 2.74,0.486 2.778,0.936 3.448,1.587 2.555,2.484 2.191,7.238 2.75,11.471 2.467,18.612 4.172,37.353 7.871,55.935004 0,0 3.607,4.013 6.264,7.099 11.064,12.849 21.019,26.411 26.284,43.975 6.27,20.92 3.585,41.82 -7.633,60.315 -9.349,15.414 -24.268,26.668 -39.964,35.962 l -0.593,-1.853 c 17.279,-12.08 34.133,-26.972 39.318,-48.24 3.677,-15.083 -0.809,-32.515 -6.571,-47.292 -5.094,-13.065 -14.589,-24.209 -23.233,-34.394 -1.789,-2.107 -3.603,-4.192 -5.472,-6.229 0,0 -2.204,-3.069 -2.806,-6.739 -2.582,-15.749 -3.416,-31.540004 -4.699,-47.326004 0,0 -0.34,-4.424 -0.589,-7.754 l -0.098,-1.322 -30.582,18.428 -15.221,9.11 -0.801,0.477 -3.955,-6.151 0.767,-0.531 14.605,-10.067 37.28,-25.534 c 0,0 1.172,-0.939 3.63,-0.927 z m 14.362,70.312004 c 0.178,0.639 -0.049,-0.186 0,0 z"/>
|
||||
</g>
|
||||
</svg>
|
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 8.9 KiB |
19
logo/conversejs-transparent.svg
Normal file
@ -0,0 +1,19 @@
|
||||
<svg class="converse-svg-logo"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
viewBox="0 0 364 364">
|
||||
<title>Converse</title>
|
||||
<g class="cls-1" id="g904">
|
||||
<g data-name="Layer 2">
|
||||
<g data-name="Layer 7">
|
||||
<path
|
||||
class="cls-3"
|
||||
d="M221.46,103.71c0,18.83-29.36,18.83-29.12,0C192.1,84.88,221.46,84.88,221.46,103.71Z" />
|
||||
<path
|
||||
class="cls-4"
|
||||
d="M179.9,4.15A175.48,175.48,0,1,0,355.38,179.63,175.48,175.48,0,0,0,179.9,4.15Zm-40.79,264.5c-.23-17.82,27.58-17.82,27.58,0S138.88,286.48,139.11,268.65ZM218.6,168.24A79.65,79.65,0,0,1,205.15,174a12.76,12.76,0,0,0-6.29,4.65L167.54,222a1.36,1.36,0,0,1-2.46-.8v-35.8a2.58,2.58,0,0,0-3.06-2.53c-15.43,3-30.23,7.7-42.73,19.94-38.8,38-29.42,105.69,16.09,133.16a162.25,162.25,0,0,1-91.47-67.27C-3.86,182.26,34.5,47.25,138.37,25.66c46.89-9.75,118.25,5.16,123.73,62.83C265.15,120.64,246.56,152.89,218.6,168.24Z" />
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.0 KiB |
@ -1,4 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
@ -7,102 +8,39 @@
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
id="chapril-logo"
|
||||
style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:1.41421;"
|
||||
class="converse-svg-logo"
|
||||
viewBox="0 0 364 364"
|
||||
version="1.1"
|
||||
id="svg13"
|
||||
sodipodi:docname="conversejs-with-byline.svg"
|
||||
inkscape:version="0.92.2 5c3e80d, 2017-08-06">
|
||||
<metadata
|
||||
id="metadata19">
|
||||
xml:space="preserve" version="1.1"
|
||||
viewBox="0 0 376 311" height="20%" width="6rem"
|
||||
sodipodi:docname="chapril-logo.svg" inkscape:version="0.92.1 r15371">
|
||||
<sodipodi:namedview pagecolor="#ffffff" bordercolor="#666666" borderopacity="1" objecttolerance="10" gridtolerance="10" guidetolerance="10" inkscape:pageopacity="0" inkscape:pageshadow="2" inkscape:window-width="640" inkscape:window-height="480" id="namedview16" showgrid="false" inkscape:zoom="0.75884244" inkscape:cx="188" inkscape:cy="155.5" inkscape:window-x="0" inkscape:window-y="24" inkscape:window-maximized="0" inkscape:current-layer="svg108"/>
|
||||
<metadata id="metadata114">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<cc:Work rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title>Converse</dc:title>
|
||||
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
|
||||
<dc:title/>
|
||||
<cc:license rdf:resource="GFDL version 1.3 ou ultérieure, Creative Commons By Sa version 2.0 ou ultérieure, Licence Art Libre version 1.3 ou ultérieure"/>
|
||||
<dc:creator>
|
||||
<cc:Agent>
|
||||
<dc:title>Antoine BARDELLI</dc:title>
|
||||
</cc:Agent>
|
||||
</dc:creator>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs
|
||||
id="defs17">
|
||||
<inkscape:perspective
|
||||
sodipodi:type="inkscape:persp3d"
|
||||
inkscape:vp_x="0 : 182 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_z="364 : 182 : 1"
|
||||
inkscape:persp3d-origin="182 : 121.33333 : 1"
|
||||
id="perspective2147" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1434"
|
||||
inkscape:window-height="951"
|
||||
id="namedview15"
|
||||
showgrid="false"
|
||||
inkscape:zoom="1.8338154"
|
||||
inkscape:cx="225.17086"
|
||||
inkscape:cy="243.79827"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="0"
|
||||
inkscape:current-layer="svg13" />
|
||||
<title
|
||||
id="title2">Converse</title>
|
||||
<g
|
||||
class="cls-1"
|
||||
id="g904"
|
||||
transform="matrix(0.2441072,0,0,0.2441072,12.20969,55.55023)">
|
||||
<g
|
||||
data-name="Layer 2"
|
||||
id="g10">
|
||||
<g
|
||||
data-name="Layer 7"
|
||||
id="g8">
|
||||
<path
|
||||
class="cls-3"
|
||||
d="m 221.46,103.71 c 0,18.83 -29.36,18.83 -29.12,0 -0.24,-18.83 29.12,-18.83 29.12,0 z"
|
||||
id="path4"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
class="cls-4"
|
||||
d="M 179.9,4.15 C 108.92504,4.15 44.938239,46.904566 17.778836,112.4757 -9.3805118,178.0467 5.6365472,253.52014 55.823205,303.70679 106.00986,353.89345 181.4833,368.91051 247.0543,341.75116 312.62543,314.59176 355.38,250.60496 355.38,179.63 355.38,82.715072 276.81493,4.15 179.9,4.15 Z m -40.79,264.5 c -0.23,-17.82 27.58,-17.82 27.58,0 0,17.82 -27.81,17.83 -27.58,0 z M 218.6,168.24 c -4.29711,2.32859 -8.79944,4.25673 -13.45,5.76 -2.53177,0.85328 -12.23498,3.26952 -13.79313,5.4398 C 180.90809,189.252 165.08,221.2 165.08,221.2 v -35.8 c -0.003,-1.6153 -1.4729,-2.83052 -3.06,-2.53 -15.43,3 -30.23,7.7 -42.73,19.94 -38.8,38 -29.025098,103.71549 16.4849,131.18549 C 98.17801,323.32071 65.725789,295.74404 44.332966,263.03587 -3.4370336,176.59587 35.058475,51.159326 138.92848,29.569326 185.81848,19.819326 256.62,30.82 262.1,88.49 c 3.05,32.15 -15.54,64.4 -43.5,79.75 z"
|
||||
id="path6"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="sssssscsccccccccccccc" />
|
||||
<defs id="defs112"/>
|
||||
<g id="g250" style="clip-rule:evenodd;fill-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:1.41420996" transform="translate(4.6079614e-7,-4.4571451e-6)">
|
||||
<path id="path124" style="clip-rule:evenodd;fill:#005184;fill-rule:nonzero;stroke-linejoin:round;stroke-miterlimit:1.41420996" d="m 96.70711,209.69029 c -2.742,1.114 -5.399,1.8 -7.885,2.057 -0.771,0.085 -1.629,0.171 -2.4,0.171 -2.571,0 -5.314,-0.428 -8.228,-1.286 -2.486,-0.857 -4.628,-2.314 -6.514,-4.371 -1.886,-1.8 -3.343,-3.942 -4.371,-6.428 -0.943,-2.486 -1.457,-5.057 -1.543,-7.714 0,-0.086 0,-0.257 0,-0.343 0,-2.485 0.514,-4.971 1.543,-7.371 1.028,-2.314 2.485,-4.457 4.371,-6.428 1.886,-2.057 4.028,-3.514 6.514,-4.371 2.828,-1.029 5.571,-1.543 8.142,-1.543 0.257,0 0.6,0 0.857,0 3.686,0.171 6.857,1.028 9.686,2.657 -0.086,1.457 -0.343,3.514 -0.6,6.343 -2.743,-1.372 -5.4,-2.143 -7.971,-2.315 -1.972,-0.171 -3.943,0.086 -6,0.772 -1.629,0.514 -3.171,1.457 -4.457,2.914 -1.286,1.371 -2.228,2.828 -2.914,4.457 -0.772,1.628 -1.114,3.342 -1.114,5.142 0.085,1.886 0.428,3.6 1.114,5.229 0.686,1.714 1.628,3.171 2.914,4.457 1.286,1.285 2.828,2.228 4.457,2.914 2.486,0.685 4.543,1.028 6.343,1.028 3.342,-0.343 5.999,-1.2 8.056,-2.657 0,1.457 0,3.686 0,6.686 z"/>
|
||||
<path id="path126" style="clip-rule:evenodd;fill:#005184;fill-rule:nonzero;stroke-linejoin:round;stroke-miterlimit:1.41420996" d="m 137.33411,184.91929 c 0,1.8 0,3.515 0,5.314 0,2.657 0,5.4 -0.086,8.057 0,4.457 0,8.743 0,12.771 -1.714,0 -4.285,0 -7.799,0 0,-3.857 0,-11.571 0.085,-23.142 0.086,-1.114 -0.171,-2.228 -0.6,-3.257 -0.428,-1.028 -1.028,-1.971 -1.8,-2.742 -0.942,-0.943 -2.142,-1.715 -3.599,-2.143 -1.029,-0.257 -2.229,-0.429 -3.6,-0.343 -1.115,0.086 -2.229,0.343 -3.257,0.686 -1.029,0.428 -2.143,1.028 -3.343,1.8 -0.6,0.6 -1.029,1.2 -1.457,1.8 v 27.341 h -8.057 v -62.997 h 8.057 v 29.313 c 0.943,-1.114 1.8,-1.971 2.571,-2.486 1.629,-0.942 3,-1.542 4.2,-1.885 1.971,-0.429 3.771,-0.6 5.571,-0.6 2.143,0.085 3.943,0.343 5.4,0.943 1.543,0.6 2.914,1.542 4.028,2.742 2.4,2.572 3.6,5.486 3.686,8.828 z"/>
|
||||
<path id="path128" style="clip-rule:evenodd;fill-rule:nonzero;stroke-linejoin:round;stroke-miterlimit:1.41420996" d="m 169.38911,146.86429 c 4.714,10.714 14.228,32.056 28.37,64.111 -1.371,0 -4.114,0 -8.313,0 -1.286,-2.657 -3.772,-7.971 -7.543,-15.942 -4.028,0 -12.085,0 -24.17,0 -1.114,2.657 -3.514,7.971 -7.028,15.942 -1.457,0 -4.2,0 -8.4,0 4.543,-10.713 13.542,-32.055 27.084,-64.111 z m 9.171,40.884 c -1.457,-3.686 -4.542,-10.885 -9.085,-21.77 -1.457,3.599 -4.285,10.885 -8.571,21.77 3,0 8.828,0 17.656,0 z"/>
|
||||
<path id="path130" style="clip-rule:evenodd;fill-rule:nonzero;stroke-linejoin:round;stroke-miterlimit:1.41420996" d="m 212.15911,199.83329 c 0.257,0.429 0.6,0.771 0.857,1.114 1.114,1.457 2.657,2.743 4.457,3.686 1.457,0.685 3.085,1.028 4.8,1.028 0.085,0 0.257,0 0.428,0 1.8,0.086 3.514,-0.257 5.143,-1.028 1.628,-0.6 3.171,-1.629 4.457,-2.914 1.285,-1.286 2.228,-2.743 2.914,-4.457 0.685,-1.543 1.028,-3.343 1.028,-5.314 0.086,-1.715 -0.257,-3.429 -1.028,-5.057 -0.6,-1.629 -1.629,-3.171 -2.914,-4.457 -1.286,-1.286 -2.743,-2.229 -4.457,-2.914 -1.115,-0.515 -2.572,-0.772 -4.2,-0.772 -0.172,0 -0.343,0 -0.429,0 -2.657,0.086 -4.714,0.429 -5.999,1.2 -3.429,1.8 -5.143,3.857 -5.143,6.171 0,3 0,7.629 0.086,13.714 z m 0,8.314 c -0.086,3.343 -0.086,10.028 -0.086,20.056 -1.286,0 -4.028,0 -8.057,0 v -54.769 c 2.657,0 5.4,0 8.057,0 0.086,1.286 0.086,2.4 0.086,3.257 0.857,-1.114 2.314,-2.142 4.457,-3.085 2.4,-1.029 4.971,-1.543 7.714,-1.543 2.657,0 5.228,0.514 7.628,1.543 2.485,1.028 4.714,2.485 6.514,4.371 1.971,1.886 3.428,4.028 4.371,6.428 1.028,2.486 1.543,4.971 1.543,7.543 0,0.085 0,0.085 0,0.171 0,2.657 -0.515,5.228 -1.543,7.714 -1.029,2.486 -2.486,4.628 -4.371,6.428 -1.886,1.972 -4.029,3.429 -6.514,4.371 -2.486,1.029 -5.057,1.543 -7.628,1.543 -2.657,-0.085 -5.229,-0.6 -7.714,-1.543 -1.372,-0.514 -2.829,-1.371 -4.457,-2.485 z"/>
|
||||
<path id="path132" style="clip-rule:evenodd;fill-rule:nonzero;stroke-linejoin:round;stroke-miterlimit:1.41420996" d="m 271.04211,180.46329 c 0,-0.086 -0.686,-0.172 -2.143,-0.429 -2.743,-0.086 -5.228,0.857 -7.371,2.828 -0.857,0.772 -1.543,1.886 -2.057,3.343 -0.343,1.371 -0.515,2.829 -0.6,4.457 0,4.543 0,11.399 0,20.399 -1.286,0 -3.943,0 -7.971,0 0,-6.257 0,-18.856 -0.086,-37.627 1.286,0 3.943,0 7.8,0 0.085,0.772 0.085,2.4 0.085,4.8 0,0.514 0,1.543 -0.085,3.171 1.028,-4.199 3.085,-6.856 6.085,-7.971 1.2,-0.343 2.4,-0.514 3.686,-0.514 0.857,-0.086 1.714,0 2.657,0.171 0,1.629 0,4.115 0,7.372 z"/>
|
||||
<path id="path134" style="clip-rule:evenodd;fill:#005184;fill-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:1.41420996" d="m 277.47011,163.23529 c 0,-1.372 0.514,-2.4 1.457,-3.171 0.943,-0.772 1.971,-1.2 3.085,-1.2 0.086,0 0.172,0 0.258,0 1.114,0 2.057,0.342 2.999,1.028 0.943,0.771 1.372,1.8 1.372,3.257 0,1.457 -0.429,2.571 -1.372,3.428 -0.942,0.858 -2.057,1.286 -3.257,1.286 -1.114,0 -2.142,-0.428 -3.085,-1.2 -0.943,-0.771 -1.457,-1.971 -1.457,-3.428 z"/>
|
||||
<path style="clip-rule:evenodd;fill-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:1.41420996" id="path136" d="m 278.15611,173.34929 c 1.371,0 4.028,0 8.056,0 0,6.342 0,18.942 0,37.883 -1.285,0 -3.942,0 -7.885,0 0,-6.256 -0.086,-18.941 -0.171,-37.883 z"/>
|
||||
<path id="path138" style="clip-rule:evenodd;fill-rule:nonzero;stroke-linejoin:round;stroke-miterlimit:1.41420996" d="m 295.55511,146.26429 v 64.797 c 1.285,0 3.942,0 7.885,0 0,-10.799 0,-32.398 0,-64.797 -1.286,0 -3.943,0 -7.885,0 z"/>
|
||||
<path id="path144" style="clip-rule:evenodd;fill:#005184;fill-rule:nonzero;stroke-linejoin:round;stroke-miterlimit:1.41420996" d="m 79.90511,45.008286 c 0.902,0.305 0.903,0.306 1.74,0.76 0,0 2.36,1.6 3.541,2.399 16.192,11.056 46.905,36.807 46.905,36.807 l -0.62,0.933 c 0,0 -30.962,-17.269 -47.812,-25.837 -0.154,2.104 -0.309,4.208 -0.465,6.312 l -0.126,1.689 c -0.635,7.993 -1.295,15.97 -2,23.945 l -0.096,1.076 c -0.824,8.583004 -1.124,17.369004 -3.069,25.573004 -1.802,7.601 -10.27,13.477 -15.485,20.114 -10.856,13.816 -19.361,29.582 -21.64,47.603 -2.579,20.389 5.773,40.853 21.062,55.815 5.92,5.794 12.534,10.853 19.323,15.617 l -3.768,5.852 c -20.581,-12.139 -40.182,-28.618 -47.181,-51.981 -6.615,-22.081 -1.608,-47.917 10.144,-67.278 6.689,-11.02 14.834,-21.098 23.413,-30.201 0,0 0.585,-2.521 0.874,-4.27 3.14,-19.016004 5.383,-38.057004 7.92,-57.227004 l 0.274,-2.074 0.28,-1.686 c 0.307,-0.8 0.337,-1.033 0.841,-1.737 1.119,-1.562 2.062,-2.818 5.945,-2.204 z"/>
|
||||
<path id="path146" style="clip-rule:evenodd;fill:#005184;fill-rule:nonzero;stroke-linejoin:round;stroke-miterlimit:1.41420996" d="m 300.65411,44.858286 c 2.74,0.486 2.778,0.936 3.448,1.587 2.555,2.484 2.191,7.238 2.75,11.471 2.467,18.612 4.172,37.353 7.871,55.935004 0,0 3.607,4.013 6.264,7.099 11.064,12.849 21.019,26.411 26.284,43.975 6.27,20.92 3.585,41.82 -7.633,60.315 -9.349,15.414 -24.268,26.668 -39.964,35.962 l -0.593,-1.853 c 17.279,-12.08 34.133,-26.972 39.318,-48.24 3.677,-15.083 -0.809,-32.515 -6.571,-47.292 -5.094,-13.065 -14.589,-24.209 -23.233,-34.394 -1.789,-2.107 -3.603,-4.192 -5.472,-6.229 0,0 -2.204,-3.069 -2.806,-6.739 -2.582,-15.749 -3.416,-31.540004 -4.699,-47.326004 0,0 -0.34,-4.424 -0.589,-7.754 l -0.098,-1.322 -30.582,18.428 -15.221,9.11 -0.801,0.477 -3.955,-6.151 0.767,-0.531 14.605,-10.067 37.28,-25.534 c 0,0 1.172,-0.939 3.63,-0.927 z m 14.362,70.312004 c 0.178,0.639 -0.049,-0.186 0,0 z"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:50.63063431px;line-height:125%;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2.10960984px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="110.04511"
|
||||
y="98.826035"
|
||||
id="text861"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan859"
|
||||
x="110.04511"
|
||||
y="98.826035"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:50.63063431px;font-family:Baumans;-inkscape-font-specification:'Baumans, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;stroke-width:2.10960984px">converse<tspan
|
||||
style="fill:#a2a2a2;fill-opacity:1;stroke-width:2.10960984px"
|
||||
id="tspan867">.js</tspan></tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:18.49652481px;line-height:125%;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.77068853px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="124.58434"
|
||||
y="128.44286"
|
||||
id="text865"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan863"
|
||||
x="124.58434"
|
||||
y="128.44286"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:18.49652481px;font-family:Muli;-inkscape-font-specification:'Muli, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#484848;fill-opacity:1;stroke-width:0.77068853px">messaging freedom</tspan></text>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 5.5 KiB After Width: | Height: | Size: 9.0 KiB |
65
logo/mailbox.svg
Normal file
@ -0,0 +1,65 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 15.0.2, SVG Export Plug-In -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
|
||||
<!ENTITY ns_flows "http://ns.adobe.com/Flows/1.0/">
|
||||
]>
|
||||
<svg version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"
|
||||
x="0px" y="0px" width="150px" height="94px" viewBox="0 0 150 94" enable-background="new 0 0 150 94" xml:space="preserve">
|
||||
<defs>
|
||||
</defs>
|
||||
<g>
|
||||
<defs>
|
||||
<rect id="SVGID_1_" width="150" height="94.337"/>
|
||||
</defs>
|
||||
<clipPath id="SVGID_2_">
|
||||
<use xlink:href="#SVGID_1_" overflow="visible"/>
|
||||
</clipPath>
|
||||
<path clip-path="url(#SVGID_2_)" fill="#76BC21" d="M126.282,74.147v13.759c0,0.299,0.148,0.448,0.448,0.448h2.572
|
||||
c0.299,0,0.448-0.149,0.448-0.448V76.003c0.569-0.24,1.556-0.419,2.632-0.419c0.809,0,1.675,0,2.423,0.12
|
||||
c0.3,0.059,0.479-0.09,0.479-0.359V73.19c0-0.238-0.119-0.419-0.388-0.447c-1.138-0.181-2.124-0.24-3.052-0.24
|
||||
c-1.825,0-3.709,0.389-5.233,1.137C126.372,73.729,126.282,73.909,126.282,74.147 M112.913,78.664c0-1.975,1.166-3.05,3.32-3.05
|
||||
c2.123,0,3.319,1.075,3.319,3.05v4.008c0,1.914-1.196,2.931-3.319,2.931c-2.154,0-3.32-1.017-3.32-2.931V78.664z M109.414,78.664
|
||||
v4.008c0,3.709,2.691,6.042,6.819,6.042c4.127,0,6.818-2.333,6.818-6.042v-4.008c0-3.769-2.691-6.161-6.818-6.161
|
||||
C112.105,72.503,109.414,74.896,109.414,78.664 M103.684,85.287v2.588c0,0,0,0.439,0.441,0.439h2.587c0,0,0.441,0,0.441-0.439
|
||||
v-2.588c0,0,0-0.441-0.441-0.441h-2.587C104.125,84.846,103.684,84.846,103.684,85.287 M87.422,87.816
|
||||
c-0.179,0.329-0.059,0.538,0.299,0.538h3.142c0.238,0,0.419-0.09,0.538-0.299l2.99-5.085l2.991,5.085
|
||||
c0.12,0.209,0.299,0.299,0.538,0.299h3.171c0.329,0,0.448-0.209,0.27-0.538l-4.815-7.237l4.546-7.208
|
||||
c0.179-0.271,0.03-0.51-0.299-0.51h-3.021c-0.239,0-0.42,0.12-0.539,0.3l-2.842,4.995l-2.841-4.995c-0.12-0.18-0.299-0.3-0.539-0.3
|
||||
h-3.02c-0.329,0-0.479,0.239-0.299,0.51l4.546,7.208L87.422,87.816z M47.375,67.419v15.493c0,3.647,1.764,5.802,4.995,5.802
|
||||
c0.598,0,1.196-0.03,1.704-0.09c0.24-0.03,0.329-0.239,0.329-0.479v-2.214c0-0.299-0.149-0.448-0.448-0.448
|
||||
c-0.389,0.03-0.778,0.061-1.137,0.061c-1.346,0-1.974-0.778-1.974-2.752V67.419c0-0.299-0.149-0.449-0.448-0.449h-2.573
|
||||
C47.524,66.97,47.375,67.12,47.375,67.419 M40.227,73.281v14.625c0,0.299,0.179,0.448,0.449,0.448h2.602
|
||||
c0.269,0,0.418-0.149,0.418-0.448V73.281c0-0.27-0.149-0.42-0.418-0.42h-2.602C40.406,72.861,40.227,73.012,40.227,73.281
|
||||
M40.226,67.408v2.588c0,0,0,0.439,0.44,0.439h2.588c0,0,0.441,0,0.441-0.439v-2.588c0,0,0-0.44-0.441-0.44h-2.588
|
||||
C40.666,66.968,40.226,66.968,40.226,67.408 M27.127,83.688c0-1.226,0.897-1.974,3.141-1.974c0.927,0,2.093,0.12,2.901,0.239v3.38
|
||||
c-0.748,0.18-1.885,0.358-2.871,0.358C28.473,85.692,27.127,85.095,27.127,83.688 M23.628,83.719c0,3.739,3.2,4.995,6.67,4.995
|
||||
c2.213,0,4.456-0.419,6.011-0.897c0.21-0.09,0.329-0.27,0.329-0.509v-8.732c0-4.218-2.512-6.072-6.221-6.072
|
||||
c-2.423,0-4.426,0.598-5.862,1.585c-0.15,0.12-0.15,0.27,0,0.509l1.196,1.824c0.15,0.24,0.389,0.269,0.599,0.12
|
||||
c0.957-0.568,2.332-0.957,3.828-0.957c2.213,0,2.991,0.896,2.991,3.021v0.568c-0.898-0.12-2.004-0.239-2.991-0.239
|
||||
C26.35,78.934,23.628,80.459,23.628,83.719 M0,74.208v13.698c0,0.299,0.15,0.448,0.449,0.448h2.572
|
||||
c0.299,0,0.448-0.149,0.448-0.448V75.942c0.599-0.18,1.376-0.328,2.393-0.328c1.944,0,2.961,0.957,2.961,3.14v9.152
|
||||
c0,0.299,0.18,0.448,0.449,0.448h2.572c0.299,0,0.449-0.149,0.449-0.448v-9.093c0-0.896-0.15-1.705-0.389-2.423
|
||||
c0.777-0.508,1.645-0.747,2.632-0.747c2.153,0,3.08,1.166,3.08,3.11v9.152c0,0.299,0.15,0.448,0.419,0.448h2.602
|
||||
c0.269,0,0.419-0.149,0.419-0.448v-9.032c0-4.188-2.692-6.371-6.43-6.371c-1.735,0-3.021,0.449-4.517,1.376
|
||||
c-1.106-0.867-2.572-1.376-4.337-1.376c-1.884,0-3.768,0.449-5.413,1.167C0.09,73.789,0,73.969,0,74.208 M38.766,32.55
|
||||
l24.153-16.543V0H5.841C5.841,0,0,0,0,5.84V6L38.766,32.55z M5.841,56.86h57.078V24.5l-22.62,15.422
|
||||
c-1.609,1.096-3.212-0.007-3.212-0.007L0,14.399v36.622C0,51.021,0,56.86,5.841,56.86 M66.217,82.164
|
||||
c0,2.542-1.286,3.438-3.439,3.438c-1.017,0-2.094-0.119-2.812-0.418V76.36c0.748-0.478,1.735-0.776,2.872-0.776
|
||||
c2.153,0,3.379,0.987,3.379,3.26V82.164z M69.747,82.134v-3.29c0-3.888-2.782-6.341-6.551-6.341c-1.196,0-2.303,0.269-3.23,0.658
|
||||
v-5.742c0-0.299-0.149-0.449-0.448-0.449h-2.572c-0.3,0-0.449,0.15-0.449,0.449v19.71c0,0.269,0.09,0.418,0.359,0.508
|
||||
c1.764,0.658,4.067,1.077,6.011,1.077C66.815,88.714,69.747,86.68,69.747,82.134 M79.287,75.614c2.124,0,3.32,1.075,3.32,3.05
|
||||
v4.008c0,1.914-1.196,2.931-3.32,2.931c-2.153,0-3.32-1.017-3.32-2.931v-4.008C75.967,76.689,77.134,75.614,79.287,75.614
|
||||
M79.287,72.503c-4.127,0-6.819,2.393-6.819,6.161v4.008c0,3.709,2.692,6.042,6.819,6.042c4.128,0,6.819-2.333,6.819-6.042v-4.008
|
||||
C86.106,74.896,83.415,72.503,79.287,72.503 M136.852,56.86H150V20.354C150,4.709,141.719,0,129.337,0
|
||||
c-6.5,0-12.005,1.437-16.081,3.066C111.163,1.763,107.924,0,100.212,0c-6.853,0-17.63,2.3-21.29,5.095V56.86h12.997V12.372
|
||||
c3.037-0.74,5.101-1.31,8.449-1.285c5.256,0.039,7.397,2.31,7.554,9.618V56.86h12.966l-0.078-36.959
|
||||
c0-5.215-1.013-7.529-1.013-7.529c2.688-0.895,5.255-1.285,9.034-1.285c5.918,0,7.826,2.453,8.059,9.773L136.852,56.86z
|
||||
M146.531,84.107c-0.569,0.479-1.825,0.748-2.961,0.748c-1.825,0-3.29-0.777-3.29-3.141v-2.811c0-2.572,1.404-3.29,3.469-3.29
|
||||
c0.897,0,2.153,0.118,2.782,0.328V84.107z M150,87.368v-13.19c0-0.239-0.09-0.419-0.329-0.508
|
||||
c-1.615-0.688-3.769-1.167-5.981-1.167c-3.799,0-6.909,1.705-6.909,6.401v2.811c0,4.217,2.931,6.191,6.461,6.191
|
||||
c1.076,0,2.361-0.239,3.318-0.658c0.091,3.021-0.986,4.008-3.229,4.008c-1.555,0-2.931-0.538-4.037-1.346
|
||||
c-0.24-0.18-0.449-0.119-0.599,0.12l-1.257,1.854c-0.148,0.269-0.148,0.449,0.091,0.598c1.585,1.228,3.38,1.855,5.832,1.855
|
||||
C148.086,94.337,150,91.795,150,87.368"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 5.8 KiB |
@ -2,7 +2,7 @@
|
||||
"short_name": "Converse",
|
||||
"name": "Converse Chat",
|
||||
"description": "Messaging Freedom",
|
||||
"version": "7.0.1",
|
||||
"version": "10.1.6",
|
||||
"categories": ["social"],
|
||||
"icons": [
|
||||
{
|
||||
|
@ -4,6 +4,7 @@
|
||||
<title>Converse.js | Mobile</title>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta name="description" content="Converse: An XMPP chat client which can be integrated into any website" />
|
||||
<meta name="author" content="JC Brand" />
|
||||
@ -18,9 +19,9 @@
|
||||
<script type="text/javascript" src="analytics.js"></script>
|
||||
<!-- *********************************************************************** -->
|
||||
|
||||
<link type="text/css" rel="stylesheet" media="screen" href="https://cdn.conversejs.org/7.0.1/dist/converse.min.css" />
|
||||
<link type="text/css" rel="stylesheet" media="screen" href="https://cdn.conversejs.org/10.1.6/dist/converse.min.css" />
|
||||
<script src="https://cdn.conversejs.org/3rdparty/libsignal-protocol.min.js"></script>
|
||||
<script src="https://cdn.conversejs.org/7.0.1/dist/converse.min.js"></script>
|
||||
<script src="https://cdn.conversejs.org/10.1.6/dist/converse.min.js"></script>
|
||||
</head>
|
||||
|
||||
<body id="page-top" data-spy="scroll" class="converse-website">
|
||||
@ -240,11 +241,9 @@
|
||||
<h2>Converse is supported by:</h2>
|
||||
<ul >
|
||||
<li><a href="https://www.keycdn.com?utm_source=conversejs" target="_blank" rel="noopener"><img style="height: 3em" src="/logo/keycdn.svg" alt="KeyCDN"></a></li>
|
||||
<li><a href="https://wikisuite.org/?utm_source=conversejs" target="_blank" rel="noopener"><img style="height: 4em" src="/logo/wikisuite-white.png" alt="WikiSuite"></a></li>
|
||||
<li><a href="https://weblate.org?utm_source=conversejs" target="_blank" rel="noopener"><img style="height: 2.6em" src="/logo/weblate-button.svg" alt="Weblate"></a></li>
|
||||
<li><a href="https://www.codefirst.co.uk?utm_source=conversejs" target="_blank" rel="noopener"><img style="width: 12em; padding-top: 0.5em" src="/logo/codefirst.png" alt="Codefirst"></a></li>
|
||||
<li><a href="https://www.b1-systems.de?utm_source=conversejs" target="_blank" rel="noopener"><img style="height: 5em" src="/logo/b1-systems.svg" alt="B1 Systems"></a></li>
|
||||
<li><a href="https://blokt.com?utm_source=conversejs" target="_blank" rel="noopener"><img style="width: 12em" src="/logo/blokt.png" alt="Blokt Crypto & Privacy"></a></li>
|
||||
<li><a href="https://primesound.org/?utm_source=conversejs" target="_blank" rel="noopener"><img style="width: 10em" src="/media/logos/primesound.png" alt="Prime Sound"></a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
|
32247
package-lock.json
generated
172
package.json
@ -1,36 +1,46 @@
|
||||
{
|
||||
"name": "converse.js",
|
||||
"version": "7.0.1",
|
||||
"version": "10.1.6",
|
||||
"description": "Browser based XMPP chat client",
|
||||
"browser": "dist/converse.js",
|
||||
"module": "src/converse.js",
|
||||
"module": "src/index.js",
|
||||
"workspaces": [
|
||||
"src/headless"
|
||||
],
|
||||
"files": [
|
||||
"CHANGES.md",
|
||||
"LICENSE.txt",
|
||||
"README.md",
|
||||
"COPYRIGHT",
|
||||
"dist/",
|
||||
"locale/",
|
||||
"sass/",
|
||||
"sounds/",
|
||||
"src/*.js",
|
||||
"src/utils/*.js",
|
||||
"src/templates/*.html",
|
||||
"src/templates/*.svg",
|
||||
"src/templates/*.js",
|
||||
"src/headless/"
|
||||
"docs/**/*.md",
|
||||
"docs/**/*.rst",
|
||||
"sass/**/*.scss",
|
||||
"src/**/*.html",
|
||||
"src/**/*.js",
|
||||
"src/**/*.json",
|
||||
"src/**/*.md",
|
||||
"src/**/*.po",
|
||||
"src/**/*.pot",
|
||||
"src/**/*.scss",
|
||||
"src/**/*.svg",
|
||||
"src/**/*.txt",
|
||||
"3rdparty/*.js"
|
||||
],
|
||||
"scripts": {
|
||||
"serve": "webpack-dev-server --config webpack.serve.js",
|
||||
"build": "webpack --config webpack/webpack.build.js",
|
||||
"lint": "eslint src/**/*.js",
|
||||
"test": "karma start karma.conf",
|
||||
"cdn": "ASSET_PATH=https://cdn.conversejs.org/dist/ npm run build",
|
||||
"clean": "rm -rf node_modules dist *.zip src/headless/dist src/headless/node_modules",
|
||||
"headless": "webpack --config webpack.headless.js",
|
||||
"nodeps": "webpack --config webpack.nodeps.js",
|
||||
"cdn": "ASSET_PATH=https://cdn.conversejs.org/dist/ npm run dev && ASSET_PATH=https://cdn.conversejs.org/dist/ npm run build",
|
||||
"prod": "webpack --config webpack.prod.js",
|
||||
"build": "npm run dev && npm run prod",
|
||||
"dev": "webpack --config webpack.dev.js",
|
||||
"watch": "webpack --watch --config webpack.dev.js",
|
||||
"lerna": "lerna bootstrap --hoist --ignore-scripts",
|
||||
"prepare": "npm run lerna && npm run build"
|
||||
"dev": "webpack --config webpack/webpack.build.js --mode=development",
|
||||
"headless": "webpack --config webpack/webpack.headless.js",
|
||||
"headless-dev": "webpack --config webpack/webpack.headless.js --mode=development",
|
||||
"nodeps": "webpack --config webpack/webpack.nodeps.js",
|
||||
"serve": "webpack serve --config webpack/webpack.serve.js",
|
||||
"watch": "webpack --watch --config webpack/webpack.build.js --mode=development",
|
||||
"types": "tsc --declaration --emitDeclarationOnly --allowJs",
|
||||
"check:types": "tsc --noEmit"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@ -57,68 +67,70 @@
|
||||
"browser": "*"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/cli": "^7.10.3",
|
||||
"@babel/core": "^7.10.5",
|
||||
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.10.1",
|
||||
"@babel/plugin-proposal-optional-chaining": "^7.12.1",
|
||||
"@babel/plugin-syntax-dynamic-import": "^7.2.0",
|
||||
"@babel/preset-env": "^7.10.2",
|
||||
"@babel/cli": "^7.17.10",
|
||||
"@babel/core": "^7.18.5",
|
||||
"@babel/preset-env": "^7.18.2",
|
||||
"@converse/headless": "file:src/headless",
|
||||
"@fortawesome/fontawesome-free": "5.14.0",
|
||||
"autoprefixer": "^9.8.4",
|
||||
"babel-eslint": "^10.1.0",
|
||||
"babel-loader": "^8.1.0",
|
||||
"bootstrap": "^4.3.1",
|
||||
"bootstrap.native": "^2.0.27",
|
||||
"@typescript-eslint/eslint-plugin": "^5.48.0",
|
||||
"autoprefixer": "^10.4.5",
|
||||
"babel-loader": "^9.1.0",
|
||||
"bootstrap.native-loader": "2.0.0",
|
||||
"clean-css-cli": "^4.3.0",
|
||||
"copy-webpack-plugin": "^6.0.2",
|
||||
"css-loader": "^3.5.3",
|
||||
"dayjs": "1.8.30",
|
||||
"eslint": "^7.3.0",
|
||||
"eslint-plugin-lodash": "^7.1.0",
|
||||
"exports-loader": "^0.7.0",
|
||||
"fast-text-encoding": "^1.0.2",
|
||||
"favico.js-slevomat": "^0.3.11",
|
||||
"file-loader": "^6.0.0",
|
||||
"haunted": "^4.7.0",
|
||||
"html-webpack-plugin": "^4.3.0",
|
||||
"http-server": "^0.12.3",
|
||||
"imports-loader": "^0.8.0",
|
||||
"clean-css-cli": "^5.6.2",
|
||||
"copy-webpack-plugin": "^11.0.0",
|
||||
"css-loader": "^6.7.1",
|
||||
"eslint": "^8.21.0",
|
||||
"fast-text-encoding": "^1.0.3",
|
||||
"html-webpack-plugin": "^5.3.2",
|
||||
"http-server": "^14.1.0",
|
||||
"imports-loader": "^4.0.0",
|
||||
"install": "^0.13.0",
|
||||
"jasmine": "^3.5.0",
|
||||
"jed": "1.1.1",
|
||||
"jsdoc": "^3.6.4",
|
||||
"karma": "^5.1.0",
|
||||
"karma-chrome-launcher": "^3.1.0",
|
||||
"jsdoc": "^4.0.0",
|
||||
"karma": "^6.3.19",
|
||||
"karma-chrome-launcher": "^3.1.1",
|
||||
"karma-cli": "^2.0.0",
|
||||
"karma-jasmine": "^3.1.1",
|
||||
"karma-jasmine-html-reporter": "^1.5.4",
|
||||
"karma-webpack": "^4.0.2",
|
||||
"lerna": "^3.22.1",
|
||||
"lit-element": "^2.3.1",
|
||||
"lit-html": "^1.2.1",
|
||||
"lodash-template-webpack-loader": "jcbrand/lodash-template-webpack-loader",
|
||||
"mini-css-extract-plugin": "^0.9.0",
|
||||
"minimist": "^1.2.3",
|
||||
"node-sass": "^4.14.1",
|
||||
"npm": "^6.14.6",
|
||||
"po-loader": "^0.5.0",
|
||||
"po2json": "^1.0.0-beta",
|
||||
"postcss-clean": "^1.1.0",
|
||||
"postcss-loader": "^3.0.0",
|
||||
"prettierx": "^0.12.1",
|
||||
"run-headless-chromium": "^0.1.1",
|
||||
"sass-loader": "^8.0.2",
|
||||
"sinon": "^9.0.2",
|
||||
"sizzle": "^2.3.5",
|
||||
"style-loader": "^0.23.1",
|
||||
"urijs": "^1.19.2",
|
||||
"webpack": "^4.43.0",
|
||||
"webpack-cli": "^3.3.12",
|
||||
"webpack-dev-server": "^3.11.0",
|
||||
"webpack-merge": "^5.0.9",
|
||||
"xss": "^1.0.7"
|
||||
"karma-jasmine": "^5.0.0",
|
||||
"karma-jasmine-html-reporter": "^2.0.0",
|
||||
"karma-webpack": "^5.0.0",
|
||||
"mini-css-extract-plugin": "^2.6.0",
|
||||
"minimist": "^1.2.6",
|
||||
"po-loader": "0.7.0",
|
||||
"po2json": "^1.0.0-beta-3",
|
||||
"postcss": "^8.4.16",
|
||||
"postcss-loader": "^7.0.1",
|
||||
"prettierx": "^0.19.0",
|
||||
"sass": "^1.51.0",
|
||||
"sass-loader": "^13.1.0",
|
||||
"style-loader": "^3.1.0",
|
||||
"tsc": "^2.0.4",
|
||||
"typescript": "^4.9.5",
|
||||
"typescript-eslint-parser": "^22.0.0",
|
||||
"uglify-js": "^3.17.4",
|
||||
"webpack": "^5.86.0",
|
||||
"webpack-cli": "^5.1.4",
|
||||
"webpack-dev-server": "^4.8.1",
|
||||
"webpack-merge": "^5.8.0"
|
||||
},
|
||||
"dependencies": {}
|
||||
"dependencies": {
|
||||
"@converse/openpromise": "^0.0.1",
|
||||
"@converse/skeletor": "^0.0.8",
|
||||
"bootstrap": "^4.6.0",
|
||||
"bootstrap.native": "^2.0.27",
|
||||
"client-compress": "^2.2.2",
|
||||
"dayjs": "^1.11.8",
|
||||
"dompurify": "^2.3.1",
|
||||
"favico.js-slevomat": "^0.3.11",
|
||||
"gifuct-js": "^2.1.2",
|
||||
"jed": "1.1.1",
|
||||
"lit": "^2.4.0",
|
||||
"localforage-webextensionstorage-driver": "^3.0.0",
|
||||
"lodash-es": "^4.17.21",
|
||||
"pluggable.js": "^3.0.1",
|
||||
"sizzle": "^2.3.5",
|
||||
"sprintf-js": "^1.1.2",
|
||||
"strophe.js": "^1.6.2",
|
||||
"urijs": "^1.19.10"
|
||||
},
|
||||
"resolutions": {
|
||||
"autoprefixer": "10.4.5"
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,5 @@
|
||||
module.exports = {
|
||||
plugins: [
|
||||
require('autoprefixer'),
|
||||
require('postcss-clean')
|
||||
]
|
||||
}
|
||||
|
@ -1 +1,3 @@
|
||||
zc.buildout==2.13.2
|
||||
Sphinx==4.5.0
|
||||
docutils==0.17.1
|
||||
sphinx-bootstrap-theme==0.8.1
|
||||
|
@ -1,633 +0,0 @@
|
||||
#conversejs {
|
||||
.chatbox-navback {
|
||||
display: none;
|
||||
}
|
||||
.flyout {
|
||||
position: absolute;
|
||||
|
||||
@media screen and (max-height: $mobile-landscape-height) {
|
||||
border-radius: 0;
|
||||
}
|
||||
@media screen and (max-width: $mobile-portrait-length) {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
@media screen and (max-height: $mobile-landscape-height) {
|
||||
bottom: 0;
|
||||
}
|
||||
@media screen and (max-width: $mobile-portrait-length) {
|
||||
bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.chatbox-btn {
|
||||
border-radius: 25%;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
font-size: var(--chatbox-button-size);
|
||||
margin: 0 0.2em;
|
||||
padding: 0 0 0 0.5em;
|
||||
text-decoration: none;
|
||||
|
||||
&:active {
|
||||
position: relative;
|
||||
top: 1px;
|
||||
}
|
||||
}
|
||||
|
||||
.chat-head {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
color: #ffffff;
|
||||
font-size: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
position: relative;
|
||||
|
||||
&.chat-head-chatbox {
|
||||
background-color: var(--chat-head-color);
|
||||
}
|
||||
|
||||
.avatar {
|
||||
margin-right: 0.5em;
|
||||
}
|
||||
|
||||
.chat-head__desc {
|
||||
color: var(--chat-head-color-lighten-50-percent);
|
||||
font-size: var(--font-size-small);
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
padding: 0.5rem 1rem 0.5rem 1rem;
|
||||
text-overflow: ellipsis;
|
||||
width: 100%;
|
||||
max-height: 5em;
|
||||
}
|
||||
|
||||
.chatbox-title {
|
||||
padding: 0.75rem 1rem 0 1rem;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.chatbox-title--no-desc {
|
||||
padding: 0.75rem 1rem;
|
||||
}
|
||||
|
||||
.chatbox-title--row {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.chatbox-title__text {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.chatbox-title__buttons {
|
||||
display: flex;
|
||||
flex-direction: row-reverse;
|
||||
flex-wrap: nowrap;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
a, a:visited, a:hover, a:not([href]):not([tabindex]) {
|
||||
&.chatbox-btn {
|
||||
&.fa,
|
||||
&.fas,
|
||||
&.far {
|
||||
color: white;
|
||||
&.button-on:before {
|
||||
padding: 0.2em;
|
||||
background-color: var(--chat-head-text-color);
|
||||
color: var(--chat-head-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.chatbox-btn {
|
||||
color: white;
|
||||
&.fa, &.far, &.fas {
|
||||
color: white;
|
||||
}
|
||||
&:active {
|
||||
position: relative;
|
||||
top: 1px;
|
||||
}
|
||||
&.button-on:before {
|
||||
border-radius: 5%;
|
||||
background-color: var(--chat-head-text-color);
|
||||
color: var(--chat-head-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.chatbox {
|
||||
text-align: left;
|
||||
margin: 0 var(--chat-gutter);
|
||||
|
||||
@media screen and (max-height: $mobile-landscape-height) {
|
||||
margin: 0;
|
||||
width: var(--mobile-chat-width);
|
||||
}
|
||||
@media screen and (max-width: $mobile-portrait-length) {
|
||||
margin: 0;
|
||||
width: var(--mobile-chat-width);
|
||||
}
|
||||
|
||||
.box-flyout {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
box-shadow: 1px 3px 5px 3px rgba(0, 0, 0, 0.4);
|
||||
z-index: 2;
|
||||
overflow: hidden;
|
||||
width: 100%;
|
||||
|
||||
@media screen and (max-height: $mobile-landscape-height) {
|
||||
height: var(--mobile-chat-height);
|
||||
width: var(--mobile-chat-width);
|
||||
height: var(--fullpage-chat-height);
|
||||
}
|
||||
@media screen and (max-width: $mobile-portrait-length) {
|
||||
height: var(--mobile-chat-height);
|
||||
width: var(--mobile-chat-width);
|
||||
height: var(--fullpage-chat-height);
|
||||
}
|
||||
}
|
||||
.chat-title {
|
||||
display: var(--heading-display);
|
||||
font-family: var(--heading-font);
|
||||
color: var(--heading-color);
|
||||
display: block;
|
||||
line-height: var(--line-height-large);
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
&.groupchat {
|
||||
padding-right: var(--chatroom-head-title-padding-right);
|
||||
}
|
||||
a {
|
||||
color: var(--chat-head-text-color);
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
.chat-body {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
background-color: var(--chat-head-color);
|
||||
border-bottom-left-radius: var(--chatbox-border-radius);
|
||||
border-bottom-right-radius: var(--chatbox-border-radius);
|
||||
|
||||
@media screen and (max-height: $mobile-landscape-height) {
|
||||
border-bottom-left-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
}
|
||||
@media screen and (max-width: $mobile-portrait-length) {
|
||||
border-bottom-left-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
}
|
||||
border-top: 0;
|
||||
p {
|
||||
color: var(--text-color);
|
||||
font-size: var(--message-font-size);
|
||||
margin: 0;
|
||||
padding: 5px;
|
||||
}
|
||||
}
|
||||
.new-msgs-indicator {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
cursor: pointer;
|
||||
background-color: var(--chat-head-color);
|
||||
color: var(--light-background-color);
|
||||
padding: 0.5em;
|
||||
font-size: 0.9em;
|
||||
text-align: center;
|
||||
z-index: 20;
|
||||
white-space: nowrap;
|
||||
margin-bottom: 0.25em;
|
||||
}
|
||||
.chat-content {
|
||||
background-color: var(--chat-content-background-color);
|
||||
border: 0;
|
||||
color: var(--text-color);
|
||||
font-size: var(--message-font-size);
|
||||
height: 100%;
|
||||
line-height: 1.3em;
|
||||
overflow: hidden;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
|
||||
converse-chat-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
converse-chat-message {
|
||||
.spinner {
|
||||
width: 100%;
|
||||
overflow-y: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
.chat-content__help {
|
||||
border-top: 1px solid var(--chat-head-color);
|
||||
max-height: 100%;
|
||||
.close-chat-help {
|
||||
svg {
|
||||
fill: var(--chat-head-color);
|
||||
}
|
||||
}
|
||||
|
||||
converse-chat-help {
|
||||
height: 100%;
|
||||
overflow-y: auto;
|
||||
display: block;
|
||||
padding: 0.5em 0;
|
||||
}
|
||||
.close-chat-help {
|
||||
float: right;
|
||||
padding-right: 1em;
|
||||
cursor: pointer;
|
||||
color: var(--chat-content-background-color);
|
||||
}
|
||||
}
|
||||
|
||||
.chat-content__messages {
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.chat-content__notifications {
|
||||
height: 1.7em;
|
||||
white-space: pre;
|
||||
background-color: var(--chat-content-background-color);
|
||||
color: var(--subdued-color);
|
||||
font-size: 90%;
|
||||
font-style: italic;
|
||||
line-height: var(--line-height-small);
|
||||
padding: 0 1em 0.3em;
|
||||
&:before {
|
||||
content: " ";
|
||||
}
|
||||
}
|
||||
|
||||
video {
|
||||
width: 100%
|
||||
}
|
||||
progress {
|
||||
margin: 0.5em 0;
|
||||
width: 100%
|
||||
}
|
||||
}
|
||||
|
||||
.chat-content-sendbutton {
|
||||
height: calc(100% - (var(--chat-textarea-height) + var(--send-button-height) + 2 * var(--send-button-margin)));
|
||||
}
|
||||
|
||||
.dropdown { /* status dropdown styles */
|
||||
background-color: var(--light-background-color);
|
||||
dd {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
position: relative;
|
||||
}
|
||||
}
|
||||
|
||||
.sendXMPPMessage {
|
||||
-moz-background-clip: padding;
|
||||
-webkit-background-clip: padding-box;
|
||||
border-bottom-radius: var(--chatbox-border-radius);
|
||||
background-clip: padding-box;
|
||||
background-color: white;
|
||||
border: 0;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
@media screen and (max-height: $mobile-landscape-height) {
|
||||
width: 100%;
|
||||
}
|
||||
@media screen and (max-width: $mobile-portrait-length) {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.suggestion-box__results {
|
||||
&:after {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.spoiler-hint {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.chat-textarea, input {
|
||||
&:active, &:focus{
|
||||
outline-color: var(--chat-head-color);
|
||||
}
|
||||
&.correcting {
|
||||
background-color: var(--chat-correcting-color);
|
||||
}
|
||||
}
|
||||
|
||||
.chat-textarea {
|
||||
color: var(--chat-textarea-color);
|
||||
background-color: var(--chat-textarea-background-color);
|
||||
border-top-left-radius: 0;
|
||||
border-top-right-radius: 0;
|
||||
border-bottom-radius: var(--chatbox-border-radius);
|
||||
padding-left: 0.5em;
|
||||
padding-right: 4.5em;
|
||||
padding-top: 0.5em;
|
||||
padding-bottom:0.5em;
|
||||
width: 100%;
|
||||
border: none;
|
||||
min-height: var(--chat-textarea-height);
|
||||
margin-bottom: -4px; // Not clear why this is necessar :(
|
||||
resize: none;
|
||||
&.spoiler {
|
||||
height: 42px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.dragresize {
|
||||
background: transparent;
|
||||
border: 0;
|
||||
margin: 0;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
z-index: 20;
|
||||
&-top {
|
||||
cursor: n-resize;
|
||||
height: 5px;
|
||||
width: 100%;
|
||||
}
|
||||
&-left,
|
||||
&-occupants-left {
|
||||
cursor: w-resize;
|
||||
width: 5px;
|
||||
height: 100%;
|
||||
left: 0;
|
||||
}
|
||||
&-topleft {
|
||||
cursor: nw-resize;
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ******************* Overlay and embedded styles *************************** */
|
||||
|
||||
#conversejs.converse-embedded,
|
||||
#conversejs.converse-overlayed {
|
||||
.controlbox-head {
|
||||
padding: 0.5em;
|
||||
}
|
||||
.chat-head {
|
||||
border-top-left-radius: 0;
|
||||
border-top-right-radius: 0;
|
||||
}
|
||||
.chatbox {
|
||||
min-width: var(--overlayed-chat-width) !important;
|
||||
width: var(--overlayed-chat-width);
|
||||
|
||||
.box-flyout {
|
||||
min-width: var(--overlayed-chat-width) !important;
|
||||
width: var(--overlayed-chat-width);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#conversejs.converse-overlayed {
|
||||
|
||||
.chat-head, .box-flyout {
|
||||
border-top-left-radius: var(--chatbox-border-radius);
|
||||
border-top-right-radius: var(--chatbox-border-radius);
|
||||
@media screen and (max-height: $mobile-landscape-height) {
|
||||
border-top-left-radius: 0;
|
||||
border-top-right-radius: 0;
|
||||
}
|
||||
@media screen and (max-width: $mobile-portrait-length) {
|
||||
border-top-left-radius: 0;
|
||||
border-top-right-radius: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.flyout {
|
||||
bottom: var(--overlayed-chatbox-hover-height);
|
||||
}
|
||||
.box-flyout {
|
||||
height: var(--overlayed-chat-height);
|
||||
min-height: calc(var(--overlayed-chat-height) / 2);
|
||||
}
|
||||
.chat-head {
|
||||
min-height: var(--overlayed-chat-head-height);
|
||||
}
|
||||
.minimized-chats-flyout .chat-head {
|
||||
cursor: default;
|
||||
}
|
||||
.chat-textarea {
|
||||
max-height: var(--overlayed-max-chat-textarea-height);
|
||||
}
|
||||
.chatbox {
|
||||
.chat-body {
|
||||
height: calc(100% - var(--overlayed-chat-head-height));
|
||||
}
|
||||
.chatbox-title {
|
||||
padding: 0.5rem 0.75rem 0 0.75rem;
|
||||
}
|
||||
.chatbox-title--no-desc {
|
||||
padding: 0.5rem 0.75rem;
|
||||
}
|
||||
converse-dropdown {
|
||||
.btn--standalone {
|
||||
padding: 0 0.2em;
|
||||
margin: 0 0 0 0.5em;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@include media-breakpoint-down(sm) {
|
||||
#conversejs.converse-overlayed {
|
||||
> .row {
|
||||
flex-direction: column;
|
||||
&.no-gutters {
|
||||
margin: -1em;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#conversejs.converse-embedded,
|
||||
#conversejs.converse-fullscreen {
|
||||
.flyout {
|
||||
border-radius: 0;
|
||||
border:none;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
.chatbox {
|
||||
margin: 0;
|
||||
.box-flyout {
|
||||
box-shadow: none;
|
||||
overflow: hidden;
|
||||
}
|
||||
@include make-col-ready();
|
||||
@include media-breakpoint-up(md) {
|
||||
@include make-col(8);
|
||||
}
|
||||
@include media-breakpoint-up(lg) {
|
||||
@include make-col(9);
|
||||
}
|
||||
@include media-breakpoint-up(xl) {
|
||||
@include make-col(10);
|
||||
}
|
||||
}
|
||||
|
||||
&.converse-singleton {
|
||||
.flyout {
|
||||
border: none !important;
|
||||
}
|
||||
.chat-head {
|
||||
padding: 0.5em;
|
||||
}
|
||||
.chatbox {
|
||||
margin: 0;
|
||||
@include make-col-ready();
|
||||
@include media-breakpoint-up(md) {
|
||||
@include make-col(12);
|
||||
}
|
||||
@include media-breakpoint-up(lg) {
|
||||
@include make-col(12);
|
||||
}
|
||||
@include media-breakpoint-up(xl) {
|
||||
@include make-col(12);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#conversejs.converse-embedded {
|
||||
.chat-head {
|
||||
font-size: var(--font-size-huge);
|
||||
}
|
||||
|
||||
.converse-chatboxes {
|
||||
z-index: 1031; // One more than bootstrap navbar
|
||||
position: inherit;
|
||||
flex-wrap: nowrap;
|
||||
bottom: auto;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
margin-left: -15px;
|
||||
}
|
||||
|
||||
.chatbox {
|
||||
.box-flyout {
|
||||
bottom: 0;
|
||||
height: 100%;
|
||||
min-width: auto;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.chat-textarea {
|
||||
max-height: var(--fullpage-max-chat-textarea-height);
|
||||
}
|
||||
}
|
||||
|
||||
/* ******************* Fullpage styles *************************** */
|
||||
|
||||
#conversejs.converse-fullscreen {
|
||||
.chatbox-btn {
|
||||
font-size: var(--fullpage-chatbox-button-size);
|
||||
margin: 0 0.3em;
|
||||
}
|
||||
.chat-head {
|
||||
font-size: var(--font-size-huge);
|
||||
}
|
||||
.chat-textarea {
|
||||
max-height: var(--fullpage-max-chat-textarea-height);
|
||||
}
|
||||
.chatbox {
|
||||
.box-flyout {
|
||||
box-shadow: none;
|
||||
height: var(--fullpage-chat-height);
|
||||
min-height: calc(var(--fullpage-chat-height) / 2);
|
||||
width: var(--fullpage-chat-width);
|
||||
overflow: hidden;
|
||||
}
|
||||
.chat-body {
|
||||
height: inherit;
|
||||
overflow: hidden;
|
||||
background-color: var(--chat-head-color);
|
||||
}
|
||||
.chat-title {
|
||||
font-size: var(--font-size-huge);
|
||||
line-height: var(--line-height-huge);
|
||||
}
|
||||
.sendXMPPMessage {
|
||||
ul {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@include media-breakpoint-down(sm) {
|
||||
#conversejs:not(.converse-embedded) {
|
||||
> .row {
|
||||
flex-direction: row-reverse;
|
||||
}
|
||||
#converse-login-panel {
|
||||
.converse-form {
|
||||
padding: 3em 2em 3em;
|
||||
}
|
||||
}
|
||||
.chatbox {
|
||||
width: calc(100% - 50px);
|
||||
.row {
|
||||
.box-flyout {
|
||||
left: 50px;
|
||||
bottom: 0;
|
||||
height: var(--fullpage-chat-height);
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#conversejs.converse-mobile,
|
||||
#conversejs.converse-overlayed,
|
||||
#conversejs.converse-fullscreen {
|
||||
.chatbox {
|
||||
.box-flyout {
|
||||
.chatbox-navback {
|
||||
margin: auto 0;
|
||||
margin-right: 1em;
|
||||
display: flex;
|
||||
.fa-arrow-left {
|
||||
&:before {
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,545 +0,0 @@
|
||||
#conversejs.converse-embedded,
|
||||
#conversejs {
|
||||
.badge--muc {
|
||||
background-color: var(--groupchats-header-color);
|
||||
}
|
||||
|
||||
.add-chatroom {
|
||||
input[type="submit"],
|
||||
input[type="button"] {
|
||||
margin: 0.3em 0;
|
||||
}
|
||||
}
|
||||
|
||||
#room-details-modal {
|
||||
.features-list {
|
||||
margin-left: 1em;
|
||||
}
|
||||
}
|
||||
|
||||
.chatroom-features {
|
||||
width: 100%;
|
||||
.features-list {
|
||||
padding-top: 0;
|
||||
.feature {
|
||||
width: 100%;
|
||||
margin-right: 0.5em;
|
||||
padding-right: 0;
|
||||
font-size: 1em;
|
||||
cursor: help;
|
||||
.fa {
|
||||
margin-right: 0.5em;
|
||||
color: var(--text-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.chat-head-chatroom {
|
||||
color: var(--chatroom-head-color);
|
||||
background-color: var(--chatroom-head-bg-color);
|
||||
border-bottom: var(--chatroom-head-border-bottom);
|
||||
|
||||
.chat-head__desc {
|
||||
color: var(--chatroom-head-color);
|
||||
display: var(--chatroom-head-description-display);
|
||||
a {
|
||||
color: var(--chatroom-head-description-link-color);
|
||||
}
|
||||
&:hover {
|
||||
button {
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.chatbox-title {
|
||||
.btn--transparent {
|
||||
i {
|
||||
color: var(--chatroom-head-color);
|
||||
}
|
||||
}
|
||||
.chatbox-title__text--bookmarked {
|
||||
margin-left: 0.5em;
|
||||
color: var(--chatroom-head-color);
|
||||
}
|
||||
}
|
||||
|
||||
.chatbox-title__buttons {
|
||||
background-color: var(--chatroom-head-bg-color);
|
||||
}
|
||||
|
||||
a, a:visited, a:hover, a:not([href]):not([tabindex]) {
|
||||
&.chatbox-btn {
|
||||
&.fa {
|
||||
color: var(--chat-head-text-color);
|
||||
&.button-on:before {
|
||||
color: var(--chatroom-head-button-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.chatbox-btn {
|
||||
&.button-on:before {
|
||||
color: var(--chatroom-head-button-color);
|
||||
}
|
||||
}
|
||||
.chatbox-title__text {
|
||||
display: var(--heading-display);
|
||||
font-weight: var(--chatroom-head-title-font-weight);
|
||||
margin: auto 0;
|
||||
padding-right: var(--chatroom-head-title-padding-right);
|
||||
white-space: nowrap;
|
||||
.chatroom-jid {
|
||||
font-size: var(--font-size-small);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.empty-history-feedback {
|
||||
position: relative;
|
||||
span {
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
position: absolute;
|
||||
margin-top: 50%;
|
||||
}
|
||||
}
|
||||
|
||||
.chatroom {
|
||||
width: var(--chatroom-width);
|
||||
@media screen and (max-height: $mobile-landscape-height){
|
||||
width: var(--mobile-chat-width);
|
||||
}
|
||||
@media screen and (max-width: $mobile-portrait-length) {
|
||||
width: var(--mobile-chat-width);
|
||||
}
|
||||
|
||||
.box-flyout {
|
||||
overflow-y: hidden;
|
||||
background-color: var(--chatroom-head-bg-color);
|
||||
|
||||
width: 100%;
|
||||
@media screen and (max-height: $mobile-landscape-height) {
|
||||
height: var(--mobile-chat-height);
|
||||
width: var(--mobile-chat-width);
|
||||
height: var(--fullpage-chat-height);
|
||||
}
|
||||
@media screen and (max-width: $mobile-portrait-length) {
|
||||
height: var(--mobile-chat-height);
|
||||
width: var(--mobile-chat-width);
|
||||
height: var(--fullpage-chat-height);
|
||||
}
|
||||
.chatroom-body {
|
||||
flex-direction: row;
|
||||
flex-flow: nowrap;
|
||||
background-color: white;
|
||||
border-top: 0;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
|
||||
.row {
|
||||
flex-direction: row;
|
||||
}
|
||||
.chat-topic {
|
||||
font-weight: bold;
|
||||
color: var(--chatroom-head-bg-color);
|
||||
}
|
||||
.chat-info {
|
||||
color: var(--chat-info-color);
|
||||
line-height: normal;
|
||||
&.badge {
|
||||
color: var(--chat-head-text-color);
|
||||
}
|
||||
&.chat-msg--retracted {
|
||||
color: var(--subdued-color);
|
||||
}
|
||||
}
|
||||
.disconnect-container {
|
||||
margin: 1em;
|
||||
width: 100%;
|
||||
h3.disconnect-msg {
|
||||
padding-bottom: 1em;
|
||||
}
|
||||
}
|
||||
.chat-area {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex: 0 1 100%;
|
||||
justify-content: flex-end;
|
||||
min-width: 25%;
|
||||
word-wrap: break-word;
|
||||
.new-msgs-indicator {
|
||||
background-color: var(--chatroom-head-bg-color);
|
||||
}
|
||||
.chat-content {
|
||||
height: 100%;
|
||||
}
|
||||
.chat-content__help {
|
||||
border-top: 1px solid var(--chatroom-head-bg-color);
|
||||
.close-chat-help {
|
||||
svg {
|
||||
fill: var(--chatroom-head-bg-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.occupants {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
overflow-x: hidden;
|
||||
overflow-y: hidden;
|
||||
vertical-align: top;
|
||||
background-color: var(--occupants-background-color);
|
||||
border-left: var(--occupants-border-left);
|
||||
padding: 0.5em;
|
||||
max-width: 75%;
|
||||
min-width: 20%;
|
||||
flex: 0 0 25%;
|
||||
|
||||
.occupants-header {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
.hide-occupants {
|
||||
align-self: flex-end;
|
||||
cursor: pointer;
|
||||
font-size: var(--font-size-small);
|
||||
}
|
||||
}
|
||||
|
||||
.occupants-header--title {
|
||||
margin-top: 0.5em;
|
||||
margin-bottom: 0.5em;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.fa-user-plus {
|
||||
margin-right: 0.25em;
|
||||
}
|
||||
|
||||
.occupants-heading {
|
||||
font-family: var(--heading-font);
|
||||
color: var(--groupchats-header-color-dark);
|
||||
padding-left: 0;
|
||||
margin-right: 1em;
|
||||
}
|
||||
.suggestion-box{
|
||||
ul {
|
||||
padding: 0;
|
||||
li {
|
||||
padding: 0.5em;
|
||||
}
|
||||
}
|
||||
}
|
||||
ul {
|
||||
padding: 0;
|
||||
margin-bottom: 0.5em;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
list-style: none;
|
||||
|
||||
&.occupant-list {
|
||||
overflow-y: auto;
|
||||
flex-basis: 0;
|
||||
flex-grow: 1;
|
||||
}
|
||||
li {
|
||||
cursor: default;
|
||||
display: block;
|
||||
font-size: var(--font-size-small);
|
||||
overflow: hidden;
|
||||
padding: 0.25em 0.25em 0.25em 0;
|
||||
text-overflow: ellipsis;
|
||||
.fa {
|
||||
margin-right: 0.5em;
|
||||
}
|
||||
&.feature {
|
||||
font-size: var(--font-size-tiny);
|
||||
}
|
||||
&.occupant {
|
||||
cursor: pointer;
|
||||
|
||||
.occupant-nick-badge {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
flex-wrap: wrap;
|
||||
|
||||
.occupant-badges {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
flex-wrap: wrap;
|
||||
flex-direction: row;
|
||||
|
||||
span {
|
||||
margin-right: 0.25rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
div.row.no-gutters {
|
||||
flex-wrap: nowrap;
|
||||
min-height: 1.5em;
|
||||
}
|
||||
.badge {
|
||||
margin-bottom: 0.125rem;
|
||||
}
|
||||
|
||||
.occupant-status {
|
||||
display: inline-block;
|
||||
margin: 0 0.5em 0.125em 0;
|
||||
width: 0.5em;
|
||||
height: 0.5em;
|
||||
|
||||
&.occupant-online,
|
||||
&.occupant-chat {
|
||||
background-color: #1A9707;
|
||||
}
|
||||
&.occupant-dnd {
|
||||
background-color: red;
|
||||
}
|
||||
&.occupant-away {
|
||||
background-color: darkorange;
|
||||
}
|
||||
&.occupant-xa {
|
||||
background-color: orange;
|
||||
}
|
||||
&.occupant-offline {
|
||||
background-color: darkgrey;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.chatroom-form-container {
|
||||
background-color: white;
|
||||
border: 0;
|
||||
color: var(--text-color);
|
||||
font-size: var(--font-size);
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
overflow-y: auto;
|
||||
|
||||
.validation-message {
|
||||
font-size: 90%;
|
||||
color: var(--error-color);
|
||||
}
|
||||
input[type=button],
|
||||
input[type=submit] {
|
||||
margin: 0 0.5em;
|
||||
}
|
||||
.button-primary {
|
||||
background-color: var(--chatroom-head-button-color);
|
||||
}
|
||||
}
|
||||
|
||||
.chatroom-form {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
padding: 2em;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.muc-bottom-panel {
|
||||
height: 3em;
|
||||
padding: 0.5em;
|
||||
text-align: center;
|
||||
font-size: var(--font-size-small);
|
||||
background-color: var(--chatroom-head-bg-color);
|
||||
color: white;
|
||||
|
||||
&.muc-bottom-panel--nickname {
|
||||
padding: 0;
|
||||
height: 16em;
|
||||
|
||||
.chatroom-form-container {
|
||||
.chatroom-form {
|
||||
padding-top: 2em;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.sendXMPPMessage {
|
||||
.suggestion-box__results--above {
|
||||
bottom: 4.5em;
|
||||
}
|
||||
.chat-textarea, input {
|
||||
&:active, &:focus{
|
||||
outline-color: var(--chatroom-head-bg-color);
|
||||
}
|
||||
&.correcting {
|
||||
background-color: var(--chatroom-correcting-color);
|
||||
}
|
||||
}
|
||||
.chat-textarea {
|
||||
border-bottom-right-radius: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.room-invite {
|
||||
.invited-contact {
|
||||
margin: -1px 0 0 -1px;
|
||||
width: 100%;
|
||||
border: 1px solid #999;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ******************* Overlay styles *************************** */
|
||||
|
||||
#conversejs.converse-overlayed {
|
||||
.chatbox {
|
||||
&.chatroom {
|
||||
min-width: var(--chatroom-width) !important;
|
||||
width: var(--chatroom-width);
|
||||
.box-flyout {
|
||||
min-width: var(--chatroom-width) !important;
|
||||
width: var(--chatroom-width);
|
||||
}
|
||||
.chatbox-title__text {
|
||||
@include make-col(7);
|
||||
}
|
||||
.chatbox-title__buttons {
|
||||
@include make-col(5);
|
||||
}
|
||||
|
||||
.chat-head__desc {
|
||||
font-size: 80%;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
.chatroom-body {
|
||||
.occupants {
|
||||
.occupants-heading {
|
||||
padding: 0;
|
||||
}
|
||||
.occupant-list {
|
||||
border-bottom: none;
|
||||
}
|
||||
ul {
|
||||
.occupant {
|
||||
.occupant-nick-badge {
|
||||
.occupant-badges {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
.occupant-status {
|
||||
margin-top: 6px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.chat-area {
|
||||
min-width: var(--overlayed-chat-width);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#conversejs.converse-embedded,
|
||||
#conversejs.converse-fullscreen,
|
||||
#conversejs.converse-mobile {
|
||||
|
||||
.chatroom {
|
||||
.box-flyout {
|
||||
width: 100%;
|
||||
|
||||
.chatroom-body {
|
||||
.chat-area {
|
||||
&.full {
|
||||
.new-msgs-indicator {
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
.occupants {
|
||||
padding: var(--occupants-padding);
|
||||
.occupants-heading {
|
||||
font-size: var(--font-size-large);
|
||||
}
|
||||
ul {
|
||||
&.occupant-list {
|
||||
li {
|
||||
font-size: var(--font-size-small);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.room-invite {
|
||||
span {
|
||||
.invited-contact {
|
||||
margin: 0 0 0.5em -1px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#conversejs.converse-embedded {
|
||||
.chatroom {
|
||||
margin: 0;
|
||||
width: 100%;
|
||||
.box-flyout {
|
||||
.occupants-heading {
|
||||
font-size: 120%;
|
||||
}
|
||||
.chat-content {
|
||||
.chat-message {
|
||||
margin: 0.5em;
|
||||
font-size: 120%;
|
||||
}
|
||||
}
|
||||
.sendXMPPMessage {
|
||||
.chat-textarea {
|
||||
padding: 0.5em;
|
||||
font-size: 110%;
|
||||
}
|
||||
}
|
||||
.chatroom-body {
|
||||
height: 100%;
|
||||
.chatroom-form-container {
|
||||
height: 100%;
|
||||
position: relative;
|
||||
}
|
||||
}
|
||||
.occupants {
|
||||
.occupant-list {
|
||||
padding-left: 0.3em;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@include media-breakpoint-down(sm) {
|
||||
#conversejs.converse-mobile,
|
||||
#conversejs.converse-overlayed,
|
||||
#conversejs.converse-fullscreen {
|
||||
.chatbox {
|
||||
.box-flyout {
|
||||
.chat-head-chatroom {
|
||||
.chatbox-navback {
|
||||
margin-right: 0 !important;
|
||||
.fa-arrow-left {
|
||||
&:before {
|
||||
color: var(--chatroom-head-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
#conversejs {
|
||||
.chat-head-headline {
|
||||
background-color: var(--headline-head-color);
|
||||
}
|
||||
|
||||
.chatbox.headlines {
|
||||
.chat-head {
|
||||
&.chat-head-chatbox {
|
||||
background-color: var(--headline-head-color);
|
||||
}
|
||||
}
|
||||
.chat-body {
|
||||
background-color: var(--headline-head-color);
|
||||
border-radius: var(--chatbox-border-radius);
|
||||
.chat-message {
|
||||
color: var(--headline-message-color);
|
||||
}
|
||||
}
|
||||
.chat-content {
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#conversejs.converse-fullscreen {
|
||||
.chatbox.headlines {
|
||||
.box-flyout {
|
||||
background-color: var(--headline-head-color);
|
||||
}
|
||||
.chat-head {
|
||||
&.chat-head-chatbox {
|
||||
background-color: var(--headline-head-color);
|
||||
}
|
||||
}
|
||||
.flyout {
|
||||
border: var(--flyout-padding) solid var(--headline-head-color);
|
||||
border-top: 0.8em solid var(--headline-head-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,90 +0,0 @@
|
||||
#conversejs.converse-overlayed {
|
||||
#minimized-chats {
|
||||
order: 100;
|
||||
|
||||
width: var(--minimized-chats-width);
|
||||
margin-bottom: 0;
|
||||
border-top-left-radius: var(--chatbox-border-radius);
|
||||
border-top-right-radius: var(--chatbox-border-radius);
|
||||
color: var(--inverse-link-color);
|
||||
margin-right: var(--chat-gutter);
|
||||
padding: 0;
|
||||
|
||||
.badge {
|
||||
bottom: 8px;
|
||||
border: 1px solid var(--overlayed-badge-color);
|
||||
}
|
||||
|
||||
#toggle-minimized-chats {
|
||||
border-top-left-radius: var(--chatbox-border-radius);
|
||||
border-top-right-radius: var(--chatbox-border-radius);
|
||||
background-color: var(--link-color);
|
||||
padding: 1em 0 0 0;
|
||||
text-align: center;
|
||||
color: white;
|
||||
white-space: nowrap;
|
||||
overflow-y: hidden;
|
||||
text-overflow: ellipsis;
|
||||
display: block;
|
||||
height: 45px;
|
||||
width: 9em;
|
||||
}
|
||||
|
||||
a.restore-chat {
|
||||
cursor: pointer;
|
||||
padding: 1px 0 1px 5px;
|
||||
color: var(--chat-head-text-color);
|
||||
line-height: 15px;
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
&:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
|
||||
a.restore-chat:visited {
|
||||
color: var(--chat-head-text-color);
|
||||
}
|
||||
|
||||
.minimized-chats-flyout {
|
||||
flex-direction: column-reverse;
|
||||
bottom: 45px;
|
||||
width: var(--minimized-chats-width);
|
||||
|
||||
.chat-head {
|
||||
min-height: 0;
|
||||
padding: 0.3em;
|
||||
border-radius: var(--chatbox-border-radius);
|
||||
height: 35px;
|
||||
margin-bottom: 0.2em;
|
||||
width: 100%;
|
||||
max-width: 9em;
|
||||
flex-wrap: nowrap;
|
||||
}
|
||||
&.minimized {
|
||||
height: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.unread-message-count {
|
||||
font-weight: bold;
|
||||
background-color: white;
|
||||
border: 1px solid;
|
||||
text-shadow: 1px 1px 0 var(--text-shadow-color);
|
||||
color: var(--warning-color);
|
||||
border-radius: 5px;
|
||||
padding: 2px 4px;
|
||||
font-size: 16px;
|
||||
text-align: center;
|
||||
position: absolute;
|
||||
right: 116px;
|
||||
bottom: 10px;
|
||||
}
|
||||
.unread-message-count-hidden,
|
||||
.chat-head-message-count-hidden {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,185 +0,0 @@
|
||||
#conversejs #converse-roster {
|
||||
text-align: left;
|
||||
width: 100%;
|
||||
position: relative;
|
||||
margin: 0;
|
||||
height: var(--roster-height);
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
// XXX: FIXME
|
||||
height: calc(100% - 70px);
|
||||
|
||||
/* Custom addition for CSP */
|
||||
#online-count {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.search-xmpp {
|
||||
ul {
|
||||
li.chat-info {
|
||||
padding-left: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.roster-filter-form {
|
||||
width: 100%;
|
||||
|
||||
.button-group {
|
||||
padding: 0.2em;
|
||||
}
|
||||
|
||||
span {
|
||||
padding: 0.3em;
|
||||
cursor: pointer;
|
||||
min-width: 25px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.roster-filter {
|
||||
width: 100%;
|
||||
margin: 0.2em;
|
||||
font-size: calc(var(--font-size) - 2px);
|
||||
}
|
||||
.state-type {
|
||||
font-size: calc(var(--font-size) - 2px);
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.roster-contacts {
|
||||
padding: 0;
|
||||
margin: 0 0 0.2em 0;
|
||||
height: 100%;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
|
||||
.roster-group {
|
||||
border: none;
|
||||
color: var(--text-color);
|
||||
font-weight: normal;
|
||||
text-shadow: 0 1px 0 var(--text-shadow-color);
|
||||
margin: 0.75em 0 0.75em 0;
|
||||
|
||||
.group-toggle {
|
||||
font-family: var(--heading-font);
|
||||
display: block;
|
||||
width: 100%;
|
||||
padding-top: 0;
|
||||
padding-bottom: 0.3rem;
|
||||
}
|
||||
|
||||
.group-toggle, .group-toggle .fa {
|
||||
color: var(--chat-head-color-dark) !important;
|
||||
&:hover {
|
||||
color: var(--chat-head-color-darker) !important;
|
||||
}
|
||||
}
|
||||
|
||||
.current-xmpp-contact {
|
||||
margin: 0.25em 0;
|
||||
|
||||
.chat-status {
|
||||
vertical-align: middle;
|
||||
font-size: 0.6em;
|
||||
margin-right: 0;
|
||||
margin-left: -0.7em;
|
||||
margin-bottom: -1.5em;
|
||||
border-radius: 50%;
|
||||
border: 2px solid var(--occupants-background-color);
|
||||
}
|
||||
.chat-status--offline {
|
||||
margin-right: 0.8em;
|
||||
}
|
||||
.chat-status--online {
|
||||
color: var(--chat-status-online);
|
||||
}
|
||||
.chat-status--busy {
|
||||
color: var(--chat-status-busy);
|
||||
}
|
||||
.chat-status--away {
|
||||
color: var(--chat-status-away);
|
||||
}
|
||||
.chat-status--offline {
|
||||
display: none;
|
||||
}
|
||||
.far.fa-circle,
|
||||
.fa-times-circle {
|
||||
color: var(--subdued-color);
|
||||
}
|
||||
}
|
||||
|
||||
li {
|
||||
&.requesting-xmpp-contact {
|
||||
a {
|
||||
line-height: var(--line-height);
|
||||
}
|
||||
.req-contact-name {
|
||||
padding: 0 0.2em 0 0;
|
||||
}
|
||||
}
|
||||
|
||||
.open-chat {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
&.unread-msgs {
|
||||
font-weight: bold;
|
||||
.contact-name {
|
||||
width: 70%;
|
||||
}
|
||||
}
|
||||
|
||||
.msgs-indicator {
|
||||
color: white;
|
||||
background-color: var(--chat-head-color);
|
||||
opacity: 1;
|
||||
border-radius: 10%;
|
||||
padding: 0.2em 0.4em;
|
||||
font-size: var(--font-size-small);
|
||||
}
|
||||
|
||||
.contact-name {
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
max-width: 85%;
|
||||
float: none;
|
||||
height: 100%;
|
||||
&.unread-msgs {
|
||||
max-width: 60%;
|
||||
}
|
||||
&.contact-name--offline {
|
||||
margin-left: 0.7em;
|
||||
}
|
||||
}
|
||||
}
|
||||
&.odd {
|
||||
background-color: #DCEAC5;
|
||||
/* Make this difference */
|
||||
}
|
||||
a, span {
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
.span {
|
||||
display: inline-block;
|
||||
}
|
||||
.decline-xmpp-request {
|
||||
margin-left: 5px;
|
||||
}
|
||||
&:hover {
|
||||
background-color: var(controlbox-pane-bg-hover-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
span {
|
||||
&.pending-contact-name {
|
||||
line-height: var(--line-height);
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,257 +0,0 @@
|
||||
$mobile_landscape_height: 450px !default;
|
||||
$mobile_portrait_length: 480px !default;
|
||||
|
||||
#conversejs, #conversejs-bg, .converse-fullscreen {
|
||||
--subdued-color: #A8ABA1;
|
||||
|
||||
--green: #3AA569;
|
||||
--redder-orange: #E77051;
|
||||
--orange: #E7A151;
|
||||
--light-blue: #578EA9;
|
||||
--lighter-blue: #85B47B;
|
||||
|
||||
--chat-status-online: var(--green);
|
||||
--chat-status-busy: var(--redder-orange);
|
||||
--chat-status-away: var(--orange);
|
||||
|
||||
--brand-heading-color: #387592; // $blue
|
||||
|
||||
--completion-light-color: #FFB9A7; // $lightest-red
|
||||
--completion-normal-color: var(--redder-orange);
|
||||
--completion-dark-color: #D24E2B; // $dark-red
|
||||
|
||||
--link-color: var(--light-blue);
|
||||
--link-hover-color: #345566;
|
||||
--link-color-lighten-10-percent: #79a5ba; // lighten($light-blue, 10%)
|
||||
--dark-link-color: #206485; // $dark-blue
|
||||
--global-background-color: #397491; // dark blue
|
||||
|
||||
--inverse-link-color: white;
|
||||
--text-shadow-color: #FAFAFA;
|
||||
--text-color: #666;
|
||||
--controlbox-text-color: #666;
|
||||
--text-color-lighten-15-percent: #8c8c8c; // lighten(#666, 15%)
|
||||
--message-text-color: #555;
|
||||
--message-receipt-color: var(--green);
|
||||
--save-button-color: var(--green);
|
||||
|
||||
--message-avatar-width: 36px;
|
||||
--message-avatar-height: 36px;
|
||||
|
||||
--chat-textarea-color: #666;
|
||||
--chat-textarea-background-color: white;
|
||||
--chat-textarea-height: 60px;
|
||||
|
||||
--send-button-height: 27px;
|
||||
--send-button-margin: 3px;
|
||||
|
||||
--inline-action-margin: 0.75em;
|
||||
|
||||
--roster-height: 194px;
|
||||
|
||||
--flyout-padding: 0.5em;
|
||||
|
||||
--chat-correcting-color: var(--chat-head-color-lighten-50-percent);
|
||||
--chat-head-color-dark: #1E9652;
|
||||
--chat-head-color-darker: #0E763B;
|
||||
--chat-head-color-lighten-50-percent: #e7f7ee; // lighten($green, 50%)
|
||||
--chat-head-color: var(--green);
|
||||
--chat-head-text-color: white;
|
||||
--chat-toolbar-btn-color: var(--green);
|
||||
--chat-toolbar-btn-disabled-color: gray;
|
||||
|
||||
--chat-content-background-color: white;
|
||||
|
||||
--chat-info-color: var(--chatroom-head-bg-color);
|
||||
|
||||
--highlight-color: #DCF9F6;
|
||||
--highlight-color-darker: #B0E8E2;
|
||||
|
||||
--primary-color: var(--light-blue);
|
||||
--primary-color-dark: #397491;
|
||||
|
||||
--secondary-color: #818479; // gray
|
||||
--secondary-color-dark: #585B51;
|
||||
|
||||
--warning-color: var(--orange);
|
||||
--warning-color-dark: #D2842B;
|
||||
|
||||
--danger-color: #D24E2B; // dark-red
|
||||
--danger-color-dark: #A93415; // darker red
|
||||
|
||||
--light-background-color: #FCFDFD;
|
||||
|
||||
--error-color: #D24E2B; // dark-red
|
||||
--info-color: #1E9652; // $dark-green
|
||||
|
||||
--button-border-radius: 5px;
|
||||
--chatbox-border-radius: 4px;
|
||||
|
||||
|
||||
--groupchats-header-color: var(--chatroom-head-bg-color);
|
||||
--groupchats-header-color-dark: var(--chatroom-head-bg-color-dark);
|
||||
|
||||
--controlbox-width: 250px;
|
||||
--controlbox-head-color: var(--light-blue);
|
||||
--controlbox-heading-color: inherit;
|
||||
--controlbox-heading-font-weight: bold;
|
||||
--controlbox-heading-top-margin: 0.75em;
|
||||
--controlbox-pane-background-color: white;
|
||||
--controlbox-pane-bg-hover-color: #eff4f7;
|
||||
--panel-divider-color: #e7e7e7;
|
||||
|
||||
--chat-gutter: 0.5em;
|
||||
--minimized-chats-width: 130px;
|
||||
|
||||
--mobile-chat-width: 100%;
|
||||
--mobile-chat-height: 400px;
|
||||
|
||||
// TODO: figure out a way to concatenate custom properties with strings.
|
||||
// --font-path: "webfonts/icomoon/fonts/";
|
||||
|
||||
--normal-font: "Helvetica", "Arial", sans-serif;
|
||||
--heading-font: 'Muli', normal;
|
||||
--branding-font: 'Baumans', cursive;
|
||||
--heading-display: block;
|
||||
--heading-color: white;
|
||||
|
||||
--chatroom-badge-color: var(--chatroom-head-bg-color);
|
||||
--chatroom-badge-hover-color: var(--chatroom-head-bg-color-dark);
|
||||
--chatroom-correcting-color: #fadfd7; // lighten($red, 30%)
|
||||
--chatroom-head-bg-color-dark: #D24E2B; // $red
|
||||
--chatroom-head-bg-color: var(--redder-orange);
|
||||
--chatroom-head-border-bottom: 0px;
|
||||
--chatroom-head-button-color: var(--chatroom-head-bg-color);
|
||||
--chatroom-head-color: white;
|
||||
--chatroom-head-description-display: block;
|
||||
--chatroom-head-description-link-color: white;
|
||||
--chatroom-head-title-font-weight: normal;
|
||||
--chatroom-head-title-padding-right: 0px;
|
||||
--chatroom-width: 500px;
|
||||
--muc-toolbar-btn-color: var(--redder-orange);
|
||||
--muc-toolbar-btn-disabled-color: gray;
|
||||
|
||||
--headline-head-color: var(--orange);
|
||||
--headline-message-color: #D2842B;
|
||||
|
||||
--chatbox-button-size: 14px;
|
||||
--fullpage-chatbox-button-size: 16px;
|
||||
|
||||
--font-size-tiny: 10px;
|
||||
--font-size-small: 12px;
|
||||
--font-size: 14px;
|
||||
--font-size-large: 16px;
|
||||
--font-size-huge: 20px;
|
||||
|
||||
--message-font-size: var(--font-size);
|
||||
--separator-text-color: var(--message-text-color);
|
||||
--chat-separator-border-bottom: 2px solid var(--chat-head-color);
|
||||
--chatroom-separator-border-bottom: 2px solid var(--chatroom-head-bg-color);
|
||||
|
||||
--chatbox-message-input-border-top: 4px solid var(--chat-head-color);
|
||||
--chatroom-message-input-border-top: 4px solid var(--chatroom-head-bg-color);
|
||||
|
||||
--line-height-small: 14px;
|
||||
--line-height: 16px;
|
||||
--line-height-large: 20px;
|
||||
--line-height-huge: 27px;
|
||||
|
||||
--occupants-padding: 1em;
|
||||
--occupants-background-color: white;
|
||||
--occupants-border-left: 0.2143rem solid var(--panel-divider-color);
|
||||
--occupants-border-bottom: 1px solid lightgrey;
|
||||
|
||||
--embedded-emoji-picker-height: 300px;
|
||||
|
||||
--avatar-border-radius: 10%;
|
||||
--avatar-border: 1px solid lightgrey;
|
||||
--avatar-background-color: white;
|
||||
|
||||
--fullpage-chat-height: calc(var(--vh, 1vh) * 100);
|
||||
--fullpage-chat-width: 100%;
|
||||
--fullpage-emoji-picker-height: 300px;
|
||||
--fullpage-max-chat-textarea-height: 15em;
|
||||
|
||||
--overlayed-chat-head-height: 55px;
|
||||
--overlayed-chat-height: 450px;
|
||||
--overlayed-chat-width: 300px;
|
||||
--overlayed-chatbox-hover-height: 1em;
|
||||
--overlayed-emoji-picker-height: 200px;
|
||||
--overlayed-max-chat-textarea-height: 200px;
|
||||
--overlayed-badge-color: #818479; // $gray-color
|
||||
|
||||
--list-toggle-color: #818479; // $gray-color
|
||||
--list-toggle-hover-color: #585B51; // $dark-gray-color
|
||||
--list-toggle-font-weight: normal;
|
||||
--list-item-hover-color: rgba(0, 0, 0, 0.035);
|
||||
--list-item-action-color: #e3eef3; // lighten($lightest-blue, 25%)
|
||||
--list-item-link-color: inherit;
|
||||
--list-item-link-hover-color: var(--dark-link-color);
|
||||
--list-item-open-color: var(--controlbox-head-color);
|
||||
--list-item-open-hover-color: var(--controlbox-head-color);
|
||||
--list-dot-circle-color: #f6dec1; // lighten($orange, 25%)
|
||||
}
|
||||
|
||||
#conversejs.theme-concord {
|
||||
--avatar-border-radius: 10%;
|
||||
--avatar-border: 0px;
|
||||
--avatar-background-color: none;
|
||||
|
||||
--controlbox-pane-background-color: #333;
|
||||
--panel-divider-color: #333;
|
||||
--controlbox-pane-bg-hover-color: #464646;
|
||||
--controlbox-heading-color: #777;
|
||||
--controlbox-heading-font-weight: bold;
|
||||
--groupchats-header-color: var(--redder-orange);
|
||||
|
||||
--chat-textarea-background-color: #F6F6F6;
|
||||
--chat-correcting-color: #FFFFC0;
|
||||
--chat-head-text-color: #AAA;
|
||||
|
||||
--controlbox-text-color: #DDD;
|
||||
|
||||
--chat-info-color: var(--subdued-color);
|
||||
|
||||
--chatbox-border-radius: 0px;
|
||||
|
||||
--heading-display: inline;
|
||||
--heading-color: #9B4D;
|
||||
|
||||
--link-hover-color: var(--lighter-blue);
|
||||
|
||||
--chatroom-badge-color: var(--redder-orange);
|
||||
--chatroom-badge-hover-color: #D24E2B; // $red
|
||||
--chatroom-correcting-color: #FFFFC0;
|
||||
--chatroom-head-bg-color: white;
|
||||
--chatroom-head-border-bottom: 1px solid #EEE;
|
||||
--chatroom-head-button-color: #999;
|
||||
--chatroom-head-color: #7E7E7E;
|
||||
--chatroom-head-description-border-left: 1px solid #DDD;
|
||||
--chatroom-head-description-color: black;
|
||||
--chatroom-head-description-display: inline;
|
||||
--chatroom-head-description-link-color: #00b3f4;
|
||||
--chatroom-head-description-padding-left: 12px;
|
||||
--chatroom-head-title-font-weight: bold;
|
||||
--chatroom-head-title-padding-right: 12px;
|
||||
--muc-toolbar-btn-color: #7E7E7E;
|
||||
--muc-toolbar-btn-disabled-color: lightgray;
|
||||
|
||||
--occupants-background-color: #F3F3F3;
|
||||
--occupants-border-left: 0px;
|
||||
--occupants-border-bottom: 0px;
|
||||
|
||||
--separator-text-color: #AAA;
|
||||
--chat-separator-border-bottom: 1px solid #AAA;
|
||||
--chatroom-separator-border-bottom: 1px solid #AAA;
|
||||
|
||||
--chatroom-message-input-border-top: 1px solid #CCC;
|
||||
--chatbox-message-input-border-top: 1px solid #CCC;
|
||||
|
||||
--fullpage-chatbox-button-size: 24px;
|
||||
|
||||
--list-toggle-font-weight: bold;
|
||||
--list-item-link-color: #F1F1F1;
|
||||
--list-item-link-hover-color: #DDD;
|
||||
--list-item-open-color: #444;
|
||||
--list-item-open-hover-color: #444;
|
||||
}
|
101
sass/font-awesome.scss
vendored
@ -1,101 +0,0 @@
|
||||
@font-face {
|
||||
font-family: 'Baumans';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: local('Baumans Regular'), local('Baumans-Regular'), url('webfonts/baumans.ttf') format('truetype');
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Muli';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: local('Muli Regular'), local('Muli-Regular'), url('webfonts/muli.ttf') format('truetype');
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'ConverseFontAwesomeBrands';
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
src: url('webfonts/fa-brands-400.eot');
|
||||
src: url('webfonts/fa-brands-400.eot?#iefix') format('embedded-opentype'),
|
||||
url('webfonts/fa-brands-400.woff2') format('woff2'),
|
||||
url('webfonts/fa-brands-400.woff') format('woff'),
|
||||
url('webfonts/fa-brands-400.ttf') format('truetype'),
|
||||
url('webfonts/fa-brands-400.svg#fontawesome') format('svg');
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'ConverseFontAwesomeRegular';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: url('webfonts/fa-regular-400.eot');
|
||||
src: url('webfonts/fa-regular-400.eot?#iefix') format('embedded-opentype'),
|
||||
url('webfonts/fa-regular-400.woff2') format('woff2'),
|
||||
url('webfonts/fa-regular-400.woff') format('woff'),
|
||||
url('webfonts/fa-regular-400.ttf') format('truetype'),
|
||||
url('webfonts/fa-regular-400.svg#fontawesome') format('svg');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'ConverseFontAwesomeSolid';
|
||||
font-style: normal;
|
||||
font-weight: 900;
|
||||
src: url('webfonts/fa-solid-900.eot');
|
||||
src: url('webfonts/fa-solid-900.eot?#iefix') format('embedded-opentype'),
|
||||
url('webfonts/fa-solid-900.svg#fontawesome') format('svg'),
|
||||
url('webfonts/fa-solid-900.woff2') format('woff2'),
|
||||
url('webfonts/fa-solid-900.woff') format('woff'),
|
||||
url('webfonts/fa-solid-900.ttf') format('truetype');
|
||||
}
|
||||
|
||||
|
||||
@import "@fortawesome/fontawesome-free/scss/variables";
|
||||
@import "@fortawesome/fontawesome-free/scss/mixins";
|
||||
@import "@fortawesome/fontawesome-free/scss/core";
|
||||
@import "@fortawesome/fontawesome-free/scss/larger";
|
||||
@import "@fortawesome/fontawesome-free/scss/fixed-width";
|
||||
@import "@fortawesome/fontawesome-free/scss/list";
|
||||
@import "@fortawesome/fontawesome-free/scss/bordered-pulled";
|
||||
@import "@fortawesome/fontawesome-free/scss/animated";
|
||||
@import "@fortawesome/fontawesome-free/scss/rotated-flipped";
|
||||
@import "@fortawesome/fontawesome-free/scss/stacked";
|
||||
@import "@fortawesome/fontawesome-free/scss/icons";
|
||||
@import "@fortawesome/fontawesome-free/scss/screen-reader";
|
||||
|
||||
#conversejs, .converse-website {
|
||||
/* Apparent font-awesome bug? The circle has some kind of bottom margin */
|
||||
|
||||
converse-icon:before {
|
||||
content: none !important;
|
||||
}
|
||||
|
||||
.far:not(converse-icon) {
|
||||
font-family: 'ConverseFontAwesomeRegular' !important;
|
||||
font-weight: 400;
|
||||
}
|
||||
.fa:not(converse-icon),
|
||||
.fas:not(converse-icon) {
|
||||
font-family: 'ConverseFontAwesomeSolid' !important;
|
||||
font-weight: 900;
|
||||
}
|
||||
|
||||
.fab:not(converse-icon) {
|
||||
font-family: 'ConverseFontAwesomeBrands';
|
||||
}
|
||||
|
||||
.fa:not(converse-icon),
|
||||
.far:not(converse-icon),
|
||||
.fas:not(converse-icon),
|
||||
.fab:not(converse-icon) {
|
||||
display: inline-block;
|
||||
font-size: inherit;
|
||||
text-rendering: auto;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
.fa-info-circle {
|
||||
height: 1em;
|
||||
}
|
||||
}
|
Before Width: | Height: | Size: 699 KiB |
@ -1,803 +0,0 @@
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
<!--
|
||||
Font Awesome Free 5.13.0 by @fontawesome - https://fontawesome.com
|
||||
License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
|
||||
-->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">
|
||||
<metadata>
|
||||
Created by FontForge 20190801 at Mon Mar 23 10:45:51 2020
|
||||
By Robert Madole
|
||||
Copyright (c) Font Awesome
|
||||
</metadata>
|
||||
<defs>
|
||||
<font id="FontAwesome5Free-Regular" horiz-adv-x="512" >
|
||||
<font-face
|
||||
font-family="Font Awesome 5 Free Regular"
|
||||
font-weight="400"
|
||||
font-stretch="normal"
|
||||
units-per-em="512"
|
||||
panose-1="2 0 5 3 0 0 0 0 0 0"
|
||||
ascent="448"
|
||||
descent="-64"
|
||||
bbox="-0.0663408 -64.0662 640.01 448.1"
|
||||
underline-thickness="25"
|
||||
underline-position="-50"
|
||||
unicode-range="U+0020-F5C8"
|
||||
/>
|
||||
<missing-glyph />
|
||||
<glyph glyph-name="heart" unicode=""
|
||||
d="M458.4 383.7c75.2998 -63.4004 64.0996 -166.601 10.5996 -221.3l-175.4 -178.7c-10 -10.2002 -23.2998 -15.7998 -37.5996 -15.7998c-14.2002 0 -27.5996 5.69922 -37.5996 15.8994l-175.4 178.7c-53.5996 54.7002 -64.5996 157.9 10.5996 221.2
|
||||
c57.8008 48.7002 147.101 41.2998 202.4 -15c55.2998 56.2998 144.6 63.5996 202.4 15zM434.8 196.2c36.2002 36.8994 43.7998 107.7 -7.2998 150.8c-38.7002 32.5996 -98.7002 27.9004 -136.5 -10.5996l-35 -35.7002l-35 35.7002
|
||||
c-37.5996 38.2998 -97.5996 43.1992 -136.5 10.5c-51.2002 -43.1006 -43.7998 -113.5 -7.2998 -150.7l175.399 -178.7c2.40039 -2.40039 4.40039 -2.40039 6.80078 0z" />
|
||||
<glyph glyph-name="star" unicode="" horiz-adv-x="576"
|
||||
d="M528.1 276.5c26.2002 -3.7998 36.7002 -36.0996 17.7002 -54.5996l-105.7 -103l25 -145.5c4.5 -26.3008 -23.1992 -45.9004 -46.3994 -33.7002l-130.7 68.7002l-130.7 -68.7002c-23.2002 -12.2998 -50.8994 7.39941 -46.3994 33.7002l25 145.5l-105.7 103
|
||||
c-19 18.5 -8.5 50.7998 17.7002 54.5996l146.1 21.2998l65.2998 132.4c11.7998 23.8994 45.7002 23.5996 57.4004 0l65.2998 -132.4zM388.6 135.7l100.601 98l-139 20.2002l-62.2002 126l-62.2002 -126l-139 -20.2002l100.601 -98l-23.7002 -138.4l124.3 65.2998
|
||||
l124.3 -65.2998z" />
|
||||
<glyph glyph-name="user" unicode="" horiz-adv-x="448"
|
||||
d="M313.6 144c74.2002 0 134.4 -60.2002 134.4 -134.4v-25.5996c0 -26.5 -21.5 -48 -48 -48h-352c-26.5 0 -48 21.5 -48 48v25.5996c0 74.2002 60.2002 134.4 134.4 134.4c28.7998 0 42.5 -16 89.5996 -16s60.9004 16 89.5996 16zM400 -16v25.5996
|
||||
c0 47.6006 -38.7998 86.4004 -86.4004 86.4004c-14.6992 0 -37.8994 -16 -89.5996 -16c-51.2998 0 -75 16 -89.5996 16c-47.6006 0 -86.4004 -38.7998 -86.4004 -86.4004v-25.5996h352zM224 160c-79.5 0 -144 64.5 -144 144s64.5 144 144 144s144 -64.5 144 -144
|
||||
s-64.5 -144 -144 -144zM224 400c-52.9004 0 -96 -43.0996 -96 -96s43.0996 -96 96 -96s96 43.0996 96 96s-43.0996 96 -96 96z" />
|
||||
<glyph glyph-name="clock" unicode=""
|
||||
d="M256 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM256 -8c110.5 0 200 89.5 200 200s-89.5 200 -200 200s-200 -89.5 -200 -200s89.5 -200 200 -200zM317.8 96.4004l-84.8994 61.6992
|
||||
c-3.10059 2.30078 -4.90039 5.90039 -4.90039 9.7002v164.2c0 6.59961 5.40039 12 12 12h32c6.59961 0 12 -5.40039 12 -12v-141.7l66.7998 -48.5996c5.40039 -3.90039 6.5 -11.4004 2.60059 -16.7998l-18.8008 -25.9004c-3.89941 -5.2998 -11.3994 -6.5 -16.7998 -2.59961z
|
||||
" />
|
||||
<glyph glyph-name="list-alt" unicode=""
|
||||
d="M464 416c26.5098 0 48 -21.4902 48 -48v-352c0 -26.5098 -21.4902 -48 -48 -48h-416c-26.5098 0 -48 21.4902 -48 48v352c0 26.5098 21.4902 48 48 48h416zM458 16c3.31152 0 6 2.68848 6 6v340c0 3.31152 -2.68848 6 -6 6h-404c-3.31152 0 -6 -2.68848 -6 -6v-340
|
||||
c0 -3.31152 2.68848 -6 6 -6h404zM416 108v-24c0 -6.62695 -5.37305 -12 -12 -12h-200c-6.62695 0 -12 5.37305 -12 12v24c0 6.62695 5.37305 12 12 12h200c6.62695 0 12 -5.37305 12 -12zM416 204v-24c0 -6.62695 -5.37305 -12 -12 -12h-200c-6.62695 0 -12 5.37305 -12 12
|
||||
v24c0 6.62695 5.37305 12 12 12h200c6.62695 0 12 -5.37305 12 -12zM416 300v-24c0 -6.62695 -5.37305 -12 -12 -12h-200c-6.62695 0 -12 5.37305 -12 12v24c0 6.62695 5.37305 12 12 12h200c6.62695 0 12 -5.37305 12 -12zM164 288c0 -19.8818 -16.1182 -36 -36 -36
|
||||
s-36 16.1182 -36 36s16.1182 36 36 36s36 -16.1182 36 -36zM164 192c0 -19.8818 -16.1182 -36 -36 -36s-36 16.1182 -36 36s16.1182 36 36 36s36 -16.1182 36 -36zM164 96c0 -19.8818 -16.1182 -36 -36 -36s-36 16.1182 -36 36s16.1182 36 36 36s36 -16.1182 36 -36z" />
|
||||
<glyph glyph-name="flag" unicode=""
|
||||
d="M336.174 368c35.4668 0 73.0195 12.6914 108.922 28.1797c31.6406 13.6514 66.9043 -9.65723 66.9043 -44.1162v-239.919c0 -16.1953 -8.1543 -31.3057 -21.7129 -40.1631c-26.5762 -17.3643 -70.0693 -39.9814 -128.548 -39.9814c-68.6084 0 -112.781 32 -161.913 32
|
||||
c-56.5674 0 -89.957 -11.2803 -127.826 -28.5566v-83.4434c0 -8.83691 -7.16309 -16 -16 -16h-16c-8.83691 0 -16 7.16309 -16 16v406.438c-14.3428 8.2998 -24 23.7979 -24 41.5615c0 27.5693 23.2422 49.71 51.2012 47.8965
|
||||
c22.9658 -1.49023 41.8662 -19.4717 44.4805 -42.3379c0.177734 -1.52441 0.321289 -4.00781 0.321289 -5.54199c0 -4.30176 -1.10352 -11.1035 -2.46289 -15.1846c22.418 8.68555 49.4199 15.168 80.7207 15.168c68.6084 0 112.781 -32 161.913 -32zM464 112v240
|
||||
c-31.5059 -14.6338 -84.5547 -32 -127.826 -32c-59.9111 0 -101.968 32 -161.913 32c-41.4365 0 -80.4766 -16.5879 -102.261 -32v-232c31.4473 14.5967 84.4648 24 127.826 24c59.9111 0 101.968 -32 161.913 -32c41.4365 0 80.4775 16.5879 102.261 32z" />
|
||||
<glyph glyph-name="bookmark" unicode="" horiz-adv-x="384"
|
||||
d="M336 448c26.5098 0 48 -21.4902 48 -48v-464l-192 112l-192 -112v464c0 26.5098 21.4902 48 48 48h288zM336 19.5703v374.434c0 3.31348 -2.68555 5.99609 -6 5.99609h-276c-3.31152 0 -6 -2.68848 -6 -6v-374.43l144 84z" />
|
||||
<glyph glyph-name="image" unicode=""
|
||||
d="M464 384c26.5098 0 48 -21.4902 48 -48v-288c0 -26.5098 -21.4902 -48 -48 -48h-416c-26.5098 0 -48 21.4902 -48 48v288c0 26.5098 21.4902 48 48 48h416zM458 48c3.31152 0 6 2.68848 6 6v276c0 3.31152 -2.68848 6 -6 6h-404c-3.31152 0 -6 -2.68848 -6 -6v-276
|
||||
c0 -3.31152 2.68848 -6 6 -6h404zM128 296c22.0908 0 40 -17.9092 40 -40s-17.9092 -40 -40 -40s-40 17.9092 -40 40s17.9092 40 40 40zM96 96v48l39.5137 39.5146c4.6875 4.68652 12.2852 4.68652 16.9717 0l39.5146 -39.5146l119.514 119.515
|
||||
c4.6875 4.68652 12.2852 4.68652 16.9717 0l87.5146 -87.5146v-80h-320z" />
|
||||
<glyph glyph-name="edit" unicode="" horiz-adv-x="576"
|
||||
d="M402.3 103.1l32 32c5 5 13.7002 1.5 13.7002 -5.69922v-145.4c0 -26.5 -21.5 -48 -48 -48h-352c-26.5 0 -48 21.5 -48 48v352c0 26.5 21.5 48 48 48h273.5c7.09961 0 10.7002 -8.59961 5.7002 -13.7002l-32 -32c-1.5 -1.5 -3.5 -2.2998 -5.7002 -2.2998h-241.5v-352h352
|
||||
v113.5c0 2.09961 0.799805 4.09961 2.2998 5.59961zM558.9 304.9l-262.601 -262.601l-90.3994 -10c-26.2002 -2.89941 -48.5 19.2002 -45.6006 45.6006l10 90.3994l262.601 262.601c22.8994 22.8994 59.8994 22.8994 82.6992 0l43.2002 -43.2002
|
||||
c22.9004 -22.9004 22.9004 -60 0.100586 -82.7998zM460.1 274l-58.0996 58.0996l-185.8 -185.899l-7.2998 -65.2998l65.2998 7.2998zM524.9 353.7l-43.2002 43.2002c-4.10059 4.09961 -10.7998 4.09961 -14.7998 0l-30.9004 -30.9004l58.0996 -58.0996l30.9004 30.8994
|
||||
c4 4.2002 4 10.7998 -0.0996094 14.9004z" />
|
||||
<glyph glyph-name="times-circle" unicode=""
|
||||
d="M256 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM256 -8c110.5 0 200 89.5 200 200s-89.5 200 -200 200s-200 -89.5 -200 -200s89.5 -200 200 -200zM357.8 254.2l-62.2002 -62.2002l62.2002 -62.2002
|
||||
c4.7002 -4.7002 4.7002 -12.2998 0 -17l-22.5996 -22.5996c-4.7002 -4.7002 -12.2998 -4.7002 -17 0l-62.2002 62.2002l-62.2002 -62.2002c-4.7002 -4.7002 -12.2998 -4.7002 -17 0l-22.5996 22.5996c-4.7002 4.7002 -4.7002 12.2998 0 17l62.2002 62.2002l-62.2002 62.2002
|
||||
c-4.7002 4.7002 -4.7002 12.2998 0 17l22.5996 22.5996c4.7002 4.7002 12.2998 4.7002 17 0l62.2002 -62.2002l62.2002 62.2002c4.7002 4.7002 12.2998 4.7002 17 0l22.5996 -22.5996c4.7002 -4.7002 4.7002 -12.2998 0 -17z" />
|
||||
<glyph glyph-name="check-circle" unicode=""
|
||||
d="M256 440c136.967 0 248 -111.033 248 -248s-111.033 -248 -248 -248s-248 111.033 -248 248s111.033 248 248 248zM256 392c-110.549 0 -200 -89.4678 -200 -200c0 -110.549 89.4678 -200 200 -200c110.549 0 200 89.4678 200 200c0 110.549 -89.4678 200 -200 200z
|
||||
M396.204 261.733c4.66699 -4.70508 4.63672 -12.3037 -0.0673828 -16.9717l-172.589 -171.204c-4.70508 -4.66797 -12.3027 -4.63672 -16.9697 0.0683594l-90.7812 91.5156c-4.66797 4.70605 -4.63672 12.3047 0.0683594 16.9717l22.7188 22.5361
|
||||
c4.70508 4.66699 12.3027 4.63574 16.9697 -0.0693359l59.792 -60.2773l141.353 140.216c4.70508 4.66797 12.3027 4.6377 16.9697 -0.0673828z" />
|
||||
<glyph glyph-name="question-circle" unicode=""
|
||||
d="M256 440c136.957 0 248 -111.083 248 -248c0 -136.997 -111.043 -248 -248 -248s-248 111.003 -248 248c0 136.917 111.043 248 248 248zM256 -8c110.569 0 200 89.4697 200 200c0 110.529 -89.5088 200 -200 200c-110.528 0 -200 -89.5049 -200 -200
|
||||
c0 -110.569 89.4678 -200 200 -200zM363.244 247.2c0 -67.0518 -72.4209 -68.084 -72.4209 -92.8633v-6.33691c0 -6.62695 -5.37305 -12 -12 -12h-45.6475c-6.62695 0 -12 5.37305 -12 12v8.65918c0 35.7451 27.1006 50.0342 47.5791 61.5156
|
||||
c17.5615 9.84473 28.3242 16.541 28.3242 29.5791c0 17.2461 -21.999 28.6934 -39.7842 28.6934c-23.1885 0 -33.8936 -10.9775 -48.9424 -29.9697c-4.05664 -5.11914 -11.46 -6.07031 -16.666 -2.12402l-27.8232 21.0986
|
||||
c-5.10742 3.87207 -6.25098 11.0654 -2.64453 16.3633c23.627 34.6934 53.7217 54.1846 100.575 54.1846c49.0713 0 101.45 -38.3037 101.45 -88.7998zM298 80c0 -23.1592 -18.8408 -42 -42 -42s-42 18.8408 -42 42s18.8408 42 42 42s42 -18.8408 42 -42z" />
|
||||
<glyph glyph-name="eye" unicode="" horiz-adv-x="576"
|
||||
d="M288 304c0.0927734 0 0.244141 0.000976562 0.336914 0.000976562c61.6641 0 111.71 -50.0469 111.71 -111.711c0 -61.6631 -50.0459 -111.71 -111.71 -111.71s-111.71 50.0469 -111.71 111.71c0 8.71289 1.95898 22.5781 4.37305 30.9502
|
||||
c6.93066 -3.94141 19.0273 -7.18457 27 -7.24023c30.9121 0 56 25.0879 56 56c-0.0556641 7.97266 -3.29883 20.0693 -7.24023 27c8.42383 2.62207 22.4189 4.8623 31.2402 5zM572.52 206.6c1.9209 -3.79883 3.47949 -10.3379 3.47949 -14.5947
|
||||
s-1.55859 -10.7959 -3.47949 -14.5947c-54.1992 -105.771 -161.59 -177.41 -284.52 -177.41s-230.29 71.5898 -284.52 177.4c-1.9209 3.79883 -3.47949 10.3379 -3.47949 14.5947s1.55859 10.7959 3.47949 14.5947c54.1992 105.771 161.59 177.41 284.52 177.41
|
||||
s230.29 -71.5898 284.52 -177.4zM288 48c98.6602 0 189.1 55 237.93 144c-48.8398 89 -139.27 144 -237.93 144s-189.09 -55 -237.93 -144c48.8398 -89 139.279 -144 237.93 -144z" />
|
||||
<glyph glyph-name="eye-slash" unicode="" horiz-adv-x="640"
|
||||
d="M634 -23c3.31738 -2.65137 6.00977 -8.25098 6.00977 -12.498c0 -3.10449 -1.57715 -7.58984 -3.51953 -10.0117l-10 -12.4902c-2.65234 -3.31152 -8.24707 -6 -12.4902 -6c-3.09961 0 -7.58008 1.57227 -10 3.50977l-598 467.49
|
||||
c-3.31738 2.65137 -6.00977 8.25098 -6.00977 12.498c0 3.10449 1.57715 7.58984 3.51953 10.0117l10 12.4902c2.65234 3.31152 8.24707 6 12.4902 6c3.09961 0 7.58008 -1.57227 10 -3.50977zM296.79 301.53c6.33496 1.35059 16.7324 2.45801 23.21 2.46973
|
||||
c60.4805 0 109.36 -47.9102 111.58 -107.85zM343.21 82.46c-6.33496 -1.34375 -16.7334 -2.44629 -23.21 -2.45996c-60.4697 0 -109.35 47.9102 -111.58 107.84zM320 336c-19.8799 0 -39.2803 -2.7998 -58.2197 -7.09961l-46.4102 36.29
|
||||
c32.9199 11.8096 67.9297 18.8096 104.63 18.8096c122.93 0 230.29 -71.5898 284.57 -177.4c1.91992 -3.79883 3.47949 -10.3379 3.47949 -14.5947s-1.55957 -10.7959 -3.47949 -14.5947c-11.7197 -22.7598 -35.4189 -56.4092 -52.9004 -75.1104l-37.7402 29.5
|
||||
c14.333 15.0156 34.0449 41.9854 44 60.2002c-48.8398 89 -139.279 144 -237.93 144zM320 48c19.8896 0 39.2803 2.7998 58.2197 7.08984l46.4102 -36.2803c-32.9199 -11.7598 -67.9297 -18.8096 -104.63 -18.8096c-122.92 0 -230.28 71.5898 -284.51 177.4
|
||||
c-1.9209 3.79883 -3.47949 10.3379 -3.47949 14.5947s1.55859 10.7959 3.47949 14.5947c11.7168 22.7568 35.4111 56.4014 52.8896 75.1006l37.7402 -29.5c-14.3467 -15.0107 -34.0811 -41.9756 -44.0498 -60.1904c48.8496 -89 139.279 -144 237.93 -144z" />
|
||||
<glyph glyph-name="calendar-alt" unicode="" horiz-adv-x="448"
|
||||
d="M148 160h-40c-6.59961 0 -12 5.40039 -12 12v40c0 6.59961 5.40039 12 12 12h40c6.59961 0 12 -5.40039 12 -12v-40c0 -6.59961 -5.40039 -12 -12 -12zM256 172c0 -6.59961 -5.40039 -12 -12 -12h-40c-6.59961 0 -12 5.40039 -12 12v40c0 6.59961 5.40039 12 12 12h40
|
||||
c6.59961 0 12 -5.40039 12 -12v-40zM352 172c0 -6.59961 -5.40039 -12 -12 -12h-40c-6.59961 0 -12 5.40039 -12 12v40c0 6.59961 5.40039 12 12 12h40c6.59961 0 12 -5.40039 12 -12v-40zM256 76c0 -6.59961 -5.40039 -12 -12 -12h-40c-6.59961 0 -12 5.40039 -12 12v40
|
||||
c0 6.59961 5.40039 12 12 12h40c6.59961 0 12 -5.40039 12 -12v-40zM160 76c0 -6.59961 -5.40039 -12 -12 -12h-40c-6.59961 0 -12 5.40039 -12 12v40c0 6.59961 5.40039 12 12 12h40c6.59961 0 12 -5.40039 12 -12v-40zM352 76c0 -6.59961 -5.40039 -12 -12 -12h-40
|
||||
c-6.59961 0 -12 5.40039 -12 12v40c0 6.59961 5.40039 12 12 12h40c6.59961 0 12 -5.40039 12 -12v-40zM448 336v-352c0 -26.5 -21.5 -48 -48 -48h-352c-26.5 0 -48 21.5 -48 48v352c0 26.5 21.5 48 48 48h48v52c0 6.59961 5.40039 12 12 12h40
|
||||
c6.59961 0 12 -5.40039 12 -12v-52h128v52c0 6.59961 5.40039 12 12 12h40c6.59961 0 12 -5.40039 12 -12v-52h48c26.5 0 48 -21.5 48 -48zM400 -10v298h-352v-298c0 -3.2998 2.7002 -6 6 -6h340c3.2998 0 6 2.7002 6 6z" />
|
||||
<glyph glyph-name="comment" unicode=""
|
||||
d="M256 416c141.4 0 256 -93.0996 256 -208s-114.6 -208 -256 -208c-32.7998 0 -64 5.2002 -92.9004 14.2998c-29.0996 -20.5996 -77.5996 -46.2998 -139.1 -46.2998c-9.59961 0 -18.2998 5.7002 -22.0996 14.5c-3.80078 8.7998 -2 19 4.59961 26
|
||||
c0.5 0.400391 31.5 33.7998 46.4004 73.2002c-33 35.0996 -52.9004 78.7002 -52.9004 126.3c0 114.9 114.6 208 256 208zM256 48c114.7 0 208 71.7998 208 160s-93.2998 160 -208 160s-208 -71.7998 -208 -160c0 -42.2002 21.7002 -74.0996 39.7998 -93.4004
|
||||
l20.6006 -21.7998l-10.6006 -28.0996c-5.5 -14.5 -12.5996 -28.1006 -19.8994 -40.2002c23.5996 7.59961 43.1992 18.9004 57.5 29l19.5 13.7998l22.6992 -7.2002c25.3008 -8 51.7002 -12.0996 78.4004 -12.0996z" />
|
||||
<glyph glyph-name="folder" unicode=""
|
||||
d="M464 320c26.5098 0 48 -21.4902 48 -48v-224c0 -26.5098 -21.4902 -48 -48 -48h-416c-26.5098 0 -48 21.4902 -48 48v288c0 26.5098 21.4902 48 48 48h146.74c8.49023 0 16.6299 -3.37012 22.6299 -9.37012l54.6299 -54.6299h192zM464 48v224h-198.62
|
||||
c-8.49023 0 -16.6299 3.37012 -22.6299 9.37012l-54.6299 54.6299h-140.12v-288h416z" />
|
||||
<glyph glyph-name="folder-open" unicode="" horiz-adv-x="576"
|
||||
d="M527.9 224c37.6992 0 60.6992 -41.5 40.6992 -73.4004l-79.8994 -128c-8.7998 -14.0996 -24.2002 -22.5996 -40.7002 -22.5996h-400c-26.5 0 -48 21.5 -48 48v288c0 26.5 21.5 48 48 48h160l64 -64h160c26.5 0 48 -21.5 48 -48v-48h47.9004zM48 330v-233.4l62.9004 104.2
|
||||
c8.69922 14.4004 24.2998 23.2002 41.0996 23.2002h280v42c0 3.2998 -2.7002 6 -6 6h-173.9l-64 64h-134.1c-3.2998 0 -6 -2.7002 -6 -6zM448 48l80 128h-378.8l-77.2002 -128h376z" />
|
||||
<glyph glyph-name="chart-bar" unicode=""
|
||||
d="M396.8 96c-6.39941 0 -12.7998 6.40039 -12.7998 12.7998v230.4c0 6.39941 6.40039 12.7998 12.7998 12.7998h22.4004c6.39941 0 12.7998 -6.40039 12.7998 -12.7998v-230.4c0 -6.39941 -6.40039 -12.7998 -12.7998 -12.7998h-22.4004zM204.8 96
|
||||
c-6.39941 0 -12.7998 6.40039 -12.7998 12.7998v198.4c0 6.39941 6.40039 12.7998 12.7998 12.7998h22.4004c6.39941 0 12.7998 -6.40039 12.7998 -12.7998v-198.4c0 -6.39941 -6.40039 -12.7998 -12.7998 -12.7998h-22.4004zM300.8 96
|
||||
c-6.39941 0 -12.7998 6.40039 -12.7998 12.7998v134.4c0 6.39941 6.40039 12.7998 12.7998 12.7998h22.4004c6.39941 0 12.7998 -6.40039 12.7998 -12.7998v-134.4c0 -6.39941 -6.40039 -12.7998 -12.7998 -12.7998h-22.4004zM496 48c8.83984 0 16 -7.16016 16 -16v-16
|
||||
c0 -8.83984 -7.16016 -16 -16 -16h-464c-17.6699 0 -32 14.3301 -32 32v336c0 8.83984 7.16016 16 16 16h16c8.83984 0 16 -7.16016 16 -16v-320h448zM108.8 96c-6.39941 0 -12.7998 6.40039 -12.7998 12.7998v70.4004c0 6.39941 6.40039 12.7998 12.7998 12.7998h22.4004
|
||||
c6.39941 0 12.7998 -6.40039 12.7998 -12.7998v-70.4004c0 -6.39941 -6.40039 -12.7998 -12.7998 -12.7998h-22.4004z" />
|
||||
<glyph glyph-name="comments" unicode="" horiz-adv-x="576"
|
||||
d="M532 61.7998c15.2998 -30.7002 37.4004 -54.5 37.7998 -54.7998c6.2998 -6.7002 8 -16.5 4.40039 -25c-3.7002 -8.5 -12 -14 -21.2002 -14c-53.5996 0 -96.7002 20.2998 -125.2 38.7998c-19 -4.39941 -39 -6.7998 -59.7998 -6.7998
|
||||
c-86.2002 0 -159.9 40.4004 -191.3 97.7998c-9.7002 1.2002 -19.2002 2.7998 -28.4004 4.90039c-28.5 -18.6006 -71.7002 -38.7998 -125.2 -38.7998c-9.19922 0 -17.5996 5.5 -21.1992 14c-3.7002 8.5 -1.90039 18.2998 4.39941 25
|
||||
c0.400391 0.399414 22.4004 24.1992 37.7002 54.8994c-27.5 27.2002 -44 61.2002 -44 98.2002c0 88.4004 93.0996 160 208 160c86.2998 0 160.3 -40.5 191.8 -98.0996c99.7002 -11.8008 176.2 -77.9004 176.2 -157.9c0 -37.0996 -16.5 -71.0996 -44 -98.2002zM139.2 154.1
|
||||
l19.7998 -4.5c16 -3.69922 32.5 -5.59961 49 -5.59961c86.7002 0 160 51.2998 160 112s-73.2998 112 -160 112s-160 -51.2998 -160 -112c0 -28.7002 16.2002 -50.5996 29.7002 -64l24.7998 -24.5l-15.5 -31.0996c-2.59961 -5.10059 -5.2998 -10.1006 -8 -14.8008
|
||||
c14.5996 5.10059 29 12.3008 43.0996 21.4004zM498.3 96c13.5 13.4004 29.7002 35.2998 29.7002 64c0 49.2002 -48.2998 91.5 -112.7 106c0.299805 -3.2998 0.700195 -6.59961 0.700195 -10c0 -80.9004 -78 -147.5 -179.3 -158.3
|
||||
c29.0996 -29.6006 77.2998 -49.7002 131.3 -49.7002c16.5 0 33 1.90039 49 5.59961l19.9004 4.60059l17.0996 -11.1006c14.0996 -9.09961 28.5 -16.2998 43.0996 -21.3994c-2.69922 4.7002 -5.39941 9.7002 -8 14.7998l-15.5 31.0996z" />
|
||||
<glyph glyph-name="star-half" unicode="" horiz-adv-x="576"
|
||||
d="M288 62.7002v-54.2998l-130.7 -68.6006c-23.3994 -12.2998 -50.8994 7.60059 -46.3994 33.7002l25 145.5l-105.7 103c-19 18.5 -8.5 50.7998 17.7002 54.5996l146.1 21.2002l65.2998 132.4c5.90039 11.8994 17.2998 17.7998 28.7002 17.7998v-68.0996l-62.2002 -126
|
||||
l-139 -20.2002l100.601 -98l-23.7002 -138.4z" />
|
||||
<glyph glyph-name="lemon" unicode=""
|
||||
d="M484.112 420.111c28.1221 -28.123 35.9434 -68.0039 19.0215 -97.0547c-23.0576 -39.584 50.1436 -163.384 -82.3311 -295.86c-132.301 -132.298 -256.435 -59.3594 -295.857 -82.3291c-29.0459 -16.917 -68.9219 -9.11426 -97.0576 19.0205
|
||||
c-28.1221 28.1221 -35.9434 68.0029 -19.0215 97.0547c23.0566 39.5859 -50.1436 163.386 82.3301 295.86c132.308 132.309 256.407 59.3496 295.862 82.332c29.0498 16.9219 68.9307 9.09863 97.0537 -19.0234zM461.707 347.217
|
||||
c13.5166 23.2031 -27.7578 63.7314 -50.4883 50.4912c-66.6025 -38.7939 -165.646 45.5898 -286.081 -74.8457c-120.444 -120.445 -36.0449 -219.472 -74.8447 -286.08c-13.542 -23.2471 27.8145 -63.6953 50.4932 -50.4883
|
||||
c66.6006 38.7949 165.636 -45.5996 286.076 74.8428c120.444 120.445 36.0449 219.472 74.8447 286.08zM291.846 338.481c1.37012 -10.96 -6.40332 -20.957 -17.3643 -22.3271c-54.8467 -6.85547 -135.779 -87.7871 -142.636 -142.636
|
||||
c-1.37305 -10.9883 -11.3984 -18.7334 -22.3262 -17.3643c-10.9609 1.37012 -18.7344 11.3652 -17.3643 22.3262c9.16211 73.2852 104.167 168.215 177.364 177.364c10.9531 1.36816 20.9561 -6.40234 22.3262 -17.3633z" />
|
||||
<glyph glyph-name="credit-card" unicode="" horiz-adv-x="576"
|
||||
d="M527.9 416c26.5996 0 48.0996 -21.5 48.0996 -48v-352c0 -26.5 -21.5 -48 -48.0996 -48h-479.801c-26.5996 0 -48.0996 21.5 -48.0996 48v352c0 26.5 21.5 48 48.0996 48h479.801zM54.0996 368c-3.2998 0 -6 -2.7002 -6 -6v-42h479.801v42c0 3.2998 -2.7002 6 -6 6
|
||||
h-467.801zM521.9 16c3.2998 0 6 2.7002 6 6v170h-479.801v-170c0 -3.2998 2.7002 -6 6 -6h467.801zM192 116v-40c0 -6.59961 -5.40039 -12 -12 -12h-72c-6.59961 0 -12 5.40039 -12 12v40c0 6.59961 5.40039 12 12 12h72c6.59961 0 12 -5.40039 12 -12zM384 116v-40
|
||||
c0 -6.59961 -5.40039 -12 -12 -12h-136c-6.59961 0 -12 5.40039 -12 12v40c0 6.59961 5.40039 12 12 12h136c6.59961 0 12 -5.40039 12 -12z" />
|
||||
<glyph glyph-name="hdd" unicode="" horiz-adv-x="576"
|
||||
d="M567.403 212.358c5.59668 -8.04688 8.59668 -17.6113 8.59668 -27.4121v-136.946c0 -26.5098 -21.4902 -48 -48 -48h-480c-26.5098 0 -48 21.4902 -48 48v136.946c0 8.30957 3.85156 20.5898 8.59668 27.4121l105.08 151.053
|
||||
c7.90625 11.3652 25.5596 20.5889 39.4033 20.5889h0.000976562h269.838h0.000976562c13.8438 0 31.4971 -9.22363 39.4033 -20.5889zM153.081 336l-77.9131 -112h425.664l-77.9131 112h-269.838zM528 48v128h-480v-128h480zM496 112c0 -17.6729 -14.3271 -32 -32 -32
|
||||
s-32 14.3271 -32 32s14.3271 32 32 32s32 -14.3271 32 -32zM400 112c0 -17.6729 -14.3271 -32 -32 -32s-32 14.3271 -32 32s14.3271 32 32 32s32 -14.3271 32 -32z" />
|
||||
<glyph glyph-name="hand-point-right" unicode=""
|
||||
d="M428.8 310.4c45.0996 0 83.2002 -38.1016 83.2002 -83.2002c0 -45.6162 -37.7646 -83.2002 -83.2002 -83.2002h-35.6475c-1.41602 -6.36719 -4.96875 -16.252 -7.92969 -22.0645c2.50586 -22.0059 -3.50293 -44.9775 -15.9844 -62.791
|
||||
c-1.14062 -52.4863 -37.3984 -91.1445 -99.9404 -91.1445h-21.2988c-60.0635 0 -98.5117 40 -127.2 40h-2.67871c-5.74707 -4.95215 -13.5361 -8 -22.1201 -8h-64c-17.6729 0 -32 12.8936 -32 28.7998v230.4c0 15.9062 14.3271 28.7998 32 28.7998h64.001
|
||||
c8.58398 0 16.373 -3.04785 22.1201 -8h2.67871c6.96387 0 14.8623 6.19336 30.1816 23.6689l0.128906 0.148438l0.130859 0.145508c8.85645 9.93652 18.1162 20.8398 25.8506 33.2529c18.7051 30.2471 30.3936 78.7842 75.707 78.7842c56.9277 0 92 -35.2861 92 -83.2002
|
||||
v-0.0839844c0 -6.21777 -0.974609 -16.2148 -2.17578 -22.3154h86.1768zM428.8 192c18.9756 0 35.2002 16.2246 35.2002 35.2002c0 18.7002 -16.7754 35.2002 -35.2002 35.2002h-158.399c0 17.3242 26.3994 35.1992 26.3994 70.3994c0 26.4004 -20.625 35.2002 -44 35.2002
|
||||
c-8.79395 0 -20.4443 -32.7119 -34.9258 -56.0996c-9.07422 -14.5752 -19.5244 -27.2256 -30.7988 -39.875c-16.1094 -18.374 -33.8359 -36.6328 -59.0752 -39.5967v-176.753c42.79 -3.7627 74.5088 -39.6758 120 -39.6758h21.2988
|
||||
c40.5244 0 57.124 22.1973 50.6006 61.3252c14.6113 8.00098 24.1514 33.9785 12.9248 53.625c19.3652 18.2246 17.7871 46.3809 4.9502 61.0498h91.0254zM88 64c0 13.2549 -10.7451 24 -24 24s-24 -10.7451 -24 -24s10.7451 -24 24 -24s24 10.7451 24 24z" />
|
||||
<glyph glyph-name="hand-point-left" unicode=""
|
||||
d="M0 227.2c0 45.0986 38.1006 83.2002 83.2002 83.2002h86.1758c-1.3623 6.91016 -2.17578 14.374 -2.17578 22.3994c0 47.9141 35.0723 83.2002 92 83.2002c45.3135 0 57.002 -48.5371 75.7061 -78.7852c7.73438 -12.4121 16.9951 -23.3154 25.8506 -33.2529
|
||||
l0.130859 -0.145508l0.128906 -0.148438c15.3213 -17.4746 23.2197 -23.668 30.1836 -23.668h2.67871c5.74707 4.95215 13.5361 8 22.1201 8h64c17.6729 0 32 -12.8936 32 -28.7998v-230.4c0 -15.9062 -14.3271 -28.7998 -32 -28.7998h-64
|
||||
c-8.58398 0 -16.373 3.04785 -22.1201 8h-2.67871c-28.6885 0 -67.1367 -40 -127.2 -40h-21.2988c-62.542 0 -98.8008 38.6582 -99.9404 91.1445c-12.4814 17.8135 -18.4922 40.7852 -15.9844 62.791c-2.96094 5.8125 -6.51367 15.6973 -7.92969 22.0645h-35.6465
|
||||
c-45.4355 0 -83.2002 37.584 -83.2002 83.2002zM48 227.2c0 -18.9756 16.2246 -35.2002 35.2002 -35.2002h91.0244c-12.8369 -14.6689 -14.415 -42.8252 4.9502 -61.0498c-11.2256 -19.6465 -1.68652 -45.624 12.9248 -53.625
|
||||
c-6.52246 -39.1279 10.0771 -61.3252 50.6016 -61.3252h21.2988c45.4912 0 77.21 35.9131 120 39.6768v176.752c-25.2393 2.96289 -42.9658 21.2227 -59.0752 39.5967c-11.2744 12.6494 -21.7246 25.2998 -30.7988 39.875
|
||||
c-14.4814 23.3877 -26.1318 56.0996 -34.9258 56.0996c-23.375 0 -44 -8.7998 -44 -35.2002c0 -35.2002 26.3994 -53.0752 26.3994 -70.3994h-158.399c-18.4248 0 -35.2002 -16.5 -35.2002 -35.2002zM448 88c-13.2549 0 -24 -10.7451 -24 -24s10.7451 -24 24 -24
|
||||
s24 10.7451 24 24s-10.7451 24 -24 24z" />
|
||||
<glyph glyph-name="hand-point-up" unicode="" horiz-adv-x="448"
|
||||
d="M105.6 364.8c0 45.0996 38.1016 83.2002 83.2002 83.2002c45.6162 0 83.2002 -37.7646 83.2002 -83.2002v-35.6465c6.36719 -1.41602 16.252 -4.96875 22.0645 -7.92969c22.0059 2.50684 44.9775 -3.50293 62.791 -15.9844
|
||||
c52.4863 -1.14062 91.1445 -37.3984 91.1445 -99.9404v-21.2988c0 -60.0635 -40 -98.5117 -40 -127.2v-2.67871c4.95215 -5.74707 8 -13.5361 8 -22.1201v-64c0 -17.6729 -12.8936 -32 -28.7998 -32h-230.4c-15.9062 0 -28.7998 14.3271 -28.7998 32v64
|
||||
c0 8.58398 3.04785 16.373 8 22.1201v2.67871c0 6.96387 -6.19336 14.8623 -23.6689 30.1816l-0.148438 0.128906l-0.145508 0.130859c-9.93652 8.85645 -20.8398 18.1162 -33.2529 25.8506c-30.2471 18.7051 -78.7842 30.3936 -78.7842 75.707
|
||||
c0 56.9277 35.2861 92 83.2002 92h0.0839844c6.21777 0 16.2148 -0.974609 22.3154 -2.17578v86.1768zM224 364.8c0 18.9756 -16.2246 35.2002 -35.2002 35.2002c-18.7002 0 -35.2002 -16.7754 -35.2002 -35.2002v-158.399c-17.3242 0 -35.1992 26.3994 -70.3994 26.3994
|
||||
c-26.4004 0 -35.2002 -20.625 -35.2002 -44c0 -8.79395 32.7119 -20.4443 56.0996 -34.9258c14.5752 -9.07422 27.2256 -19.5244 39.875 -30.7988c18.374 -16.1094 36.6328 -33.8359 39.5967 -59.0752h176.753c3.7627 42.79 39.6758 74.5088 39.6758 120v21.2988
|
||||
c0 40.5244 -22.1973 57.124 -61.3252 50.6006c-8.00098 14.6113 -33.9785 24.1514 -53.625 12.9248c-18.2246 19.3652 -46.3809 17.7871 -61.0498 4.9502v91.0254zM352 24c-13.2549 0 -24 -10.7451 -24 -24s10.7451 -24 24 -24s24 10.7451 24 24s-10.7451 24 -24 24z" />
|
||||
<glyph glyph-name="hand-point-down" unicode="" horiz-adv-x="448"
|
||||
d="M188.8 -64c-45.0986 0 -83.2002 38.1006 -83.2002 83.2002v86.1758c-6.91016 -1.3623 -14.374 -2.17578 -22.3994 -2.17578c-47.9141 0 -83.2002 35.0723 -83.2002 92c0 45.3135 48.5371 57.002 78.7852 75.707c12.4121 7.73438 23.3154 16.9951 33.2529 25.8506
|
||||
l0.145508 0.130859l0.148438 0.128906c17.4746 15.3213 23.668 23.2197 23.668 30.1836v2.67871c-4.95215 5.74707 -8 13.5361 -8 22.1201v64c0 17.6729 12.8936 32 28.7998 32h230.4c15.9062 0 28.7998 -14.3271 28.7998 -32v-64.001
|
||||
c0 -8.58398 -3.04785 -16.373 -8 -22.1201v-2.67871c0 -28.6885 40 -67.1367 40 -127.2v-21.2988c0 -62.542 -38.6582 -98.8008 -91.1445 -99.9404c-17.8135 -12.4814 -40.7852 -18.4922 -62.791 -15.9844c-5.8125 -2.96094 -15.6973 -6.51367 -22.0645 -7.92969v-35.6465
|
||||
c0 -45.4355 -37.584 -83.2002 -83.2002 -83.2002zM188.8 -16c18.9756 0 35.2002 16.2246 35.2002 35.2002v91.0244c14.6689 -12.8369 42.8252 -14.415 61.0498 4.9502c19.6465 -11.2256 45.624 -1.68652 53.625 12.9248c39.1279 -6.52246 61.3252 10.0771 61.3252 50.6016
|
||||
v21.2988c0 45.4912 -35.9131 77.21 -39.6768 120h-176.752c-2.96289 -25.2393 -21.2227 -42.9658 -39.5967 -59.0752c-12.6494 -11.2744 -25.2998 -21.7246 -39.875 -30.7988c-23.3877 -14.4814 -56.0996 -26.1318 -56.0996 -34.9258c0 -23.375 8.7998 -44 35.2002 -44
|
||||
c35.2002 0 53.0752 26.3994 70.3994 26.3994v-158.399c0 -18.4248 16.5 -35.2002 35.2002 -35.2002zM328 384c0 -13.2549 10.7451 -24 24 -24s24 10.7451 24 24s-10.7451 24 -24 24s-24 -10.7451 -24 -24z" />
|
||||
<glyph glyph-name="copy" unicode="" horiz-adv-x="448"
|
||||
d="M433.941 382.059c7.75977 -7.75977 14.0586 -22.9658 14.0586 -33.9404v-268.118c0 -26.5098 -21.4902 -48 -48 -48h-80v-48c0 -26.5098 -21.4902 -48 -48 -48h-224c-26.5098 0 -48 21.4902 -48 48v320c0 26.5098 21.4902 48 48 48h80v48c0 26.5098 21.4902 48 48 48
|
||||
h172.118c10.9746 0 26.1807 -6.29883 33.9404 -14.0586zM266 -16c3.31152 0 6 2.68848 6 6v42h-96c-26.5098 0 -48 21.4902 -48 48v224h-74c-3.31152 0 -6 -2.68848 -6 -6v-308c0 -3.31152 2.68848 -6 6 -6h212zM394 80c3.31152 0 6 2.68848 6 6v202h-88
|
||||
c-13.2549 0 -24 10.7451 -24 24v88h-106c-3.31152 0 -6 -2.68848 -6 -6v-308c0 -3.31152 2.68848 -6 6 -6h212zM400 336v9.63184v0.000976562c0 1.37207 -0.787109 3.27246 -1.75684 4.24219l-48.3682 48.3682c-1.12598 1.125 -2.65234 1.75684 -4.24316 1.75684h-9.63184
|
||||
v-64h64z" />
|
||||
<glyph glyph-name="save" unicode="" horiz-adv-x="448"
|
||||
d="M433.941 318.059c7.75977 -7.75977 14.0586 -22.9658 14.0586 -33.9404v-268.118c0 -26.5098 -21.4902 -48 -48 -48h-352c-26.5098 0 -48 21.4902 -48 48v352c0 26.5098 21.4902 48 48 48h268.118c10.9746 0 26.1807 -6.29883 33.9404 -14.0586zM272 368h-128v-80h128v80
|
||||
zM394 16c3.31152 0 6 2.68848 6 6v259.632v0.000976562c0 1.37207 -0.787109 3.27246 -1.75684 4.24219l-78.2432 78.2432v-100.118c0 -13.2549 -10.7451 -24 -24 -24h-176c-13.2549 0 -24 10.7451 -24 24v104h-42c-3.31152 0 -6 -2.68848 -6 -6v-340
|
||||
c0 -3.31152 2.68848 -6 6 -6h340zM224 216c48.5234 0 88 -39.4766 88 -88s-39.4766 -88 -88 -88s-88 39.4766 -88 88s39.4766 88 88 88zM224 88c22.0557 0 40 17.9443 40 40s-17.9443 40 -40 40s-40 -17.9443 -40 -40s17.9443 -40 40 -40z" />
|
||||
<glyph glyph-name="square" unicode="" horiz-adv-x="448"
|
||||
d="M400 416c26.5 0 48 -21.5 48 -48v-352c0 -26.5 -21.5 -48 -48 -48h-352c-26.5 0 -48 21.5 -48 48v352c0 26.5 21.5 48 48 48h352zM394 16c3.2998 0 6 2.7002 6 6v340c0 3.2998 -2.7002 6 -6 6h-340c-3.2998 0 -6 -2.7002 -6 -6v-340c0 -3.2998 2.7002 -6 6 -6h340z" />
|
||||
<glyph glyph-name="envelope" unicode=""
|
||||
d="M464 384c26.5098 0 48 -21.4902 48 -48v-288c0 -26.5098 -21.4902 -48 -48 -48h-416c-26.5098 0 -48 21.4902 -48 48v288c0 26.5098 21.4902 48 48 48h416zM464 336h-416v-40.8047c22.4248 -18.2627 58.1797 -46.6602 134.587 -106.49
|
||||
c16.834 -13.2422 50.2051 -45.0762 73.4131 -44.7012c23.2119 -0.371094 56.5723 31.4541 73.4131 44.7012c76.4189 59.8389 112.165 88.2305 134.587 106.49v40.8047zM48 48h416v185.601c-22.915 -18.252 -55.4189 -43.8691 -104.947 -82.6523
|
||||
c-22.5439 -17.748 -60.3359 -55.1787 -103.053 -54.9473c-42.9277 -0.231445 -81.2051 37.75 -103.062 54.9551c-49.5293 38.7842 -82.0244 64.3945 -104.938 82.6455v-185.602z" />
|
||||
<glyph glyph-name="lightbulb" unicode="" horiz-adv-x="352"
|
||||
d="M176 368c8.83984 0 16 -7.16016 16 -16s-7.16016 -16 -16 -16c-35.2803 0 -64 -28.7002 -64 -64c0 -8.83984 -7.16016 -16 -16 -16s-16 7.16016 -16 16c0 52.9404 43.0596 96 96 96zM96.0596 -11.1699l-0.0400391 43.1797h159.961l-0.0507812 -43.1797
|
||||
c-0.00976562 -3.13965 -0.939453 -6.21973 -2.67969 -8.83984l-24.5098 -36.8398c-2.95996 -4.45996 -7.95996 -7.14062 -13.3203 -7.14062h-78.8496c-5.35059 0 -10.3506 2.68066 -13.3203 7.14062l-24.5098 36.8398c-1.75 2.62012 -2.68066 5.68945 -2.68066 8.83984z
|
||||
M176 448c97.2002 0 176 -78.7998 176 -176c0 -44.3701 -16.4502 -84.8496 -43.5498 -115.79c-16.6406 -18.9795 -42.7402 -58.79 -52.4199 -92.1602v-0.0498047h-48v0.0996094c0.00390625 4.04199 0.999023 10.4482 2.21973 14.3008
|
||||
c5.67969 17.9893 22.9902 64.8496 62.0996 109.46c20.4102 23.29 31.6504 53.1699 31.6504 84.1396c0 70.5801 -57.4199 128 -128 128c-68.2803 0 -128.15 -54.3604 -127.95 -128c0.0898438 -30.9902 11.0703 -60.71 31.6104 -84.1396
|
||||
c39.3496 -44.9004 56.5801 -91.8604 62.1699 -109.67c1.42969 -4.56055 2.13965 -9.30078 2.15039 -14.0703v-0.120117h-48v0.0595703c-9.68066 33.3604 -35.7803 73.1709 -52.4209 92.1602c-27.1094 30.9307 -43.5596 71.4102 -43.5596 115.78
|
||||
c0 93.0303 73.7197 176 176 176z" />
|
||||
<glyph glyph-name="bell" unicode="" horiz-adv-x="448"
|
||||
d="M439.39 85.71c6 -6.44043 8.66016 -14.1602 8.61035 -21.71c-0.0996094 -16.4004 -12.9805 -32 -32.0996 -32h-383.801c-19.1191 0 -31.9893 15.5996 -32.0996 32c-0.0498047 7.5498 2.61035 15.2598 8.61035 21.71c19.3193 20.7598 55.4697 51.9902 55.4697 154.29
|
||||
c0 77.7002 54.4795 139.9 127.939 155.16v20.8398c0 17.6699 14.3203 32 31.9805 32s31.9805 -14.3301 31.9805 -32v-20.8398c73.46 -15.2598 127.939 -77.46 127.939 -155.16c0 -102.3 36.1504 -133.53 55.4697 -154.29zM67.5303 80h312.939
|
||||
c-21.2197 27.96 -44.4199 74.3203 -44.5293 159.42c0 0.200195 0.0595703 0.379883 0.0595703 0.580078c0 61.8604 -50.1396 112 -112 112s-112 -50.1396 -112 -112c0 -0.200195 0.0595703 -0.379883 0.0595703 -0.580078
|
||||
c-0.109375 -85.0898 -23.3096 -131.45 -44.5293 -159.42zM224 -64c-35.3203 0 -63.9697 28.6504 -63.9697 64h127.939c0 -35.3496 -28.6494 -64 -63.9697 -64z" />
|
||||
<glyph glyph-name="hospital" unicode="" horiz-adv-x="448"
|
||||
d="M128 204v40c0 6.62695 5.37305 12 12 12h40c6.62695 0 12 -5.37305 12 -12v-40c0 -6.62695 -5.37305 -12 -12 -12h-40c-6.62695 0 -12 5.37305 -12 12zM268 192c-6.62695 0 -12 5.37305 -12 12v40c0 6.62695 5.37305 12 12 12h40c6.62695 0 12 -5.37305 12 -12v-40
|
||||
c0 -6.62695 -5.37305 -12 -12 -12h-40zM192 108c0 -6.62695 -5.37305 -12 -12 -12h-40c-6.62695 0 -12 5.37305 -12 12v40c0 6.62695 5.37305 12 12 12h40c6.62695 0 12 -5.37305 12 -12v-40zM268 96c-6.62695 0 -12 5.37305 -12 12v40c0 6.62695 5.37305 12 12 12h40
|
||||
c6.62695 0 12 -5.37305 12 -12v-40c0 -6.62695 -5.37305 -12 -12 -12h-40zM448 -28v-36h-448v36c0 6.62695 5.37305 12 12 12h19.5v378.965c0 11.6172 10.7451 21.0352 24 21.0352h88.5v40c0 13.2549 10.7451 24 24 24h112c13.2549 0 24 -10.7451 24 -24v-40h88.5
|
||||
c13.2549 0 24 -9.41797 24 -21.0352v-378.965h19.5c6.62695 0 12 -5.37305 12 -12zM79.5 -15h112.5v67c0 6.62695 5.37305 12 12 12h40c6.62695 0 12 -5.37305 12 -12v-67h112.5v351h-64.5v-24c0 -13.2549 -10.7451 -24 -24 -24h-112c-13.2549 0 -24 10.7451 -24 24v24
|
||||
h-64.5v-351zM266 384h-26v26c0 3.31152 -2.68848 6 -6 6h-20c-3.31152 0 -6 -2.68848 -6 -6v-26h-26c-3.31152 0 -6 -2.68848 -6 -6v-20c0 -3.31152 2.68848 -6 6 -6h26v-26c0 -3.31152 2.68848 -6 6 -6h20c3.31152 0 6 2.68848 6 6v26h26c3.31152 0 6 2.68848 6 6v20
|
||||
c0 3.31152 -2.68848 6 -6 6z" />
|
||||
<glyph glyph-name="plus-square" unicode="" horiz-adv-x="448"
|
||||
d="M352 208v-32c0 -6.59961 -5.40039 -12 -12 -12h-88v-88c0 -6.59961 -5.40039 -12 -12 -12h-32c-6.59961 0 -12 5.40039 -12 12v88h-88c-6.59961 0 -12 5.40039 -12 12v32c0 6.59961 5.40039 12 12 12h88v88c0 6.59961 5.40039 12 12 12h32c6.59961 0 12 -5.40039 12 -12
|
||||
v-88h88c6.59961 0 12 -5.40039 12 -12zM448 368v-352c0 -26.5 -21.5 -48 -48 -48h-352c-26.5 0 -48 21.5 -48 48v352c0 26.5 21.5 48 48 48h352c26.5 0 48 -21.5 48 -48zM400 22v340c0 3.2998 -2.7002 6 -6 6h-340c-3.2998 0 -6 -2.7002 -6 -6v-340
|
||||
c0 -3.2998 2.7002 -6 6 -6h340c3.2998 0 6 2.7002 6 6z" />
|
||||
<glyph glyph-name="circle" unicode=""
|
||||
d="M256 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM256 -8c110.5 0 200 89.5 200 200s-89.5 200 -200 200s-200 -89.5 -200 -200s89.5 -200 200 -200z" />
|
||||
<glyph glyph-name="smile" unicode="" horiz-adv-x="496"
|
||||
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8c110.3 0 200 89.7002 200 200s-89.7002 200 -200 200s-200 -89.7002 -200 -200s89.7002 -200 200 -200zM168 208c-17.7002 0 -32 14.2998 -32 32s14.2998 32 32 32
|
||||
s32 -14.2998 32 -32s-14.2998 -32 -32 -32zM328 208c-17.7002 0 -32 14.2998 -32 32s14.2998 32 32 32s32 -14.2998 32 -32s-14.2998 -32 -32 -32zM332 135.4c8.5 10.1992 23.7002 11.5 33.7998 3.09961c10.2002 -8.5 11.6006 -23.5996 3.10059 -33.7998
|
||||
c-30 -36 -74.1006 -56.6006 -120.9 -56.6006s-90.9004 20.6006 -120.9 56.6006c-8.39941 10.2002 -7.09961 25.2998 3.10059 33.7998c10.0996 8.40039 25.2998 7.09961 33.7998 -3.09961c20.7998 -25.1006 51.5 -39.4004 84 -39.4004s63.2002 14.4004 84 39.4004z" />
|
||||
<glyph glyph-name="frown" unicode="" horiz-adv-x="496"
|
||||
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8c110.3 0 200 89.7002 200 200s-89.7002 200 -200 200s-200 -89.7002 -200 -200s89.7002 -200 200 -200zM168 208c-17.7002 0 -32 14.2998 -32 32s14.2998 32 32 32
|
||||
s32 -14.2998 32 -32s-14.2998 -32 -32 -32zM328 272c17.7002 0 32 -14.2998 32 -32s-14.2998 -32 -32 -32s-32 14.2998 -32 32s14.2998 32 32 32zM248 144c40.2002 0 78 -17.7002 103.8 -48.5996c8.40039 -10.2002 7.10059 -25.3008 -3.09961 -33.8008
|
||||
c-10.7002 -8.7998 -25.7002 -6.59961 -33.7998 3.10059c-16.6006 20 -41 31.3994 -66.9004 31.3994s-50.2998 -11.5 -66.9004 -31.3994c-8.5 -10.2002 -23.5996 -11.5 -33.7998 -3.10059c-10.2002 8.5 -11.5996 23.6006 -3.09961 33.8008
|
||||
c25.7998 30.8994 63.5996 48.5996 103.8 48.5996z" />
|
||||
<glyph glyph-name="meh" unicode="" horiz-adv-x="496"
|
||||
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8c110.3 0 200 89.7002 200 200s-89.7002 200 -200 200s-200 -89.7002 -200 -200s89.7002 -200 200 -200zM168 208c-17.7002 0 -32 14.2998 -32 32s14.2998 32 32 32
|
||||
s32 -14.2998 32 -32s-14.2998 -32 -32 -32zM328 272c17.7002 0 32 -14.2998 32 -32s-14.2998 -32 -32 -32s-32 14.2998 -32 32s14.2998 32 32 32zM336 128c13.2002 0 24 -10.7998 24 -24s-10.7998 -24 -24 -24h-176c-13.2002 0 -24 10.7998 -24 24s10.7998 24 24 24h176z
|
||||
" />
|
||||
<glyph glyph-name="keyboard" unicode="" horiz-adv-x="576"
|
||||
d="M528 384c26.5098 0 48 -21.4902 48 -48v-288c0 -26.5098 -21.4902 -48 -48 -48h-480c-26.5098 0 -48 21.4902 -48 48v288c0 26.5098 21.4902 48 48 48h480zM536 48v288c0 4.41113 -3.58887 8 -8 8h-480c-4.41113 0 -8 -3.58887 -8 -8v-288c0 -4.41113 3.58887 -8 8 -8
|
||||
h480c4.41113 0 8 3.58887 8 8zM170 178c0 -6.62695 -5.37305 -12 -12 -12h-28c-6.62695 0 -12 5.37305 -12 12v28c0 6.62695 5.37305 12 12 12h28c6.62695 0 12 -5.37305 12 -12v-28zM266 178c0 -6.62695 -5.37305 -12 -12 -12h-28c-6.62695 0 -12 5.37305 -12 12v28
|
||||
c0 6.62695 5.37305 12 12 12h28c6.62695 0 12 -5.37305 12 -12v-28zM362 178c0 -6.62695 -5.37305 -12 -12 -12h-28c-6.62695 0 -12 5.37305 -12 12v28c0 6.62695 5.37305 12 12 12h28c6.62695 0 12 -5.37305 12 -12v-28zM458 178c0 -6.62695 -5.37305 -12 -12 -12h-28
|
||||
c-6.62695 0 -12 5.37305 -12 12v28c0 6.62695 5.37305 12 12 12h28c6.62695 0 12 -5.37305 12 -12v-28zM122 96c0 -6.62695 -5.37305 -12 -12 -12h-28c-6.62695 0 -12 5.37305 -12 12v28c0 6.62695 5.37305 12 12 12h28c6.62695 0 12 -5.37305 12 -12v-28zM506 96
|
||||
c0 -6.62695 -5.37305 -12 -12 -12h-28c-6.62695 0 -12 5.37305 -12 12v28c0 6.62695 5.37305 12 12 12h28c6.62695 0 12 -5.37305 12 -12v-28zM122 260c0 -6.62695 -5.37305 -12 -12 -12h-28c-6.62695 0 -12 5.37305 -12 12v28c0 6.62695 5.37305 12 12 12h28
|
||||
c6.62695 0 12 -5.37305 12 -12v-28zM218 260c0 -6.62695 -5.37305 -12 -12 -12h-28c-6.62695 0 -12 5.37305 -12 12v28c0 6.62695 5.37305 12 12 12h28c6.62695 0 12 -5.37305 12 -12v-28zM314 260c0 -6.62695 -5.37305 -12 -12 -12h-28c-6.62695 0 -12 5.37305 -12 12v28
|
||||
c0 6.62695 5.37305 12 12 12h28c6.62695 0 12 -5.37305 12 -12v-28zM410 260c0 -6.62695 -5.37305 -12 -12 -12h-28c-6.62695 0 -12 5.37305 -12 12v28c0 6.62695 5.37305 12 12 12h28c6.62695 0 12 -5.37305 12 -12v-28zM506 260c0 -6.62695 -5.37305 -12 -12 -12h-28
|
||||
c-6.62695 0 -12 5.37305 -12 12v28c0 6.62695 5.37305 12 12 12h28c6.62695 0 12 -5.37305 12 -12v-28zM408 102c0 -6.62695 -5.37305 -12 -12 -12h-216c-6.62695 0 -12 5.37305 -12 12v16c0 6.62695 5.37305 12 12 12h216c6.62695 0 12 -5.37305 12 -12v-16z" />
|
||||
<glyph glyph-name="calendar" unicode="" horiz-adv-x="448"
|
||||
d="M400 384c26.5 0 48 -21.5 48 -48v-352c0 -26.5 -21.5 -48 -48 -48h-352c-26.5 0 -48 21.5 -48 48v352c0 26.5 21.5 48 48 48h48v52c0 6.59961 5.40039 12 12 12h40c6.59961 0 12 -5.40039 12 -12v-52h128v52c0 6.59961 5.40039 12 12 12h40c6.59961 0 12 -5.40039 12 -12
|
||||
v-52h48zM394 -16c3.2998 0 6 2.7002 6 6v298h-352v-298c0 -3.2998 2.7002 -6 6 -6h340z" />
|
||||
<glyph glyph-name="play-circle" unicode=""
|
||||
d="M371.7 210c16.3994 -9.2002 16.3994 -32.9004 0 -42l-176 -101c-15.9004 -8.7998 -35.7002 2.59961 -35.7002 21v208c0 18.5 19.9004 29.7998 35.7002 21zM504 192c0 -137 -111 -248 -248 -248s-248 111 -248 248s111 248 248 248s248 -111 248 -248zM56 192
|
||||
c0 -110.5 89.5 -200 200 -200s200 89.5 200 200s-89.5 200 -200 200s-200 -89.5 -200 -200z" />
|
||||
<glyph glyph-name="minus-square" unicode="" horiz-adv-x="448"
|
||||
d="M108 164c-6.59961 0 -12 5.40039 -12 12v32c0 6.59961 5.40039 12 12 12h232c6.59961 0 12 -5.40039 12 -12v-32c0 -6.59961 -5.40039 -12 -12 -12h-232zM448 368v-352c0 -26.5 -21.5 -48 -48 -48h-352c-26.5 0 -48 21.5 -48 48v352c0 26.5 21.5 48 48 48h352
|
||||
c26.5 0 48 -21.5 48 -48zM400 22v340c0 3.2998 -2.7002 6 -6 6h-340c-3.2998 0 -6 -2.7002 -6 -6v-340c0 -3.2998 2.7002 -6 6 -6h340c3.2998 0 6 2.7002 6 6z" />
|
||||
<glyph glyph-name="check-square" unicode="" horiz-adv-x="448"
|
||||
d="M400 416c26.5098 0 48 -21.4902 48 -48v-352c0 -26.5098 -21.4902 -48 -48 -48h-352c-26.5098 0 -48 21.4902 -48 48v352c0 26.5098 21.4902 48 48 48h352zM400 16v352h-352v-352h352zM364.136 257.724l-172.589 -171.204
|
||||
c-4.70508 -4.66699 -12.3027 -4.63672 -16.9697 0.0683594l-90.7812 91.5156c-4.66699 4.70508 -4.63672 12.3037 0.0693359 16.9717l22.7188 22.5361c4.70508 4.66699 12.3027 4.63672 16.9697 -0.0693359l59.792 -60.2773l141.353 140.217
|
||||
c4.70508 4.66699 12.3027 4.63672 16.9697 -0.0683594l22.5361 -22.7178c4.66699 -4.70605 4.63672 -12.3047 -0.0683594 -16.9717z" />
|
||||
<glyph glyph-name="share-square" unicode="" horiz-adv-x="576"
|
||||
d="M561.938 289.94c18.75 -18.7402 18.75 -49.1406 0 -67.8809l-143.998 -144c-29.9727 -29.9727 -81.9404 -9.05273 -81.9404 33.9404v53.7998c-101.266 -7.83691 -99.625 -31.6406 -84.1104 -78.7598c14.2285 -43.0889 -33.4736 -79.248 -71.0195 -55.7402
|
||||
c-51.6924 32.3057 -84.8701 83.0635 -84.8701 144.76c0 39.3408 12.2197 72.7402 36.3301 99.3008c19.8398 21.8398 47.7402 38.4697 82.9102 49.4199c36.7295 11.4395 78.3096 16.1094 120.76 17.9893v57.1982c0 42.9355 51.9258 63.9541 81.9404 33.9404zM384 112l144 144
|
||||
l-144 144v-104.09c-110.86 -0.90332 -240 -10.5166 -240 -119.851c0 -52.1396 32.79 -85.6094 62.3096 -104.06c-39.8174 120.65 48.999 141.918 177.69 143.84v-103.84zM408.74 27.5068c6.14844 1.75684 15.5449 5.92383 20.9736 9.30273
|
||||
c7.97656 4.95215 18.2861 -0.825195 18.2861 -10.2139v-42.5957c0 -26.5098 -21.4902 -48 -48 -48h-352c-26.5098 0 -48 21.4902 -48 48v352c0 26.5098 21.4902 48 48 48h132c6.62695 0 12 -5.37305 12 -12v-4.48633c0 -4.91699 -2.9873 -9.36914 -7.56934 -11.1514
|
||||
c-13.7021 -5.33105 -26.3955 -11.5371 -38.0498 -18.585c-1.59668 -0.974609 -4.41016 -1.77051 -6.28027 -1.77734h-86.1006c-3.31152 0 -6 -2.68848 -6 -6v-340c0 -3.31152 2.68848 -6 6 -6h340c3.31152 0 6 2.68848 6 6v25.9658c0 5.37012 3.5791 10.0596 8.74023 11.541
|
||||
z" />
|
||||
<glyph glyph-name="compass" unicode="" horiz-adv-x="496"
|
||||
d="M347.94 318.14c16.6592 7.61035 33.8096 -9.54004 26.1992 -26.1992l-65.9697 -144.341c-2.73047 -5.97363 -9.7959 -13.0391 -15.7695 -15.7695l-144.341 -65.9697c-16.6592 -7.61035 -33.8096 9.5498 -26.1992 26.1992l65.9697 144.341
|
||||
c2.73047 5.97363 9.7959 13.0391 15.7695 15.7695zM270.58 169.42c12.4697 12.4697 12.4697 32.6904 0 45.1602s-32.6904 12.4697 -45.1602 0s-12.4697 -32.6904 0 -45.1602s32.6904 -12.4697 45.1602 0zM248 440c136.97 0 248 -111.03 248 -248s-111.03 -248 -248 -248
|
||||
s-248 111.03 -248 248s111.03 248 248 248zM248 -8c110.28 0 200 89.7197 200 200s-89.7197 200 -200 200s-200 -89.7197 -200 -200s89.7197 -200 200 -200z" />
|
||||
<glyph glyph-name="caret-square-down" unicode="" horiz-adv-x="448"
|
||||
d="M125.1 240h197.801c10.6992 0 16.0996 -13 8.5 -20.5l-98.9004 -98.2998c-4.7002 -4.7002 -12.2002 -4.7002 -16.9004 0l-98.8994 98.2998c-7.7002 7.5 -2.2998 20.5 8.39941 20.5zM448 368v-352c0 -26.5 -21.5 -48 -48 -48h-352c-26.5 0 -48 21.5 -48 48v352
|
||||
c0 26.5 21.5 48 48 48h352c26.5 0 48 -21.5 48 -48zM400 22v340c0 3.2998 -2.7002 6 -6 6h-340c-3.2998 0 -6 -2.7002 -6 -6v-340c0 -3.2998 2.7002 -6 6 -6h340c3.2998 0 6 2.7002 6 6z" />
|
||||
<glyph glyph-name="caret-square-up" unicode="" horiz-adv-x="448"
|
||||
d="M322.9 144h-197.801c-10.6992 0 -16.0996 13 -8.5 20.5l98.9004 98.2998c4.7002 4.7002 12.2002 4.7002 16.9004 0l98.8994 -98.2998c7.7002 -7.5 2.2998 -20.5 -8.39941 -20.5zM448 368v-352c0 -26.5 -21.5 -48 -48 -48h-352c-26.5 0 -48 21.5 -48 48v352
|
||||
c0 26.5 21.5 48 48 48h352c26.5 0 48 -21.5 48 -48zM400 22v340c0 3.2998 -2.7002 6 -6 6h-340c-3.2998 0 -6 -2.7002 -6 -6v-340c0 -3.2998 2.7002 -6 6 -6h340c3.2998 0 6 2.7002 6 6z" />
|
||||
<glyph glyph-name="caret-square-right" unicode="" horiz-adv-x="448"
|
||||
d="M176 93.0996v197.801c0 10.6992 13 16.0996 20.5 8.5l98.2998 -98.9004c4.7002 -4.7002 4.7002 -12.2002 0 -16.9004l-98.2998 -98.8994c-7.5 -7.7002 -20.5 -2.2998 -20.5 8.39941zM448 368v-352c0 -26.5 -21.5 -48 -48 -48h-352c-26.5 0 -48 21.5 -48 48v352
|
||||
c0 26.5 21.5 48 48 48h352c26.5 0 48 -21.5 48 -48zM400 22v340c0 3.2998 -2.7002 6 -6 6h-340c-3.2998 0 -6 -2.7002 -6 -6v-340c0 -3.2998 2.7002 -6 6 -6h340c3.2998 0 6 2.7002 6 6z" />
|
||||
<glyph glyph-name="file" unicode="" horiz-adv-x="384"
|
||||
d="M369.9 350.1c9 -9 14.0996 -21.2998 14.0996 -34v-332.1c0 -26.5 -21.5 -48 -48 -48h-288c-26.5 0 -48 21.5 -48 48v416c0 26.5 21.5 48 48 48.0996h204.1c12.7002 0 24.9004 -5.09961 33.9004 -14.0996zM332.1 320l-76.0996 76.0996v-76.0996h76.0996zM48 -16h288v288
|
||||
h-104c-13.2998 0 -24 10.7002 -24 24v104h-160v-416z" />
|
||||
<glyph glyph-name="file-alt" unicode="" horiz-adv-x="384"
|
||||
d="M288 200v-28c0 -6.59961 -5.40039 -12 -12 -12h-168c-6.59961 0 -12 5.40039 -12 12v28c0 6.59961 5.40039 12 12 12h168c6.59961 0 12 -5.40039 12 -12zM276 128c6.59961 0 12 -5.40039 12 -12v-28c0 -6.59961 -5.40039 -12 -12 -12h-168c-6.59961 0 -12 5.40039 -12 12
|
||||
v28c0 6.59961 5.40039 12 12 12h168zM384 316.1v-332.1c0 -26.5 -21.5 -48 -48 -48h-288c-26.5 0 -48 21.5 -48 48v416c0 26.5 21.5 48 48 48h204.1c12.7002 0 24.9004 -5.09961 33.9004 -14.0996l83.9004 -83.9004c9 -8.90039 14.0996 -21.2002 14.0996 -33.9004z
|
||||
M256 396.1v-76.0996h76.0996zM336 -16v288h-104c-13.2998 0 -24 10.7002 -24 24v104h-160v-416h288z" />
|
||||
<glyph glyph-name="thumbs-up" unicode=""
|
||||
d="M466.27 161.31c4.6748 -22.6465 0.864258 -44.5371 -8.98926 -62.9893c2.95898 -23.8682 -4.02148 -48.5654 -17.3398 -66.9902c-0.954102 -55.9072 -35.8232 -95.3301 -112.94 -95.3301c-7 0 -15 0.00976562 -22.2197 0.00976562
|
||||
c-102.742 0 -133.293 38.9395 -177.803 39.9404c-3.56934 -13.7764 -16.085 -23.9502 -30.9775 -23.9502h-64c-17.6729 0 -32 14.3271 -32 32v240c0 17.6729 14.3271 32 32 32h98.7598c19.1455 16.9531 46.0137 60.6533 68.7598 83.4004
|
||||
c13.667 13.667 10.1533 108.6 71.7607 108.6c57.5801 0 95.2695 -31.9355 95.2695 -104.73c0 -18.4092 -3.92969 -33.7295 -8.84961 -46.5391h36.4795c48.6025 0 85.8203 -41.5654 85.8203 -85.5801c0 -19.1504 -4.95996 -34.9902 -13.7305 -49.8408zM404.52 107.48
|
||||
c21.5811 20.3838 18.6992 51.0645 5.21094 65.6191c9.44922 0 22.3594 18.9102 22.2695 37.8105c-0.0898438 18.9102 -16.71 37.8203 -37.8203 37.8203h-103.989c0 37.8193 28.3594 55.3691 28.3594 94.5391c0 23.75 0 56.7305 -47.2695 56.7305
|
||||
c-18.9102 -18.9102 -9.45996 -66.1797 -37.8203 -94.54c-26.5596 -26.5703 -66.1797 -97.46 -94.54 -97.46h-10.9199v-186.17c53.6113 0 100.001 -37.8203 171.64 -37.8203h37.8203c35.5117 0 60.8203 17.1201 53.1201 65.9004
|
||||
c15.2002 8.16016 26.5 36.4395 13.9395 57.5703zM88 16c0 13.2549 -10.7451 24 -24 24s-24 -10.7451 -24 -24s10.7451 -24 24 -24s24 10.7451 24 24z" />
|
||||
<glyph glyph-name="thumbs-down" unicode=""
|
||||
d="M466.27 222.69c8.77051 -14.8506 13.7305 -30.6904 13.7305 -49.8408c0 -44.0146 -37.2178 -85.5801 -85.8203 -85.5801h-36.4795c4.91992 -12.8096 8.84961 -28.1299 8.84961 -46.5391c0 -72.7949 -37.6895 -104.73 -95.2695 -104.73
|
||||
c-61.6074 0 -58.0938 94.9326 -71.7607 108.6c-22.7461 22.7471 -49.6133 66.4473 -68.7598 83.4004h-7.05176c-5.5332 -9.56152 -15.8662 -16 -27.708 -16h-64c-17.6729 0 -32 14.3271 -32 32v240c0 17.6729 14.3271 32 32 32h64c8.11328 0 15.5146 -3.02539 21.1553 -8
|
||||
h10.8447c40.9971 0 73.1953 39.9902 176.78 39.9902c7.21973 0 15.2197 0.00976562 22.2197 0.00976562c77.1172 0 111.986 -39.4229 112.94 -95.3301c13.3184 -18.4248 20.2979 -43.1221 17.3398 -66.9902c9.85352 -18.4521 13.6641 -40.3428 8.98926 -62.9893zM64 152
|
||||
c13.2549 0 24 10.7451 24 24s-10.7451 24 -24 24s-24 -10.7451 -24 -24s10.7451 -24 24 -24zM394.18 135.27c21.1104 0 37.7305 18.9102 37.8203 37.8203c0.0898438 18.9004 -12.8203 37.8105 -22.2695 37.8105c13.4883 14.5547 16.3701 45.2354 -5.21094 65.6191
|
||||
c12.5605 21.1309 1.26074 49.4102 -13.9395 57.5703c7.7002 48.7803 -17.6084 65.9004 -53.1201 65.9004h-37.8203c-71.6387 0 -118.028 -37.8203 -171.64 -37.8203v-186.17h10.9199c28.3604 0 67.9805 -70.8896 94.54 -97.46
|
||||
c28.3604 -28.3604 18.9102 -75.6299 37.8203 -94.54c47.2695 0 47.2695 32.9805 47.2695 56.7305c0 39.1699 -28.3594 56.7197 -28.3594 94.5391h103.989z" />
|
||||
<glyph glyph-name="sun" unicode=""
|
||||
d="M494.2 226.1c11.2002 -7.59961 17.7998 -20.0996 17.8994 -33.6992c0 -13.4004 -6.69922 -26 -17.7998 -33.5l-59.7998 -40.5l13.7002 -71c2.5 -13.2002 -1.60059 -26.8008 -11.1006 -36.3008s-22.8994 -13.7998 -36.2998 -11.0996l-70.8994 13.7002l-40.4004 -59.9004
|
||||
c-7.5 -11.0996 -20.0996 -17.7998 -33.5 -17.7998s-26 6.7002 -33.5 17.9004l-40.4004 59.8994l-70.7998 -13.7002c-13.3994 -2.59961 -26.7998 1.60059 -36.2998 11.1006s-13.7002 23.0996 -11.0996 36.2998l13.6992 71l-59.7998 40.5
|
||||
c-11.0996 7.5 -17.7998 20 -17.7998 33.5s6.59961 26 17.7998 33.5996l59.7998 40.5l-13.6992 71c-2.60059 13.2002 1.59961 26.7002 11.0996 36.3008c9.5 9.59961 23 13.6992 36.2998 11.1992l70.7998 -13.6992l40.4004 59.8994c15.0996 22.2998 51.9004 22.2998 67 0
|
||||
l40.4004 -59.8994l70.8994 13.6992c13 2.60059 26.6006 -1.59961 36.2002 -11.0996c9.5 -9.59961 13.7002 -23.2002 11.0996 -36.4004l-13.6992 -71zM381.3 140.5l76.7998 52.0996l-76.7998 52l17.6006 91.1006l-91 -17.6006l-51.9004 76.9004l-51.7998 -76.7998
|
||||
l-91 17.5996l17.5996 -91.2002l-76.7998 -52l76.7998 -52l-17.5996 -91.1992l90.8994 17.5996l51.9004 -77l51.9004 76.9004l91 -17.6006zM256 296c57.2998 0 104 -46.7002 104 -104s-46.7002 -104 -104 -104s-104 46.7002 -104 104s46.7002 104 104 104zM256 136
|
||||
c30.9004 0 56 25.0996 56 56s-25.0996 56 -56 56s-56 -25.0996 -56 -56s25.0996 -56 56 -56z" />
|
||||
<glyph glyph-name="moon" unicode=""
|
||||
d="M279.135 -64c-141.424 0 -256 114.64 -256 256c0 141.425 114.641 256 256 256c13.0068 -0.00195312 33.9443 -1.91797 46.7354 -4.27734c44.0205 -8.13086 53.7666 -66.8691 15.0215 -88.9189c-41.374 -23.5439 -67.4336 -67.4121 -67.4336 -115.836
|
||||
c0 -83.5234 75.9238 -146.475 158.272 -130.792c43.6904 8.32129 74.5186 -42.5693 46.248 -77.4004c-47.8613 -58.9717 -120.088 -94.7754 -198.844 -94.7754zM279.135 400c-114.875 0 -208 -93.125 -208 -208s93.125 -208 208 -208
|
||||
c65.2314 0 123.439 30.0361 161.575 77.0244c-111.611 -21.2568 -215.252 64.0957 -215.252 177.943c0 67.5127 36.9326 126.392 91.6934 157.555c-12.3271 2.27637 -25.0312 3.47754 -38.0166 3.47754z" />
|
||||
<glyph glyph-name="caret-square-left" unicode="" horiz-adv-x="448"
|
||||
d="M272 290.9v-197.801c0 -10.6992 -13 -16.0996 -20.5 -8.5l-98.2998 98.9004c-4.7002 4.7002 -4.7002 12.2002 0 16.9004l98.2998 98.8994c7.5 7.7002 20.5 2.2998 20.5 -8.39941zM448 368v-352c0 -26.5 -21.5 -48 -48 -48h-352c-26.5 0 -48 21.5 -48 48v352
|
||||
c0 26.5 21.5 48 48 48h352c26.5 0 48 -21.5 48 -48zM400 22v340c0 3.2998 -2.7002 6 -6 6h-340c-3.2998 0 -6 -2.7002 -6 -6v-340c0 -3.2998 2.7002 -6 6 -6h340c3.2998 0 6 2.7002 6 6z" />
|
||||
<glyph glyph-name="dot-circle" unicode=""
|
||||
d="M256 392c-110.549 0 -200 -89.4678 -200 -200c0 -110.549 89.4678 -200 200 -200c110.549 0 200 89.4678 200 200c0 110.549 -89.4678 200 -200 200zM256 440c136.967 0 248 -111.033 248 -248s-111.033 -248 -248 -248s-248 111.033 -248 248s111.033 248 248 248z
|
||||
M256 272c44.1826 0 80 -35.8174 80 -80s-35.8174 -80 -80 -80s-80 35.8174 -80 80s35.8174 80 80 80z" />
|
||||
<glyph glyph-name="building" unicode="" horiz-adv-x="448"
|
||||
d="M128 300v40c0 6.59961 5.40039 12 12 12h40c6.59961 0 12 -5.40039 12 -12v-40c0 -6.59961 -5.40039 -12 -12 -12h-40c-6.59961 0 -12 5.40039 -12 12zM268 288c-6.59961 0 -12 5.40039 -12 12v40c0 6.59961 5.40039 12 12 12h40c6.59961 0 12 -5.40039 12 -12v-40
|
||||
c0 -6.59961 -5.40039 -12 -12 -12h-40zM140 192c-6.59961 0 -12 5.40039 -12 12v40c0 6.59961 5.40039 12 12 12h40c6.59961 0 12 -5.40039 12 -12v-40c0 -6.59961 -5.40039 -12 -12 -12h-40zM268 192c-6.59961 0 -12 5.40039 -12 12v40c0 6.59961 5.40039 12 12 12h40
|
||||
c6.59961 0 12 -5.40039 12 -12v-40c0 -6.59961 -5.40039 -12 -12 -12h-40zM192 108c0 -6.59961 -5.40039 -12 -12 -12h-40c-6.59961 0 -12 5.40039 -12 12v40c0 6.59961 5.40039 12 12 12h40c6.59961 0 12 -5.40039 12 -12v-40zM268 96c-6.59961 0 -12 5.40039 -12 12v40
|
||||
c0 6.59961 5.40039 12 12 12h40c6.59961 0 12 -5.40039 12 -12v-40c0 -6.59961 -5.40039 -12 -12 -12h-40zM448 -28v-36h-448v36c0 6.59961 5.40039 12 12 12h19.5v440c0 13.2998 10.7002 24 24 24h337c13.2998 0 24 -10.7002 24 -24v-440h19.5
|
||||
c6.59961 0 12 -5.40039 12 -12zM79.5 -15h112.5v67c0 6.59961 5.40039 12 12 12h40c6.59961 0 12 -5.40039 12 -12v-67h112.5v414l-288.5 1z" />
|
||||
<glyph glyph-name="file-pdf" unicode="" horiz-adv-x="384"
|
||||
d="M369.9 350.1c9 -9 14.0996 -21.2998 14.0996 -34v-332.1c0 -26.5 -21.5 -48 -48 -48h-288c-26.5 0 -48 21.5 -48 48v416c0 26.5 21.5 48 48 48.0996h204.1c12.7002 0 24.9004 -5.09961 33.9004 -14.0996zM332.1 320l-76.0996 76.0996v-76.0996h76.0996zM48 -16h288v288
|
||||
h-104c-13.2998 0 -24 10.7002 -24 24v104h-160v-416zM298.2 127.7c10.5 -10.5 8 -38.7002 -17.5 -38.7002c-14.7998 0 -36.9004 6.7998 -55.7998 17c-21.6006 -3.59961 -46 -12.7002 -68.4004 -20.0996c-50.0996 -86.4004 -79.4004 -47 -76.0996 -31.2002
|
||||
c4 20 31 35.8994 51 46.2002c10.5 18.3994 25.3994 50.5 35.3994 74.3994c-7.39941 28.6006 -11.3994 51 -7 67.1006c4.7998 17.6992 38.4004 20.2998 42.6006 -5.90039c4.69922 -15.4004 -1.5 -39.9004 -5.40039 -56c8.09961 -21.2998 19.5996 -35.7998 36.7998 -46.2998
|
||||
c17.4004 2.2002 52.2002 5.5 64.4004 -6.5zM100.1 49.9004c0 -0.700195 11.4004 4.69922 30.4004 35c-5.90039 -5.5 -25.2998 -21.3008 -30.4004 -35zM181.7 240.5c-2.5 0 -2.60059 -26.9004 1.7998 -40.7998c4.90039 8.7002 5.59961 40.7998 -1.7998 40.7998zM157.3 103.9
|
||||
c15.9004 6.09961 34 14.8994 54.7998 19.1992c-11.1992 8.30078 -21.7998 20.4004 -30.0996 35.5c-6.7002 -17.6992 -15 -37.7998 -24.7002 -54.6992zM288.9 108.9c3.59961 2.39941 -2.2002 10.3994 -37.3008 7.7998c32.3008 -13.7998 37.3008 -7.7998 37.3008 -7.7998z" />
|
||||
<glyph glyph-name="file-word" unicode="" horiz-adv-x="384"
|
||||
d="M369.9 350.1c9 -9 14.0996 -21.2998 14.0996 -34v-332.1c0 -26.5 -21.5 -48 -48 -48h-288c-26.5 0 -48 21.5 -48 48v416c0 26.5 21.5 48 48 48.0996h204.1c12.7002 0 24.9004 -5.09961 33.9004 -14.0996zM332.1 320l-76.0996 76.0996v-76.0996h76.0996zM48 -16h288v288
|
||||
h-104c-13.2998 0 -24 10.7002 -24 24v104h-160v-416zM268.1 192v0.200195h15.8008c7.7998 0 13.5 -7.2998 11.5996 -14.9004c-4.2998 -17 -13.7002 -54.0996 -34.5 -136c-1.2998 -5.39941 -6.09961 -9.09961 -11.5996 -9.09961h-24.7002
|
||||
c-5.5 0 -10.2998 3.7998 -11.6006 9.09961c-5.2998 20.9004 -17.7998 71 -17.8994 71.4004l-2.90039 17.2998c-0.5 -5.2998 -1.5 -11.0996 -3 -17.2998l-17.8994 -71.4004c-1.30078 -5.39941 -6.10059 -9.09961 -11.6006 -9.09961h-25.2002
|
||||
c-5.59961 0 -10.3994 3.7002 -11.6992 9.09961c-6.5 26.5 -25.2002 103.4 -33.2002 136c-1.7998 7.5 3.89941 14.7998 11.7002 14.7998h16.7998c5.7998 0 10.7002 -4.09961 11.7998 -9.69922c5 -25.7002 18.4004 -93.8008 19.0996 -99
|
||||
c0.300781 -1.7002 0.400391 -3.10059 0.5 -4.2002c0.800781 7.5 0.400391 4.7002 24.8008 103.7c1.39941 5.2998 6.19922 9.09961 11.6992 9.09961h13.3008c5.59961 0 10.3994 -3.7998 11.6992 -9.2002c23.9004 -99.7002 22.8008 -94.3994 23.6006 -99.5
|
||||
c0.299805 -1.7002 0.5 -3.09961 0.700195 -4.2998c0.599609 8.09961 0.399414 5.7998 21 103.5c1.09961 5.5 6 9.5 11.6992 9.5z" />
|
||||
<glyph glyph-name="file-excel" unicode="" horiz-adv-x="384"
|
||||
d="M369.9 350.1c9 -9 14.0996 -21.2998 14.0996 -34v-332.1c0 -26.5 -21.5 -48 -48 -48h-288c-26.5 0 -48 21.5 -48 48v416c0 26.5 21.5 48 48 48.0996h204.1c12.7002 0 24.9004 -5.09961 33.9004 -14.0996zM332.1 320l-76.0996 76.0996v-76.0996h76.0996zM48 -16h288v288
|
||||
h-104c-13.2998 0 -24 10.7002 -24 24v104h-160v-416zM260 224c9.2002 0 15 -10 10.2998 -18c-16 -27.5 -45.5996 -76.9004 -46.2998 -78l46.4004 -78c4.59961 -8 -1.10059 -18 -10.4004 -18h-28.7998c-4.40039 0 -8.5 2.40039 -10.6006 6.2998
|
||||
c-22.6992 41.7998 -13.6992 27.5 -28.5996 57.7002c-5.59961 -12.7002 -6.90039 -17.7002 -28.5996 -57.7002c-2.10059 -3.89941 -6.10059 -6.2998 -10.5 -6.2998h-28.9004c-9.2998 0 -15.0996 10 -10.4004 18l46.3008 78l-46.3008 78c-4.59961 8 1.10059 18 10.4004 18
|
||||
h28.9004c4.39941 0 8.5 -2.40039 10.5996 -6.2998c21.7002 -40.4004 14.7002 -28.6006 28.5996 -57.7002c6.40039 15.2998 10.6006 24.5996 28.6006 57.7002c2.09961 3.89941 6.09961 6.2998 10.5 6.2998h28.7998z" />
|
||||
<glyph glyph-name="file-powerpoint" unicode="" horiz-adv-x="384"
|
||||
d="M369.9 350.1c9 -9 14.0996 -21.2998 14.0996 -34v-332.1c0 -26.5 -21.5 -48 -48 -48h-288c-26.5 0 -48 21.5 -48 48v416c0 26.5 21.5 48 48 48.0996h204.1c12.7002 0 24.9004 -5.09961 33.9004 -14.0996zM332.1 320l-76.0996 76.0996v-76.0996h76.0996zM48 -16h288v288
|
||||
h-104c-13.2998 0 -24 10.7002 -24 24v104h-160v-416zM120 44v168c0 6.59961 5.40039 12 12 12h69.2002c36.7002 0 62.7998 -27 62.7998 -66.2998c0 -74.2998 -68.7002 -66.5 -95.5 -66.5v-47.2002c0 -6.59961 -5.40039 -12 -12 -12h-24.5c-6.59961 0 -12 5.40039 -12 12z
|
||||
M168.5 131.4h23c7.90039 0 13.9004 2.39941 18.0996 7.19922c8.5 9.80078 8.40039 28.5 0.100586 37.8008c-4.10059 4.59961 -9.90039 7 -17.4004 7h-23.8994v-52h0.0996094z" />
|
||||
<glyph glyph-name="file-image" unicode="" horiz-adv-x="384"
|
||||
d="M369.9 350.1c9 -9 14.0996 -21.2998 14.0996 -34v-332.1c0 -26.5 -21.5 -48 -48 -48h-288c-26.5 0 -48 21.5 -48 48v416c0 26.5 21.5 48 48 48.0996h204.1c12.7002 0 24.9004 -5.09961 33.9004 -14.0996zM332.1 320l-76.0996 76.0996v-76.0996h76.0996zM48 -16h288v288
|
||||
h-104c-13.2998 0 -24 10.7002 -24 24v104h-160v-416zM80 32v64l39.5 39.5c4.7002 4.7002 12.2998 4.7002 17 0l39.5 -39.5l87.5 87.5c4.7002 4.7002 12.2998 4.7002 17 0l23.5 -23.5v-128h-224zM128 272c26.5 0 48 -21.5 48 -48s-21.5 -48 -48 -48s-48 21.5 -48 48
|
||||
s21.5 48 48 48z" />
|
||||
<glyph glyph-name="file-archive" unicode="" horiz-adv-x="384"
|
||||
d="M128.3 288h32v-32h-32v32zM192.3 384v-32h-32v32h32zM128.3 352h32v-32h-32v32zM192.3 320v-32h-32v32h32zM369.9 350.1c9 -9 14.0996 -21.2998 14.0996 -34v-332.1c0 -26.5 -21.5 -48 -48 -48h-288c-26.5 0 -48 21.5 -48 48v416c0 26.5 21.5 48 48 48.0996h204.1
|
||||
c12.7002 0 24.9004 -5.09961 33.9004 -14.0996zM256 396.1v-76.0996h76.0996zM336 -16v288h-104c-13.2998 0 -24 10.7002 -24 24v104h-48.2998v-16h-32v16h-79.7002v-416h288zM194.2 182.3l17.2998 -87.7002c6.40039 -32.3994 -18.4004 -62.5996 -51.5 -62.5996
|
||||
c-33.2002 0 -58 30.4004 -51.4004 62.9004l19.7002 97.0996v32h32v-32h22.1006c5.7998 0 10.6992 -4.09961 11.7998 -9.7002zM160.3 57.9004c17.9004 0 32.4004 12.0996 32.4004 27c0 14.8994 -14.5 27 -32.4004 27c-17.8994 0 -32.3994 -12.1006 -32.3994 -27
|
||||
c0 -14.9004 14.5 -27 32.3994 -27zM192.3 256v-32h-32v32h32z" />
|
||||
<glyph glyph-name="file-audio" unicode="" horiz-adv-x="384"
|
||||
d="M369.941 350.059c7.75977 -7.75977 14.0586 -22.9658 14.0586 -33.9404v-332.118c0 -26.5098 -21.4902 -48 -48 -48h-288c-26.5098 0 -48 21.4902 -48 48v416c0 26.5098 21.4902 48 48 48h204.118c10.9746 0 26.1807 -6.29883 33.9404 -14.0586zM332.118 320
|
||||
l-76.1182 76.1182v-76.1182h76.1182zM48 -16h288v288h-104c-13.2549 0 -24 10.7451 -24 24v104h-160v-416zM192 60.0244c0 -10.6914 -12.9258 -16.0459 -20.4854 -8.48535l-35.5146 35.9746h-28c-6.62695 0 -12 5.37305 -12 12v56c0 6.62695 5.37305 12 12 12h28
|
||||
l35.5146 36.9473c7.56055 7.56055 20.4854 2.20605 20.4854 -8.48535v-135.951zM233.201 107.154c9.05078 9.29688 9.05957 24.1328 0.000976562 33.4385c-22.1494 22.752 12.2344 56.2461 34.3945 33.4814c27.1982 -27.9404 27.2119 -72.4443 0.000976562 -100.401
|
||||
c-21.793 -22.3857 -56.9463 10.3154 -34.3965 33.4814z" />
|
||||
<glyph glyph-name="file-video" unicode="" horiz-adv-x="384"
|
||||
d="M369.941 350.059c7.75977 -7.75977 14.0586 -22.9658 14.0586 -33.9404v-332.118c0 -26.5098 -21.4902 -48 -48 -48h-288c-26.5098 0 -48 21.4902 -48 48v416c0 26.5098 21.4902 48 48 48h204.118c10.9746 0 26.1807 -6.29883 33.9404 -14.0586zM332.118 320
|
||||
l-76.1182 76.1182v-76.1182h76.1182zM48 -16h288v288h-104c-13.2549 0 -24 10.7451 -24 24v104h-160v-416zM276.687 195.303c10.0049 10.0049 27.3135 2.99707 27.3135 -11.3135v-111.976c0 -14.2939 -17.2959 -21.332 -27.3135 -11.3135l-52.6865 52.6738v-37.374
|
||||
c0 -11.0459 -8.9541 -20 -20 -20h-104c-11.0459 0 -20 8.9541 -20 20v104c0 11.0459 8.9541 20 20 20h104c11.0459 0 20 -8.9541 20 -20v-37.374z" />
|
||||
<glyph glyph-name="file-code" unicode="" horiz-adv-x="384"
|
||||
d="M149.9 98.9004c3.5 -3.30078 3.69922 -8.90039 0.399414 -12.4004l-17.3994 -18.5996c-1.60059 -1.80078 -4 -2.80078 -6.40039 -2.80078c-2.2002 0 -4.40039 0.900391 -6 2.40039l-57.7002 54.0996c-3.7002 3.40039 -3.7002 9.30078 0 12.8008l57.7002 54.0996
|
||||
c3.40039 3.2998 9 3.2002 12.4004 -0.400391l17.3994 -18.5996l0.200195 -0.200195c3.2002 -3.59961 2.7998 -9.2002 -0.799805 -12.3994l-32.7998 -28.9004l32.7998 -28.9004zM369.9 350.1c9 -9 14.0996 -21.2998 14.0996 -34v-332.1c0 -26.5 -21.5 -48 -48 -48h-288
|
||||
c-26.5 0 -48 21.5 -48 48v416c0 26.5 21.5 48 48 48.0996h204.1c12.7002 0 24.9004 -5.09961 33.9004 -14.0996zM256 396.1v-76.0996h76.0996zM336 -16v288h-104c-13.2998 0 -24 10.7002 -24 24v104h-160v-416h288zM209.6 234l24.4004 -7
|
||||
c4.7002 -1.2998 7.40039 -6.2002 6 -10.9004l-54.7002 -188.199c-1.2998 -4.60059 -6.2002 -7.40039 -10.8994 -6l-24.4004 7.09961c-4.7002 1.2998 -7.40039 6.2002 -6 10.9004l54.7002 188.1c1.39941 4.7002 6.2002 7.40039 10.8994 6zM234.1 157.1
|
||||
c-3.5 3.30078 -3.69922 8.90039 -0.399414 12.4004l17.3994 18.5996c3.30078 3.60059 8.90039 3.7002 12.4004 0.400391l57.7002 -54.0996c3.7002 -3.40039 3.7002 -9.30078 0 -12.8008l-57.7002 -54.0996c-3.5 -3.2998 -9.09961 -3.09961 -12.4004 0.400391
|
||||
l-17.3994 18.5996l-0.200195 0.200195c-3.2002 3.59961 -2.7998 9.2002 0.799805 12.3994l32.7998 28.9004l-32.7998 28.9004z" />
|
||||
<glyph glyph-name="life-ring" unicode=""
|
||||
d="M256 -56c-136.967 0 -248 111.033 -248 248s111.033 248 248 248s248 -111.033 248 -248s-111.033 -248 -248 -248zM152.602 20.7197c63.2178 -38.3184 143.579 -38.3184 206.797 0l-53.4111 53.4111c-31.8467 -13.5215 -68.168 -13.5059 -99.9746 0zM336 192
|
||||
c0 44.1123 -35.8877 80 -80 80s-80 -35.8877 -80 -80s35.8877 -80 80 -80s80 35.8877 80 80zM427.28 88.6016c38.3184 63.2178 38.3184 143.579 0 206.797l-53.4111 -53.4111c13.5215 -31.8467 13.5049 -68.168 0 -99.9746zM359.397 363.28
|
||||
c-63.2168 38.3184 -143.578 38.3184 -206.796 0l53.4111 -53.4111c31.8457 13.5215 68.167 13.5049 99.9736 0zM84.7197 295.398c-38.3184 -63.2178 -38.3184 -143.579 0 -206.797l53.4111 53.4111c-13.5215 31.8467 -13.5059 68.168 0 99.9746z" />
|
||||
<glyph glyph-name="paper-plane" unicode=""
|
||||
d="M440 441.5c34.5996 19.9004 77.5996 -8.7998 71.5 -48.9004l-59.4004 -387.199c-2.2998 -14.5 -11.0996 -27.3008 -23.8994 -34.5c-7.2998 -4.10059 -15.4004 -6.2002 -23.6006 -6.2002c-6.19922 0 -12.3994 1.2002 -18.2998 3.59961l-111.899 46.2002l-43.8008 -59.0996
|
||||
c-27.3994 -36.9004 -86.5996 -17.8008 -86.5996 28.5996v84.4004l-114.3 47.2998c-36.7998 15.0996 -40.1006 66 -5.7002 85.8994zM192 -16l36.5996 49.5l-36.5996 15.0996v-64.5996zM404.6 12.7002l59.4004 387.3l-416 -240l107.8 -44.5996l211.5 184.3
|
||||
c14.2002 12.2998 34.4004 -5.7002 23.7002 -21.2002l-140.2 -202.3z" />
|
||||
<glyph glyph-name="futbol" unicode="" horiz-adv-x="496"
|
||||
d="M483.8 268.6c42.2998 -130.199 -29 -270.1 -159.2 -312.399c-25.5 -8.2998 -51.2998 -12.2002 -76.6992 -12.2002c-104.5 0 -201.7 66.5996 -235.7 171.4c-42.2998 130.199 29 270.1 159.2 312.399c25.5 8.2998 51.2998 12.2002 76.6992 12.2002
|
||||
c104.5 0 201.7 -66.5996 235.7 -171.4zM409.3 74.9004c6.10059 8.39941 12.1006 16.8994 16.7998 26.1992c14.3008 28.1006 21.5 58.5 21.7002 89.2002l-38.8994 36.4004l-71.1006 -22.1006l-24.3994 -75.1992l43.6992 -60.9004zM409.3 310.3
|
||||
c-24.5 33.4004 -58.7002 58.4004 -97.8994 71.4004l-47.4004 -26.2002v-73.7998l64.2002 -46.5l70.7002 22zM184.9 381.6c-39.9004 -13.2998 -73.5 -38.5 -97.8008 -71.8994l10.1006 -52.5l70.5996 -22l64.2002 46.5v73.7998zM139 68.5l43.5 61.7002l-24.2998 74.2998
|
||||
l-71.1006 22.2002l-39 -36.4004c0.5 -55.7002 23.4004 -95.2002 37.8008 -115.3zM187.2 1.5c64.0996 -20.4004 115.5 -1.7998 121.7 0l22.3994 48.0996l-44.2998 61.7002h-78.5996l-43.6006 -61.7002z" />
|
||||
<glyph glyph-name="newspaper" unicode="" horiz-adv-x="576"
|
||||
d="M552 384c13.2549 0 24 -10.7451 24 -24v-336c0 -13.2549 -10.7451 -24 -24 -24h-496c-30.9277 0 -56 25.0723 -56 56v272c0 13.2549 10.7451 24 24 24h42.752c6.60547 18.623 24.3896 32 45.248 32h440zM48 56c0 -4.41113 3.58887 -8 8 -8s8 3.58887 8 8v248h-16v-248z
|
||||
M528 48v288h-416v-280c0 -2.7168 -0.204102 -5.38574 -0.578125 -8h416.578zM172 168c-6.62695 0 -12 5.37305 -12 12v96c0 6.62695 5.37305 12 12 12h136c6.62695 0 12 -5.37305 12 -12v-96c0 -6.62695 -5.37305 -12 -12 -12h-136zM200 248v-40h80v40h-80zM160 108v24
|
||||
c0 6.62695 5.37305 12 12 12h136c6.62695 0 12 -5.37305 12 -12v-24c0 -6.62695 -5.37305 -12 -12 -12h-136c-6.62695 0 -12 5.37305 -12 12zM352 108v24c0 6.62695 5.37305 12 12 12h104c6.62695 0 12 -5.37305 12 -12v-24c0 -6.62695 -5.37305 -12 -12 -12h-104
|
||||
c-6.62695 0 -12 5.37305 -12 12zM352 252v24c0 6.62695 5.37305 12 12 12h104c6.62695 0 12 -5.37305 12 -12v-24c0 -6.62695 -5.37305 -12 -12 -12h-104c-6.62695 0 -12 5.37305 -12 12zM352 180v24c0 6.62695 5.37305 12 12 12h104c6.62695 0 12 -5.37305 12 -12v-24
|
||||
c0 -6.62695 -5.37305 -12 -12 -12h-104c-6.62695 0 -12 5.37305 -12 12z" />
|
||||
<glyph glyph-name="bell-slash" unicode="" horiz-adv-x="640"
|
||||
d="M633.99 -23.0195c6.91016 -5.52051 8.01953 -15.5908 2.5 -22.4902l-10 -12.4902c-5.53027 -6.88965 -15.5898 -8.00977 -22.4902 -2.49023l-598 467.51c-6.90039 5.52051 -8.01953 15.5908 -2.49023 22.4902l10 12.4902
|
||||
c5.52051 6.90039 15.5898 8.00977 22.4902 2.49023zM163.53 80h182.84l61.3994 -48h-279.659c-19.1201 0 -31.9902 15.5996 -32.1006 32c-0.0498047 7.5498 2.61035 15.2598 8.61035 21.71c18.3701 19.7402 51.5703 49.6904 54.8398 140.42l45.4697 -35.5498
|
||||
c-6.91992 -54.7803 -24.6895 -88.5498 -41.3994 -110.58zM320 352c-23.3496 0 -45 -7.17969 -62.9404 -19.4004l-38.1699 29.8408c19.6807 15.7793 43.1104 27.3096 69.1299 32.7197v20.8398c0 17.6699 14.3203 32 31.9805 32s31.9805 -14.3301 31.9805 -32v-20.8398
|
||||
c73.46 -15.2598 127.939 -77.46 127.939 -155.16c0 -41.3604 6.03027 -70.7197 14.3398 -92.8496l-59.5293 46.54c-1.63086 13.96 -2.77051 28.8896 -2.79004 45.7295c0 0.200195 0.0595703 0.379883 0.0595703 0.580078c0 61.8604 -50.1396 112 -112 112zM320 -64
|
||||
c-35.3203 0 -63.9697 28.6504 -63.9697 64h127.939c0 -35.3496 -28.6494 -64 -63.9697 -64z" />
|
||||
<glyph glyph-name="copyright" unicode=""
|
||||
d="M256 440c136.967 0 248 -111.033 248 -248s-111.033 -248 -248 -248s-248 111.033 -248 248s111.033 248 248 248zM256 -8c110.549 0 200 89.4678 200 200c0 110.549 -89.4678 200 -200 200c-110.549 0 -200 -89.4688 -200 -200c0 -110.549 89.4678 -200 200 -200z
|
||||
M363.351 93.0645c-9.61328 -9.71289 -45.5293 -41.3965 -104.064 -41.3965c-82.4297 0 -140.484 61.4248 -140.484 141.567c0 79.1514 60.2754 139.4 139.763 139.4c55.5303 0 88.7373 -26.6201 97.5928 -34.7783c2.13379 -1.96289 3.86523 -5.9082 3.86523 -8.80762
|
||||
c0 -1.95508 -0.864258 -4.87402 -1.92969 -6.51465l-18.1543 -28.1133c-3.8418 -5.9502 -11.9668 -7.28223 -17.499 -2.9209c-8.5957 6.77637 -31.8145 22.5381 -61.708 22.5381c-48.3037 0 -77.916 -35.3301 -77.916 -80.082c0 -41.5889 26.8877 -83.6924 78.2764 -83.6924
|
||||
c32.6572 0 56.8428 19.0391 65.7266 27.2256c5.26953 4.85645 13.5957 4.03906 17.8193 -1.73828l19.8652 -27.1699c1.28613 -1.74512 2.33008 -4.91992 2.33008 -7.08789c0 -2.72363 -1.56055 -6.5 -3.48242 -8.42969z" />
|
||||
<glyph glyph-name="closed-captioning" unicode=""
|
||||
d="M464 384c26.5 0 48 -21.5 48 -48v-288c0 -26.5 -21.5 -48 -48 -48h-416c-26.5 0 -48 21.5 -48 48v288c0 26.5 21.5 48 48 48h416zM458 48c3.2998 0 6 2.7002 6 6v276c0 3.2998 -2.7002 6 -6 6h-404c-3.2998 0 -6 -2.7002 -6 -6v-276c0 -3.2998 2.7002 -6 6 -6h404z
|
||||
M246.9 133.7c1.69922 -2.40039 1.5 -5.60059 -0.5 -7.7002c-53.6006 -56.7998 -172.801 -32.0996 -172.801 67.9004c0 97.2998 121.7 119.5 172.5 70.0996c2.10059 -2 2.5 -3.2002 1 -5.7002l-17.5 -30.5c-1.89941 -3.09961 -6.19922 -4 -9.09961 -1.7002
|
||||
c-40.7998 32 -94.5996 14.9004 -94.5996 -31.1992c0 -48 51 -70.5 92.1992 -32.6006c2.80078 2.5 7.10059 2.10059 9.2002 -0.899414zM437.3 133.7c1.7002 -2.40039 1.5 -5.60059 -0.5 -7.7002c-53.5996 -56.9004 -172.8 -32.0996 -172.8 67.9004
|
||||
c0 97.2998 121.7 119.5 172.5 70.0996c2.09961 -2 2.5 -3.2002 1 -5.7002l-17.5 -30.5c-1.90039 -3.09961 -6.2002 -4 -9.09961 -1.7002c-40.8008 32 -94.6006 14.9004 -94.6006 -31.1992c0 -48 51 -70.5 92.2002 -32.6006c2.7998 2.5 7.09961 2.10059 9.2002 -0.899414z
|
||||
" />
|
||||
<glyph glyph-name="object-group" unicode=""
|
||||
d="M500 320h-12v-256h12c6.62695 0 12 -5.37305 12 -12v-72c0 -6.62695 -5.37305 -12 -12 -12h-72c-6.62695 0 -12 5.37305 -12 12v12h-320v-12c0 -6.62695 -5.37305 -12 -12 -12h-72c-6.62695 0 -12 5.37305 -12 12v72c0 6.62695 5.37305 12 12 12h12v256h-12
|
||||
c-6.62695 0 -12 5.37305 -12 12v72c0 6.62695 5.37305 12 12 12h72c6.62695 0 12 -5.37305 12 -12v-12h320v12c0 6.62695 5.37305 12 12 12h72c6.62695 0 12 -5.37305 12 -12v-72c0 -6.62695 -5.37305 -12 -12 -12zM448 384v-32h32v32h-32zM32 384v-32h32v32h-32zM64 0v32
|
||||
h-32v-32h32zM480 0v32h-32v-32h32zM440 64v256h-12c-6.62695 0 -12 5.37305 -12 12v12h-320v-12c0 -6.62695 -5.37305 -12 -12 -12h-12v-256h12c6.62695 0 12 -5.37305 12 -12v-12h320v12c0 6.62695 5.37305 12 12 12h12zM404 256c6.62695 0 12 -5.37207 12 -12v-168
|
||||
c0 -6.62793 -5.37305 -12 -12 -12h-200c-6.62695 0 -12 5.37207 -12 12v52h-84c-6.62695 0 -12 5.37207 -12 12v168c0 6.62793 5.37305 12 12 12h200c6.62695 0 12 -5.37207 12 -12v-52h84zM136 280v-112h144v112h-144zM376 104v112h-56v-76
|
||||
c0 -6.62793 -5.37305 -12 -12 -12h-76v-24h144z" />
|
||||
<glyph glyph-name="object-ungroup" unicode="" horiz-adv-x="576"
|
||||
d="M564 224h-12v-160h12c6.62695 0 12 -5.37305 12 -12v-72c0 -6.62695 -5.37305 -12 -12 -12h-72c-6.62695 0 -12 5.37305 -12 12v12h-224v-12c0 -6.62695 -5.37305 -12 -12 -12h-72c-6.62695 0 -12 5.37305 -12 12v72c0 6.62695 5.37305 12 12 12h12v24h-88v-12
|
||||
c0 -6.62695 -5.37305 -12 -12 -12h-72c-6.62695 0 -12 5.37305 -12 12v72c0 6.62695 5.37305 12 12 12h12v160h-12c-6.62695 0 -12 5.37305 -12 12v72c0 6.62695 5.37305 12 12 12h72c6.62695 0 12 -5.37305 12 -12v-12h224v12c0 6.62695 5.37305 12 12 12h72
|
||||
c6.62695 0 12 -5.37305 12 -12v-72c0 -6.62695 -5.37305 -12 -12 -12h-12v-24h88v12c0 6.62695 5.37305 12 12 12h72c6.62695 0 12 -5.37305 12 -12v-72c0 -6.62695 -5.37305 -12 -12 -12zM352 384v-32h32v32h-32zM352 128v-32h32v32h-32zM64 96v32h-32v-32h32zM64 352v32
|
||||
h-32v-32h32zM96 136h224v12c0 6.62695 5.37305 12 12 12h12v160h-12c-6.62695 0 -12 5.37305 -12 12v12h-224v-12c0 -6.62695 -5.37305 -12 -12 -12h-12v-160h12c6.62695 0 12 -5.37305 12 -12v-12zM224 0v32h-32v-32h32zM504 64v160h-12c-6.62695 0 -12 5.37305 -12 12v12
|
||||
h-88v-88h12c6.62695 0 12 -5.37305 12 -12v-72c0 -6.62695 -5.37305 -12 -12 -12h-72c-6.62695 0 -12 5.37305 -12 12v12h-88v-24h12c6.62695 0 12 -5.37305 12 -12v-12h224v12c0 6.62695 5.37305 12 12 12h12zM544 0v32h-32v-32h32zM544 256v32h-32v-32h32z" />
|
||||
<glyph glyph-name="sticky-note" unicode="" horiz-adv-x="448"
|
||||
d="M448 99.8936c0 -10.9746 -6.29883 -26.1797 -14.0586 -33.9404l-83.8828 -83.8818c-7.75977 -7.76074 -22.9658 -14.0596 -33.9404 -14.0596h-268.118c-26.5098 0 -48 21.4902 -48 48v351.988c0 26.5098 21.4902 48 48 48h352c26.5098 0 48 -21.4902 48 -48v-268.106z
|
||||
M320 19.8936l76.1182 76.1182h-76.1182v-76.1182zM400 368h-352v-351.988h224v104c0 13.2549 10.7451 24 24 24h104v223.988z" />
|
||||
<glyph glyph-name="clone" unicode=""
|
||||
d="M464 448c26.5098 0 48 -21.4902 48 -48v-320c0 -26.5098 -21.4902 -48 -48 -48h-48v-48c0 -26.5098 -21.4902 -48 -48 -48h-320c-26.5098 0 -48 21.4902 -48 48v320c0 26.5098 21.4902 48 48 48h48v48c0 26.5098 21.4902 48 48 48h320zM362 -16c3.31152 0 6 2.68848 6 6
|
||||
v42h-224c-26.5098 0 -48 21.4902 -48 48v224h-42c-3.31152 0 -6 -2.68848 -6 -6v-308c0 -3.31152 2.68848 -6 6 -6h308zM458 80c3.31152 0 6 2.68848 6 6v308c0 3.31152 -2.68848 6 -6 6h-308c-3.31152 0 -6 -2.68848 -6 -6v-308c0 -3.31152 2.68848 -6 6 -6h308z" />
|
||||
<glyph glyph-name="hourglass" unicode="" horiz-adv-x="384"
|
||||
d="M368 400c0 -80.0996 -31.8984 -165.619 -97.1797 -208c64.9912 -42.1934 97.1797 -127.436 97.1797 -208h4c6.62695 0 12 -5.37305 12 -12v-24c0 -6.62695 -5.37305 -12 -12 -12h-360c-6.62695 0 -12 5.37305 -12 12v24c0 6.62695 5.37305 12 12 12h4
|
||||
c0 80.0996 31.8994 165.619 97.1797 208c-64.9912 42.1934 -97.1797 127.436 -97.1797 208h-4c-6.62695 0 -12 5.37305 -12 12v24c0 6.62695 5.37305 12 12 12h360c6.62695 0 12 -5.37305 12 -12v-24c0 -6.62695 -5.37305 -12 -12 -12h-4zM64 400
|
||||
c0 -101.621 57.3066 -184 128 -184s128 82.3799 128 184h-256zM320 -16c0 101.62 -57.3076 184 -128 184s-128 -82.3799 -128 -184h256z" />
|
||||
<glyph glyph-name="hand-rock" unicode=""
|
||||
d="M408.864 368.948c48.8213 20.751 103.136 -15.0723 103.136 -67.9111v-114.443c0 -15.3955 -3.08887 -30.3906 -9.18262 -44.5674l-42.835 -99.6562c-4.99707 -11.625 -3.98242 -18.8574 -3.98242 -42.3701c0 -17.6729 -14.3271 -32 -32 -32h-252
|
||||
c-17.6729 0 -32 14.3271 -32 32c0 27.3301 1.1416 29.2012 -3.11035 32.9033l-97.71 85.0811c-24.8994 21.6797 -39.1797 52.8926 -39.1797 85.6338v56.9531c0 47.4277 44.8457 82.0215 91.0459 71.1807c1.96094 55.751 63.5107 87.8262 110.671 60.8057
|
||||
c29.1895 31.0713 78.8604 31.4473 108.334 -0.0214844c32.7051 18.6846 76.4121 10.3096 98.8135 -23.5879zM464 186.594v114.445c0 34.29 -52 33.8232 -52 0.676758c0 -8.83594 -7.16309 -16 -16 -16h-7c-8.83691 0 -16 7.16406 -16 16v26.751
|
||||
c0 34.457 -52 33.707 -52 0.676758v-27.4287c0 -8.83594 -7.16309 -16 -16 -16h-7c-8.83691 0 -16 7.16406 -16 16v40.4658c0 34.3525 -52 33.8115 -52 0.677734v-41.1436c0 -8.83594 -7.16406 -16 -16 -16h-7c-8.83594 0 -16 7.16406 -16 16v26.751
|
||||
c0 34.4023 -52 33.7744 -52 0.676758v-116.571c0 -8.83203 -7.16797 -16 -16 -16c-3.30664 0 -8.01367 1.7627 -10.5068 3.93359l-7 6.09473c-3.03223 2.64062 -5.49316 8.04688 -5.49316 12.0674v0v41.2275c0 34.2148 -52 33.8857 -52 0.677734v-56.9531
|
||||
c0 -18.8555 8.27441 -36.874 22.7002 -49.4365l97.71 -85.0801c12.4502 -10.8398 19.5898 -26.4463 19.5898 -42.8164v-10.2861h220v7.07617c0 13.21 2.65332 26.0791 7.88281 38.25l42.835 99.6553c2.91602 6.75391 5.28223 18.207 5.28223 25.5635v0.0488281z" />
|
||||
<glyph glyph-name="hand-paper" unicode="" horiz-adv-x="448"
|
||||
d="M372.57 335.359c39.9062 5.63281 75.4297 -25.7393 75.4297 -66.3594v-131.564c-0.00195312 -12.7666 -2.33008 -33.2246 -5.19531 -45.666l-30.1836 -130.958c-3.34668 -14.5234 -16.2783 -24.8125 -31.1816 -24.8125h-222.897
|
||||
c-9.10352 0 -20.7793 6.01758 -26.0615 13.4316l-119.97 168.415c-21.2441 29.8203 -14.8047 71.3574 14.5498 93.1533c18.7754 13.9395 42.1309 16.2979 62.083 8.87109v126.13c0 44.0547 41.125 75.5439 82.4053 64.9834c23.8926 48.1963 92.3535 50.2471 117.982 0.74707
|
||||
c42.5186 11.1445 83.0391 -21.9346 83.0391 -65.5469v-10.8242zM399.997 137.437l-0.00195312 131.563c0 24.9492 -36.5703 25.5508 -36.5703 -0.691406v-76.3086c0 -8.83691 -7.16309 -16 -16 -16h-6.85645c-8.83691 0 -16 7.16309 -16 16v154.184
|
||||
c0 25.501 -36.5703 26.3633 -36.5703 0.691406v-154.875c0 -8.83691 -7.16309 -16 -16 -16h-6.85645c-8.83691 0 -16 7.16309 -16 16v188.309c0 25.501 -36.5703 26.3545 -36.5703 0.691406v-189c0 -8.83691 -7.16309 -16 -16 -16h-6.85645c-8.83691 0 -16 7.16309 -16 16
|
||||
v153.309c0 25.501 -36.5713 26.3359 -36.5713 0.691406v-206.494c0 -15.5703 -20.0352 -21.9092 -29.0303 -9.2832l-27.1279 38.0791c-14.3711 20.1709 -43.833 -2.33496 -29.3945 -22.6045l115.196 -161.697h201.92l27.3252 118.551
|
||||
c2.63086 11.417 3.96484 23.1553 3.96484 34.8857z" />
|
||||
<glyph glyph-name="hand-scissors" unicode=""
|
||||
d="M256 -32c-44.9561 0 -77.3428 43.2627 -64.0244 85.8535c-21.6484 13.71 -34.0156 38.7617 -30.3408 65.0068h-87.6348c-40.8037 0 -74 32.8105 -74 73.1406c0 40.3291 33.1963 73.1396 74 73.1396l94 -9.14062l-78.8496 18.6787
|
||||
c-38.3076 14.7422 -57.04 57.4707 -41.9424 95.1123c15.0303 37.4736 57.7549 55.7803 95.6416 41.2012l144.929 -55.7568c24.9551 30.5566 57.8086 43.9932 92.2178 24.7324l97.999 -54.8525c20.9746 -11.7393 34.0049 -33.8457 34.0049 -57.6904v-205.702
|
||||
c0 -30.7422 -21.4404 -57.5576 -51.7979 -64.5537l-118.999 -27.4268c-4.97168 -1.14648 -10.0889 -1.72949 -15.2031 -1.72949zM256 16.0127l70 -0.000976562c1.23633 0 3.21777 0.225586 4.42285 0.501953l119.001 27.4277
|
||||
c8.58203 1.97754 14.5762 9.29102 14.5762 17.7812v205.701c0 6.4873 -3.62109 12.542 -9.44922 15.8047l-98 54.8545c-8.13965 4.55566 -18.668 2.61914 -24.4873 -4.50781l-21.7646 -26.6475c-2.65039 -3.24512 -8.20215 -5.87891 -12.3926 -5.87891
|
||||
c-1.64062 0 -4.21484 0.477539 -5.74609 1.06738l-166.549 64.0908c-32.6543 12.5664 -50.7744 -34.5771 -19.2227 -46.7168l155.357 -59.7852c5.66016 -2.17773 10.2539 -8.86816 10.2539 -14.9326v0v-11.6328c0 -8.83691 -7.16309 -16 -16 -16h-182
|
||||
c-34.375 0 -34.4297 -50.2803 0 -50.2803h182c8.83691 0 16 -7.16309 16 -16v-6.85645c0 -8.83691 -7.16309 -16 -16 -16h-28c-25.1221 0 -25.1592 -36.5674 0 -36.5674h28c8.83691 0 16 -7.16211 16 -16v-6.85547c0 -8.83691 -7.16309 -16 -16 -16
|
||||
c-25.1201 0 -25.1602 -36.5674 0 -36.5674z" />
|
||||
<glyph glyph-name="hand-lizard" unicode="" horiz-adv-x="576"
|
||||
d="M556.686 157.458c12.6357 -19.4863 19.3145 -42.0615 19.3145 -65.2871v-124.171h-224v71.582l-99.751 38.7871c-2.7832 1.08203 -5.70996 1.63086 -8.69727 1.63086h-131.552c-30.8789 0 -56 25.1211 -56 56c0 48.5234 39.4766 88 88 88h113.709l18.333 48h-196.042
|
||||
c-44.1123 0 -80 35.8877 -80 80v8c0 30.8779 25.1211 56 56 56h293.917c24.5 0 47.084 -12.2725 60.4111 -32.8291zM528 16v76.1709v0.0478516c0 11.7461 -5.19141 29.2734 -11.5879 39.124l-146.358 225.715c-4.44336 6.85254 -11.9707 10.9424 -20.1367 10.9424h-293.917
|
||||
c-4.41113 0 -8 -3.58887 -8 -8v-8c0 -17.6445 14.3555 -32 32 -32h213.471c25.2021 0 42.626 -25.293 33.6299 -48.8457l-24.5518 -64.2812c-7.05371 -18.4658 -25.0732 -30.873 -44.8398 -30.873h-113.709c-22.0557 0 -40 -17.9443 -40 -40c0 -4.41113 3.58887 -8 8 -8
|
||||
h131.552h0.0517578c7.44141 0 19.1074 -2.19238 26.041 -4.89355l99.752 -38.7881c18.5898 -7.22852 30.6035 -24.7881 30.6035 -44.7363v-23.582h128z" />
|
||||
<glyph glyph-name="hand-spock" unicode=""
|
||||
d="M501.03 331.824c6.05762 -9.77832 10.9746 -27.0498 10.9746 -38.5518c0 -4.80664 -0.915039 -12.499 -2.04297 -17.1709l-57.623 -241.963c-12.748 -54.1729 -68.2627 -98.1387 -123.915 -98.1387h-0.345703h-107.455h-0.224609
|
||||
c-33.8135 0 -81.2148 18.834 -105.807 42.041l-91.3652 85.9766c-12.8213 12.0469 -23.2266 36.1016 -23.2266 53.6943c0 16.1299 8.97266 38.7529 20.0273 50.499c5.31836 5.66406 29.875 29.3926 68.1152 21.8477l-24.3594 82.1973
|
||||
c-1.68164 5.66406 -3.0459 15.0576 -3.0459 20.9668c0 37.5938 30.417 70.502 67.8955 73.4551c-0.204102 2.03125 -0.369141 5.33691 -0.369141 7.37891c0 31.627 24.8594 63.6895 55.4902 71.5684c43.248 10.9785 80.5645 -17.7012 89.6602 -53.0723l13.6836 -53.207
|
||||
l4.64648 22.6602c6.76074 32.417 39.123 58.8115 72.2373 58.916c8.73438 0 56.625 -3.26953 70.7383 -54.0801c15.0664 0.710938 46.9199 -3.50977 66.3105 -35.0176zM463.271 287.219c7.86914 32.9844 -42.1211 45.2695 -50.0859 11.9219l-24.8008 -104.146
|
||||
c-4.38867 -18.4141 -31.7783 -11.8926 -28.0557 6.2168l28.5479 139.166c7.39844 36.0703 -43.3076 45.0703 -50.1182 11.9629l-31.791 -154.971c-3.54883 -17.3086 -28.2832 -18.0469 -32.7109 -0.804688l-47.3262 184.035
|
||||
c-8.43359 32.8105 -58.3691 20.2676 -49.8652 -12.8359l42.4414 -165.039c4.81641 -18.7207 -23.3711 -26.9121 -28.9648 -8.00781l-31.3438 105.779c-9.6875 32.6465 -59.1191 18.2578 -49.3867 -14.625l36.0137 -121.539
|
||||
c5.61816 -18.9521 10.1777 -50.377 10.1777 -70.1436v-0.00878906c0 -6.54297 -8.05664 -10.9355 -13.4824 -5.82617l-51.123 48.1074c-24.7852 23.4082 -60.0527 -14.1875 -35.2793 -37.4902l91.3691 -85.9805c16.9629 -16.0068 49.6592 -28.998 72.9824 -28.998h0.154297
|
||||
h107.455h0.216797c34.7402 0 69.3936 27.4443 77.3525 61.2598z" />
|
||||
<glyph glyph-name="hand-pointer" unicode="" horiz-adv-x="448"
|
||||
d="M358.182 268.639c43.1934 16.6348 89.8184 -15.7949 89.8184 -62.6387v-84c-0.000976562 -4.25 -0.775391 -11.0615 -1.72754 -15.2041l-27.4297 -118.999c-6.98242 -30.2969 -33.7549 -51.7969 -64.5566 -51.7969h-178.286c-21.2588 0 -41.3682 10.4102 -53.791 27.8457
|
||||
l-109.699 154.001c-21.2432 29.8193 -14.8047 71.3574 14.5498 93.1523c18.8115 13.9658 42.1748 16.2822 62.083 8.87207v161.129c0 36.9443 29.7363 67 66.2861 67s66.2861 -30.0557 66.2861 -67v-73.6338c20.4131 2.85742 41.4678 -3.94238 56.5947 -19.6289
|
||||
c27.1934 12.8467 60.3799 5.66992 79.8721 -19.0986zM80.9854 168.303c-14.4004 20.2119 -43.8008 -2.38281 -29.3945 -22.6055l109.712 -154c3.43457 -4.81934 8.92871 -7.69727 14.6973 -7.69727h178.285c8.49219 0 15.8037 5.99414 17.7822 14.5762l27.4297 119.001
|
||||
c0.333008 1.44629 0.501953 2.93457 0.501953 4.42285v84c0 25.1602 -36.5713 25.1211 -36.5713 0c0 -8.83594 -7.16309 -16 -16 -16h-6.85645c-8.83691 0 -16 7.16406 -16 16v21c0 25.1602 -36.5713 25.1201 -36.5713 0v-21c0 -8.83594 -7.16309 -16 -16 -16h-6.85938
|
||||
c-8.83691 0 -16 7.16406 -16 16v35c0 25.1602 -36.5703 25.1201 -36.5703 0v-35c0 -8.83594 -7.16309 -16 -16 -16h-6.85742c-8.83691 0 -16 7.16406 -16 16v175c0 25.1602 -36.5713 25.1201 -36.5713 0v-241.493c0 -15.5703 -20.0352 -21.9092 -29.0303 -9.2832z
|
||||
M176.143 48v96c0 8.83691 6.26855 16 14 16h6c7.73242 0 14 -7.16309 14 -16v-96c0 -8.83691 -6.26758 -16 -14 -16h-6c-7.73242 0 -14 7.16309 -14 16zM251.571 48v96c0 8.83691 6.26758 16 14 16h6c7.73145 0 14 -7.16309 14 -16v-96c0 -8.83691 -6.26855 -16 -14 -16h-6
|
||||
c-7.73242 0 -14 7.16309 -14 16zM327 48v96c0 8.83691 6.26758 16 14 16h6c7.73242 0 14 -7.16309 14 -16v-96c0 -8.83691 -6.26758 -16 -14 -16h-6c-7.73242 0 -14 7.16309 -14 16z" />
|
||||
<glyph glyph-name="hand-peace" unicode="" horiz-adv-x="448"
|
||||
d="M362.146 256.024c42.5908 13.3184 85.8535 -19.0684 85.8535 -64.0244l-0.0117188 -70.001c-0.000976562 -4.25 -0.775391 -11.0615 -1.72949 -15.2031l-27.4268 -118.999c-6.99707 -30.3564 -33.8105 -51.7969 -64.5547 -51.7969h-205.702
|
||||
c-23.8447 0 -45.9502 13.0303 -57.6904 34.0059l-54.8525 97.999c-19.2607 34.4092 -5.82422 67.2617 24.7324 92.2178l-55.7568 144.928c-14.5791 37.8867 3.72754 80.6113 41.2012 95.6416c37.6406 15.0977 80.3691 -3.63477 95.1123 -41.9424l18.6787 -78.8496
|
||||
l-9.14062 94c0 40.8037 32.8096 74 73.1396 74s73.1406 -33.1963 73.1406 -74v-87.6348c26.2451 3.6748 51.2959 -8.69238 65.0068 -30.3408zM399.987 122l-0.000976562 70c0 25.1602 -36.5674 25.1201 -36.5674 0c0 -8.83691 -7.16309 -16 -16 -16h-6.85547
|
||||
c-8.83789 0 -16 7.16309 -16 16v28c0 25.1592 -36.5674 25.1221 -36.5674 0v-28c0 -8.83691 -7.16309 -16 -16 -16h-6.85645c-8.83691 0 -16 7.16309 -16 16v182c0 34.4297 -50.2803 34.375 -50.2803 0v-182c0 -8.83691 -7.16309 -16 -16 -16h-11.6328v0
|
||||
c-6.06445 0 -12.7549 4.59375 -14.9326 10.2539l-59.7842 155.357c-12.1396 31.5518 -59.2842 13.4326 -46.7168 -19.2227l64.0898 -166.549c0.589844 -1.53125 1.06738 -4.10547 1.06738 -5.74609c0 -4.19043 -2.63379 -9.74219 -5.87891 -12.3926l-26.6475 -21.7646
|
||||
c-7.12695 -5.81934 -9.06445 -16.3467 -4.50781 -24.4873l54.8535 -98c3.26367 -5.82812 9.31934 -9.44922 15.8057 -9.44922h205.701c8.49121 0 15.8037 5.99414 17.7812 14.5762l27.4277 119.001c0.333008 1.44629 0.501953 2.93457 0.501953 4.42285z" />
|
||||
<glyph glyph-name="registered" unicode=""
|
||||
d="M256 440c136.967 0 248 -111.033 248 -248s-111.033 -248 -248 -248s-248 111.033 -248 248s111.033 248 248 248zM256 -8c110.549 0 200 89.4678 200 200c0 110.549 -89.4678 200 -200 200c-110.549 0 -200 -89.4688 -200 -200c0 -110.549 89.4678 -200 200 -200z
|
||||
M366.442 73.791c4.40332 -7.99219 -1.37012 -17.791 -10.5107 -17.791h-42.8096h-0.0126953c-3.97559 0 -8.71582 2.84961 -10.5801 6.36035l-47.5156 89.3027h-31.958v-83.6631c0 -6.61719 -5.38281 -12 -12 -12h-38.5674c-6.61719 0 -12 5.38281 -12 12v248.304
|
||||
c0 6.61719 5.38281 12 12 12h78.667c71.251 0 101.498 -32.749 101.498 -85.252c0 -31.6123 -15.2148 -59.2969 -39.4824 -73.1758c3.02148 -4.61719 0.225586 0.199219 53.2715 -96.085zM256.933 208.094c20.9131 0 32.4307 11.5186 32.4316 32.4316
|
||||
c0 19.5752 -6.5127 31.709 -38.9297 31.709h-27.377v-64.1406h33.875z" />
|
||||
<glyph glyph-name="calendar-plus" unicode="" horiz-adv-x="448"
|
||||
d="M336 156v-24c0 -6.59961 -5.40039 -12 -12 -12h-76v-76c0 -6.59961 -5.40039 -12 -12 -12h-24c-6.59961 0 -12 5.40039 -12 12v76h-76c-6.59961 0 -12 5.40039 -12 12v24c0 6.59961 5.40039 12 12 12h76v76c0 6.59961 5.40039 12 12 12h24c6.59961 0 12 -5.40039 12 -12
|
||||
v-76h76c6.59961 0 12 -5.40039 12 -12zM448 336v-352c0 -26.5 -21.5 -48 -48 -48h-352c-26.5 0 -48 21.5 -48 48v352c0 26.5 21.5 48 48 48h48v52c0 6.59961 5.40039 12 12 12h40c6.59961 0 12 -5.40039 12 -12v-52h128v52c0 6.59961 5.40039 12 12 12h40
|
||||
c6.59961 0 12 -5.40039 12 -12v-52h48c26.5 0 48 -21.5 48 -48zM400 -10v298h-352v-298c0 -3.2998 2.7002 -6 6 -6h340c3.2998 0 6 2.7002 6 6z" />
|
||||
<glyph glyph-name="calendar-minus" unicode="" horiz-adv-x="448"
|
||||
d="M124 120c-6.59961 0 -12 5.40039 -12 12v24c0 6.59961 5.40039 12 12 12h200c6.59961 0 12 -5.40039 12 -12v-24c0 -6.59961 -5.40039 -12 -12 -12h-200zM448 336v-352c0 -26.5 -21.5 -48 -48 -48h-352c-26.5 0 -48 21.5 -48 48v352c0 26.5 21.5 48 48 48h48v52
|
||||
c0 6.59961 5.40039 12 12 12h40c6.59961 0 12 -5.40039 12 -12v-52h128v52c0 6.59961 5.40039 12 12 12h40c6.59961 0 12 -5.40039 12 -12v-52h48c26.5 0 48 -21.5 48 -48zM400 -10v298h-352v-298c0 -3.2998 2.7002 -6 6 -6h340c3.2998 0 6 2.7002 6 6z" />
|
||||
<glyph glyph-name="calendar-times" unicode="" horiz-adv-x="448"
|
||||
d="M311.7 73.2998l-17 -17c-4.7002 -4.7002 -12.2998 -4.7002 -17 0l-53.7002 53.7998l-53.7002 -53.6992c-4.7002 -4.7002 -12.2998 -4.7002 -17 0l-17 17c-4.7002 4.69922 -4.7002 12.2998 0 17l53.7002 53.6992l-53.7002 53.7002c-4.7002 4.7002 -4.7002 12.2998 0 17
|
||||
l17 17c4.7002 4.7002 12.2998 4.7002 17 0l53.7002 -53.7002l53.7002 53.7002c4.7002 4.7002 12.2998 4.7002 17 0l17 -17c4.7002 -4.7002 4.7002 -12.2998 0 -17l-53.7998 -53.7998l53.6992 -53.7002c4.80078 -4.7002 4.80078 -12.2998 0.100586 -17zM448 336v-352
|
||||
c0 -26.5 -21.5 -48 -48 -48h-352c-26.5 0 -48 21.5 -48 48v352c0 26.5 21.5 48 48 48h48v52c0 6.59961 5.40039 12 12 12h40c6.59961 0 12 -5.40039 12 -12v-52h128v52c0 6.59961 5.40039 12 12 12h40c6.59961 0 12 -5.40039 12 -12v-52h48c26.5 0 48 -21.5 48 -48zM400 -10
|
||||
v298h-352v-298c0 -3.2998 2.7002 -6 6 -6h340c3.2998 0 6 2.7002 6 6z" />
|
||||
<glyph glyph-name="calendar-check" unicode="" horiz-adv-x="448"
|
||||
d="M400 384c26.5098 0 48 -21.4902 48 -48v-352c0 -26.5098 -21.4902 -48 -48 -48h-352c-26.5098 0 -48 21.4902 -48 48v352c0 26.5098 21.4902 48 48 48h48v52c0 6.62695 5.37305 12 12 12h40c6.62695 0 12 -5.37305 12 -12v-52h128v52c0 6.62695 5.37305 12 12 12h40
|
||||
c6.62695 0 12 -5.37305 12 -12v-52h48zM394 -16c3.31152 0 6 2.68848 6 6v298h-352v-298c0 -3.31152 2.68848 -6 6 -6h340zM341.151 184.65l-142.31 -141.169c-4.70508 -4.66699 -12.3027 -4.6377 -16.9707 0.0673828l-75.0908 75.6992
|
||||
c-4.66699 4.70508 -4.6377 12.3027 0.0673828 16.9707l22.7197 22.5361c4.70508 4.66699 12.3027 4.63672 16.9697 -0.0693359l44.1035 -44.4609l111.072 110.182c4.70508 4.66699 12.3027 4.63672 16.9707 -0.0683594l22.5361 -22.7178
|
||||
c4.66699 -4.70508 4.63672 -12.3027 -0.0683594 -16.9697z" />
|
||||
<glyph glyph-name="map" unicode="" horiz-adv-x="576"
|
||||
d="M560.02 416c8.4502 0 15.9805 -6.83008 15.9805 -16.0195v-346.32c0 -11.9609 -9.01367 -25.2705 -20.1201 -29.71l-151.83 -52.8105c-5.32617 -1.7334 -14.1953 -3.13965 -19.7969 -3.13965c-5.7373 0 -14.8105 1.47363 -20.2529 3.29004l-172 60.71l-170.05 -62.8398
|
||||
c-1.99023 -0.790039 -4 -1.16016 -5.95996 -1.16016c-8.45996 0 -15.9902 6.83008 -15.9902 16.0195v346.32c0.00292969 11.959 9.0166 25.2686 20.1201 29.71l151.83 52.8105c6.43945 2.08984 13.1201 3.13965 19.8096 3.13965
|
||||
c5.73242 -0.00195312 14.8008 -1.47168 20.2402 -3.28027l172 -60.7197h0.00976562l170.05 62.8398c1.98047 0.790039 4 1.16016 5.95996 1.16016zM224 357.58v-285.97l128 -45.1904v285.97zM48 29.9502l127.36 47.0801l0.639648 0.229492v286.2l-128 -44.5303v-288.979z
|
||||
M528 65.0801v288.97l-127.36 -47.0693l-0.639648 -0.240234v-286.19z" />
|
||||
<glyph glyph-name="comment-alt" unicode=""
|
||||
d="M448 448c35.2998 0 64 -28.7002 64 -64v-288c0 -35.2998 -28.7002 -64 -64 -64h-144l-124.9 -93.5996c-2.19922 -1.7002 -4.69922 -2.40039 -7.09961 -2.40039c-6.2002 0 -12 4.90039 -12 12v84h-96c-35.2998 0 -64 28.7002 -64 64v288c0 35.2998 28.7002 64 64 64h384z
|
||||
M464 96v288c0 8.7998 -7.2002 16 -16 16h-384c-8.7998 0 -16 -7.2002 -16 -16v-288c0 -8.7998 7.2002 -16 16 -16h144v-60l67.2002 50.4004l12.7998 9.59961h160c8.7998 0 16 7.2002 16 16z" />
|
||||
<glyph glyph-name="pause-circle" unicode=""
|
||||
d="M256 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM256 -8c110.5 0 200 89.5 200 200s-89.5 200 -200 200s-200 -89.5 -200 -200s89.5 -200 200 -200zM352 272v-160c0 -8.7998 -7.2002 -16 -16 -16h-48
|
||||
c-8.7998 0 -16 7.2002 -16 16v160c0 8.7998 7.2002 16 16 16h48c8.7998 0 16 -7.2002 16 -16zM240 272v-160c0 -8.7998 -7.2002 -16 -16 -16h-48c-8.7998 0 -16 7.2002 -16 16v160c0 8.7998 7.2002 16 16 16h48c8.7998 0 16 -7.2002 16 -16z" />
|
||||
<glyph glyph-name="stop-circle" unicode=""
|
||||
d="M504 192c0 -137 -111 -248 -248 -248s-248 111 -248 248s111 248 248 248s248 -111 248 -248zM56 192c0 -110.5 89.5 -200 200 -200s200 89.5 200 200s-89.5 200 -200 200s-200 -89.5 -200 -200zM352 272v-160c0 -8.7998 -7.2002 -16 -16 -16h-160
|
||||
c-8.7998 0 -16 7.2002 -16 16v160c0 8.7998 7.2002 16 16 16h160c8.7998 0 16 -7.2002 16 -16z" />
|
||||
<glyph glyph-name="handshake" unicode="" horiz-adv-x="640"
|
||||
d="M519.2 320.1h120.8v-255.699h-64c-17.5 0 -31.7998 14.1992 -31.9004 31.6992h-57.8994c-1.7998 -8.19922 -5.2998 -16.0996 -10.9004 -23l-26.2002 -32.2998c-15.7998 -19.3994 -41.8994 -25.5 -64 -16.7998c-13.5 -16.5996 -30.5996 -24 -48.7998 -24
|
||||
c-15.0996 0 -28.5996 5.09961 -41.0996 15.9004c-31.7998 -21.9004 -74.7002 -21.3008 -105.601 3.7998l-84.5996 76.3994h-9.09961c-0.100586 -17.5 -14.3008 -31.6992 -31.9004 -31.6992h-64v255.699h118l47.5996 47.6006c10.5 10.3994 24.8008 16.2998 39.6006 16.2998
|
||||
h226.8v0c12.7812 0 30.5225 -7.30273 39.5996 -16.2998zM48 96.4004c8.7998 0 16 7.09961 16 16c0 8.7998 -7.2002 16 -16 16s-16 -7.2002 -16 -16c0 -8.80078 7.2002 -16 16 -16zM438 103.3c2.7002 3.40039 2.2002 8.5 -1.2002 11.2998l-108.2 87.8008l-8.19922 -7.5
|
||||
c-40.3008 -36.8008 -86.7002 -11.8008 -101.5 4.39941c-26.7002 29 -25 74.4004 4.39941 101.3l38.7002 35.5h-56.7002c-2 -0.799805 -3.7002 -1.5 -5.7002 -2.2998l-61.6992 -61.5996h-41.9004v-128.101h27.7002l97.2998 -88
|
||||
c16.0996 -13.0996 41.4004 -10.5 55.2998 6.60059l15.6006 19.2002l36.7998 -31.5c3 -2.40039 12 -4.90039 18 2.39941l30 36.5l23.8994 -19.3994c3.5 -2.80078 8.5 -2.2002 11.3008 1.19922zM544 144.1v128h-44.7002l-61.7002 61.6006
|
||||
c-1.39941 1.5 -3.39941 2.2998 -5.5 2.2998l-83.6992 -0.200195c-10 0 -19.6006 -3.7002 -27 -10.5l-65.6006 -60.0996c-9.7002 -8.7998 -10.5 -24 -1.2002 -33.9004c8.90039 -9.39941 25.1006 -8.7002 34.6006 0l55.2002 50.6006c6.5 5.89941 16.5996 5.5 22.5996 -1
|
||||
l10.9004 -11.7002c6 -6.5 5.5 -16.6006 -1 -22.6006l-12.5 -11.3994l102.699 -83.4004c2.80078 -2.2998 5.40039 -4.89941 7.7002 -7.7002h69.2002zM592 96.4004c8.7998 0 16 7.09961 16 16c0 8.7998 -7.2002 16 -16 16s-16 -7.2002 -16 -16c0 -8.80078 7.2002 -16 16 -16z
|
||||
" />
|
||||
<glyph glyph-name="envelope-open" unicode=""
|
||||
d="M494.586 283.484c9.6123 -7.94824 17.4141 -24.5205 17.4141 -36.9932v-262.491c0 -26.5098 -21.4902 -48 -48 -48h-416c-26.5098 0 -48 21.4902 -48 48v262.515c0 12.5166 7.84668 29.1279 17.5146 37.0771c4.08008 3.35449 110.688 89.0996 135.15 108.549
|
||||
c22.6992 18.1426 60.1299 55.8594 103.335 55.8594c43.4365 0 81.2314 -38.1914 103.335 -55.8594c23.5283 -18.707 130.554 -104.773 135.251 -108.656zM464 -10v253.632v0.00488281c0 1.5791 -0.996094 3.66602 -2.22363 4.6582
|
||||
c-15.8633 12.8232 -108.793 87.5752 -132.366 106.316c-17.5527 14.0195 -49.7168 45.3887 -73.4102 45.3887c-23.6016 0 -55.2451 -30.8799 -73.4102 -45.3887c-23.5713 -18.7393 -116.494 -93.4795 -132.364 -106.293
|
||||
c-1.40918 -1.13965 -2.22559 -2.85254 -2.22559 -4.66504v-253.653c0 -3.31152 2.68848 -6 6 -6h404c3.31152 0 6 2.68848 6 6zM432.009 177.704c4.24902 -5.15918 3.46484 -12.7949 -1.74512 -16.9814c-28.9746 -23.2822 -59.2734 -47.5967 -70.9287 -56.8623
|
||||
c-22.6992 -18.1436 -60.1299 -55.8604 -103.335 -55.8604c-43.4521 0 -81.2871 38.2373 -103.335 55.8604c-11.2793 8.9668 -41.7441 33.4131 -70.9268 56.8643c-5.20996 4.1875 -5.99316 11.8223 -1.74512 16.9814l15.2578 18.5283
|
||||
c4.17773 5.07227 11.6572 5.84277 16.7793 1.72559c28.6182 -23.001 58.5654 -47.0352 70.5596 -56.5713c17.5527 -14.0195 49.7168 -45.3887 73.4102 -45.3887c23.6016 0 55.2461 30.8799 73.4102 45.3887c11.9941 9.53516 41.9434 33.5703 70.5625 56.5684
|
||||
c5.12207 4.11621 12.6016 3.3457 16.7783 -1.72656z" />
|
||||
<glyph glyph-name="address-book" unicode="" horiz-adv-x="448"
|
||||
d="M436 288h-20v-64h20c6.59961 0 12 -5.40039 12 -12v-40c0 -6.59961 -5.40039 -12 -12 -12h-20v-64h20c6.59961 0 12 -5.40039 12 -12v-40c0 -6.59961 -5.40039 -12 -12 -12h-20v-48c0 -26.5 -21.5 -48 -48 -48h-320c-26.5 0 -48 21.5 -48 48v416c0 26.5 21.5 48 48 48
|
||||
h320c26.5 0 48 -21.5 48 -48v-48h20c6.59961 0 12 -5.40039 12 -12v-40c0 -6.59961 -5.40039 -12 -12 -12zM368 -16v416h-320v-416h320zM208 192c-35.2998 0 -64 28.7002 -64 64s28.7002 64 64 64s64 -28.7002 64 -64s-28.7002 -64 -64 -64zM118.4 64
|
||||
c-12.4004 0 -22.4004 8.59961 -22.4004 19.2002v19.2002c0 31.7998 30.0996 57.5996 67.2002 57.5996c11.3994 0 17.8994 -8 44.7998 -8c26.0996 0 34 8 44.7998 8c37.1006 0 67.2002 -25.7998 67.2002 -57.5996v-19.2002c0 -10.6006 -10 -19.2002 -22.4004 -19.2002
|
||||
h-179.199z" />
|
||||
<glyph glyph-name="address-card" unicode="" horiz-adv-x="576"
|
||||
d="M528 416c26.5 0 48 -21.5 48 -48v-352c0 -26.5 -21.5 -48 -48 -48h-480c-26.5 0 -48 21.5 -48 48v352c0 26.5 21.5 48 48 48h480zM528 16v352h-480v-352h480zM208 192c-35.2998 0 -64 28.7002 -64 64s28.7002 64 64 64s64 -28.7002 64 -64s-28.7002 -64 -64 -64z
|
||||
M118.4 64c-12.4004 0 -22.4004 8.59961 -22.4004 19.2002v19.2002c0 31.7998 30.0996 57.5996 67.2002 57.5996c11.3994 0 17.8994 -8 44.7998 -8c26.0996 0 34 8 44.7998 8c37.1006 0 67.2002 -25.7998 67.2002 -57.5996v-19.2002
|
||||
c0 -10.6006 -10 -19.2002 -22.4004 -19.2002h-179.199zM360 128c-4.40039 0 -8 3.59961 -8 8v16c0 4.40039 3.59961 8 8 8h112c4.40039 0 8 -3.59961 8 -8v-16c0 -4.40039 -3.59961 -8 -8 -8h-112zM360 192c-4.40039 0 -8 3.59961 -8 8v16c0 4.40039 3.59961 8 8 8h112
|
||||
c4.40039 0 8 -3.59961 8 -8v-16c0 -4.40039 -3.59961 -8 -8 -8h-112zM360 256c-4.40039 0 -8 3.59961 -8 8v16c0 4.40039 3.59961 8 8 8h112c4.40039 0 8 -3.59961 8 -8v-16c0 -4.40039 -3.59961 -8 -8 -8h-112z" />
|
||||
<glyph glyph-name="user-circle" unicode="" horiz-adv-x="496"
|
||||
d="M248 344c53 0 96 -43 96 -96s-43 -96 -96 -96s-96 43 -96 96s43 96 96 96zM248 200c26.5 0 48 21.5 48 48s-21.5 48 -48 48s-48 -21.5 -48 -48s21.5 -48 48 -48zM248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8
|
||||
c49.7002 0 95.0996 18.2998 130.1 48.4004c-14.8994 23 -40.3994 38.5 -69.5996 39.5c-20.7998 -6.5 -40.5996 -9.60059 -60.5 -9.60059s-39.7002 3.2002 -60.5 9.60059c-29.2002 -0.900391 -54.7002 -16.5 -69.5996 -39.5c35 -30.1006 80.3994 -48.4004 130.1 -48.4004z
|
||||
M410.7 76.0996c23.3994 32.7002 37.2998 72.7002 37.2998 115.9c0 110.3 -89.7002 200 -200 200s-200 -89.7002 -200 -200c0 -43.2002 13.9004 -83.2002 37.2998 -115.9c24.5 31.4004 62.2002 51.9004 105.101 51.9004c10.1992 0 26.0996 -9.59961 57.5996 -9.59961
|
||||
c31.5996 0 47.4004 9.59961 57.5996 9.59961c43 0 80.7002 -20.5 105.101 -51.9004z" />
|
||||
<glyph glyph-name="id-badge" unicode="" horiz-adv-x="384"
|
||||
d="M336 448c26.5 0 48 -21.5 48 -48v-416c0 -26.5 -21.5 -48 -48 -48h-288c-26.5 0 -48 21.5 -48 48v416c0 26.5 21.5 48 48 48h288zM336 -16v416h-288v-416h288zM144 336c-8.7998 0 -16 7.2002 -16 16s7.2002 16 16 16h96c8.7998 0 16 -7.2002 16 -16s-7.2002 -16 -16 -16
|
||||
h-96zM192 160c-35.2998 0 -64 28.7002 -64 64s28.7002 64 64 64s64 -28.7002 64 -64s-28.7002 -64 -64 -64zM102.4 32c-12.4004 0 -22.4004 8.59961 -22.4004 19.2002v19.2002c0 31.7998 30.0996 57.5996 67.2002 57.5996c11.3994 0 17.8994 -8 44.7998 -8
|
||||
c26.0996 0 34 8 44.7998 8c37.1006 0 67.2002 -25.7998 67.2002 -57.5996v-19.2002c0 -10.6006 -10 -19.2002 -22.4004 -19.2002h-179.199z" />
|
||||
<glyph glyph-name="id-card" unicode="" horiz-adv-x="576"
|
||||
d="M528 416c26.5 0 48 -21.5 48 -48v-352c0 -26.5 -21.5 -48 -48 -48h-480c-26.5 0 -48 21.5 -48 48v352c0 26.5 21.5 48 48 48h480zM528 16v288h-480v-288h32.7998c-1 4.5 -0.799805 -3.59961 -0.799805 22.4004c0 31.7998 30.0996 57.5996 67.2002 57.5996
|
||||
c11.3994 0 17.8994 -8 44.7998 -8c26.0996 0 34 8 44.7998 8c37.1006 0 67.2002 -25.7998 67.2002 -57.5996c0 -26 0.0996094 -17.9004 -0.799805 -22.4004h224.8zM360 96c-4.40039 0 -8 3.59961 -8 8v16c0 4.40039 3.59961 8 8 8h112c4.40039 0 8 -3.59961 8 -8v-16
|
||||
c0 -4.40039 -3.59961 -8 -8 -8h-112zM360 160c-4.40039 0 -8 3.59961 -8 8v16c0 4.40039 3.59961 8 8 8h112c4.40039 0 8 -3.59961 8 -8v-16c0 -4.40039 -3.59961 -8 -8 -8h-112zM360 224c-4.40039 0 -8 3.59961 -8 8v16c0 4.40039 3.59961 8 8 8h112
|
||||
c4.40039 0 8 -3.59961 8 -8v-16c0 -4.40039 -3.59961 -8 -8 -8h-112zM192 128c-35.2998 0 -64 28.7002 -64 64s28.7002 64 64 64s64 -28.7002 64 -64s-28.7002 -64 -64 -64z" />
|
||||
<glyph glyph-name="window-maximize" unicode=""
|
||||
d="M464 416c26.5 0 48 -21.5 48 -48v-352c0 -26.5 -21.5 -48 -48 -48h-416c-26.5 0 -48 21.5 -48 48v352c0 26.5 21.5 48 48 48h416zM464 22v234h-416v-234c0 -3.2998 2.7002 -6 6 -6h404c3.2998 0 6 2.7002 6 6z" />
|
||||
<glyph glyph-name="window-minimize" unicode=""
|
||||
d="M480 -32h-448c-17.7002 0 -32 14.2998 -32 32s14.2998 32 32 32h448c17.7002 0 32 -14.2998 32 -32s-14.2998 -32 -32 -32z" />
|
||||
<glyph glyph-name="window-restore" unicode=""
|
||||
d="M464 448c26.5 0 48 -21.5 48 -48v-320c0 -26.5 -21.5 -48 -48 -48h-48v-48c0 -26.5 -21.5 -48 -48 -48h-320c-26.5 0 -48 21.5 -48 48v320c0 26.5 21.5 48 48 48h48v48c0 26.5 21.5 48 48 48h320zM368 -16v208h-320v-208h320zM464 80v320h-320v-48h224
|
||||
c26.5 0 48 -21.5 48 -48v-224h48z" />
|
||||
<glyph glyph-name="snowflake" unicode="" horiz-adv-x="448"
|
||||
d="M440.1 92.7998c7.60059 -4.39941 10.1006 -14.2002 5.5 -21.7002l-7.89941 -13.8994c-4.40039 -7.7002 -14 -10.2998 -21.5 -5.90039l-39.2002 23l9.09961 -34.7002c2.30078 -8.5 -2.69922 -17.2998 -11.0996 -19.5996l-15.2002 -4.09961
|
||||
c-8.39941 -2.30078 -17.0996 2.7998 -19.2998 11.2998l-21.2998 81l-71.9004 42.2002v-84.5l58.2998 -59.3008c6.10059 -6.19922 6.10059 -16.3994 0 -22.5996l-11.0996 -11.2998c-6.09961 -6.2002 -16.0996 -6.2002 -22.2002 0l-24.8994 25.3994v-46.0996
|
||||
c0 -8.7998 -7 -16 -15.7002 -16h-15.7002c-8.7002 0 -15.7002 7.2002 -15.7002 16v45.9004l-24.8994 -25.4004c-6.10059 -6.2002 -16.1006 -6.2002 -22.2002 0l-11.1006 11.2998c-6.09961 6.2002 -6.09961 16.4004 0 22.6006l58.3008 59.2998v84.5l-71.9004 -42.2002
|
||||
l-21.2998 -81c-2.2998 -8.5 -10.9004 -13.5996 -19.2998 -11.2998l-15.2002 4.09961c-8.40039 2.2998 -13.2998 11.1006 -11.1006 19.6006l9.10059 34.6992l-39.2002 -23c-7.5 -4.39941 -17.2002 -1.7998 -21.5 5.90039l-7.90039 13.9004
|
||||
c-4.2998 7.69922 -1.69922 17.5 5.80078 21.8994l39.1992 23l-34.0996 9.2998c-8.40039 2.30078 -13.2998 11.1006 -11.0996 19.6006l4.09961 15.5c2.2998 8.5 10.9004 13.5996 19.2998 11.2998l79.7002 -21.7002l71.9004 42.2002l-71.9004 42.2002l-79.7002 -21.7002
|
||||
c-8.39941 -2.2998 -17.0996 2.7998 -19.2998 11.2998l-4.09961 15.5c-2.30078 8.5 2.69922 17.2998 11.0996 19.6006l34.0996 9.09961l-39.1992 23c-7.60059 4.5 -10.1006 14.2002 -5.80078 21.9004l7.90039 13.8994c4.40039 7.7002 14 10.2998 21.5 5.90039l39.2002 -23
|
||||
l-9.10059 34.7002c-2.2998 8.5 2.7002 17.2998 11.1006 19.5996l15.2002 4.09961c8.39941 2.30078 17.0996 -2.7998 19.2998 -11.2998l21.2998 -81l71.9004 -42.2002v84.5l-58.3008 59.3008c-6.09961 6.19922 -6.09961 16.3994 0 22.5996l11.5 11.2998
|
||||
c6.10059 6.2002 16.1006 6.2002 22.2002 0l24.9004 -25.3994v46.0996c0 8.7998 7 16 15.7002 16h15.6992c8.7002 0 15.7002 -7.2002 15.7002 -16v-45.9004l24.9004 25.4004c6.09961 6.2002 16.0996 6.2002 22.2002 0l11.0996 -11.2998
|
||||
c6.09961 -6.2002 6.09961 -16.4004 0 -22.6006l-58.2998 -59.2998v-84.5l71.8994 42.2002l21.3008 81c2.2998 8.5 10.8994 13.5996 19.2998 11.2998l15.2002 -4.09961c8.39941 -2.2998 13.2998 -11.1006 11.0996 -19.6006l-9.09961 -34.6992l39.1992 23
|
||||
c7.5 4.39941 17.2002 1.7998 21.5 -5.90039l7.90039 -13.9004c4.2998 -7.69922 1.7002 -17.5 -5.7998 -21.8994l-39.2002 -23l34.0996 -9.2998c8.40039 -2.30078 13.3008 -11.1006 11.1006 -19.6006l-4.10059 -15.5c-2.2998 -8.5 -10.8994 -13.5996 -19.2998 -11.2998
|
||||
l-79.7002 21.7002l-71.8994 -42.2002l71.7998 -42.2002l79.7002 21.7002c8.39941 2.2998 17.0996 -2.7998 19.2998 -11.2998l4.09961 -15.5c2.30078 -8.5 -2.69922 -17.2998 -11.0996 -19.6006l-34.0996 -9.2998z" />
|
||||
<glyph glyph-name="trash-alt" unicode="" horiz-adv-x="448"
|
||||
d="M268 32c-6.62402 0 -12 5.37598 -12 12v216c0 6.62402 5.37598 12 12 12h24c6.62402 0 12 -5.37598 12 -12v-216c0 -6.62402 -5.37598 -12 -12 -12h-24zM432 368c8.83203 0 16 -7.16797 16 -16v-16c0 -8.83203 -7.16797 -16 -16 -16h-16v-336
|
||||
c0 -26.4961 -21.5039 -48 -48 -48h-288c-26.4961 0 -48 21.5039 -48 48v336h-16c-8.83203 0 -16 7.16797 -16 16v16c0 8.83203 7.16797 16 16 16h82.4102l34.0195 56.7002c7.71875 12.8613 26.1572 23.2998 41.1572 23.2998h0.00292969h100.82h0.0224609
|
||||
c15 0 33.4385 -10.4385 41.1572 -23.2998l34 -56.7002h82.4102zM171.84 397.09l-17.4502 -29.0898h139.221l-17.46 29.0898c-0.96582 1.60645 -3.26953 2.91016 -5.14355 2.91016h-0.00683594h-94h-0.0166016c-1.87402 0 -4.17871 -1.30371 -5.14355 -2.91016zM368 -16v336
|
||||
h-288v-336h288zM156 32c-6.62402 0 -12 5.37598 -12 12v216c0 6.62402 5.37598 12 12 12h24c6.62402 0 12 -5.37598 12 -12v-216c0 -6.62402 -5.37598 -12 -12 -12h-24z" />
|
||||
<glyph glyph-name="images" unicode="" horiz-adv-x="576"
|
||||
d="M480 32v-16c0 -26.5098 -21.4902 -48 -48 -48h-384c-26.5098 0 -48 21.4902 -48 48v256c0 26.5098 21.4902 48 48 48h16v-48h-10c-3.31152 0 -6 -2.68848 -6 -6v-244c0 -3.31152 2.68848 -6 6 -6h372c3.31152 0 6 2.68848 6 6v10h48zM522 368h-372
|
||||
c-3.31152 0 -6 -2.68848 -6 -6v-244c0 -3.31152 2.68848 -6 6 -6h372c3.31152 0 6 2.68848 6 6v244c0 3.31152 -2.68848 6 -6 6zM528 416c26.5098 0 48 -21.4902 48 -48v-256c0 -26.5098 -21.4902 -48 -48 -48h-384c-26.5098 0 -48 21.4902 -48 48v256
|
||||
c0 26.5098 21.4902 48 48 48h384zM264 304c0 -22.0908 -17.9092 -40 -40 -40s-40 17.9092 -40 40s17.9092 40 40 40s40 -17.9092 40 -40zM192 208l39.5146 39.5146c4.68652 4.68652 12.2842 4.68652 16.9717 0l39.5137 -39.5146l103.515 103.515
|
||||
c4.68652 4.68652 12.2842 4.68652 16.9717 0l71.5137 -71.5146v-80h-288v48z" />
|
||||
<glyph glyph-name="clipboard" unicode="" horiz-adv-x="384"
|
||||
d="M336 384c26.5 0 48 -21.5 48 -48v-352c0 -26.5 -21.5 -48 -48 -48h-288c-26.5 0 -48 21.5 -48 48v352c0 26.5 21.5 48 48 48h80c0 35.2998 28.7002 64 64 64s64 -28.7002 64 -64h80zM192 408c-13.2998 0 -24 -10.7002 -24 -24s10.7002 -24 24 -24s24 10.7002 24 24
|
||||
s-10.7002 24 -24 24zM336 -10v340c0 3.2998 -2.7002 6 -6 6h-42v-36c0 -6.59961 -5.40039 -12 -12 -12h-168c-6.59961 0 -12 5.40039 -12 12v36h-42c-3.2998 0 -6 -2.7002 -6 -6v-340c0 -3.2998 2.7002 -6 6 -6h276c3.2998 0 6 2.7002 6 6z" />
|
||||
<glyph glyph-name="arrow-alt-circle-down" unicode=""
|
||||
d="M256 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM256 -8c110.5 0 200 89.5 200 200s-89.5 200 -200 200s-200 -89.5 -200 -200s89.5 -200 200 -200zM224 308c0 6.59961 5.40039 12 12 12h40c6.59961 0 12 -5.40039 12 -12v-116
|
||||
h67c10.7002 0 16.0996 -12.9004 8.5 -20.5l-99 -99c-4.7002 -4.7002 -12.2998 -4.7002 -17 0l-99 99c-7.5 7.59961 -2.2002 20.5 8.5 20.5h67v116z" />
|
||||
<glyph glyph-name="arrow-alt-circle-left" unicode=""
|
||||
d="M8 192c0 137 111 248 248 248s248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248zM456 192c0 110.5 -89.5 200 -200 200s-200 -89.5 -200 -200s89.5 -200 200 -200s200 89.5 200 200zM384 212v-40c0 -6.59961 -5.40039 -12 -12 -12h-116v-67
|
||||
c0 -10.7002 -12.9004 -16 -20.5 -8.5l-99 99c-4.7002 4.7002 -4.7002 12.2998 0 17l99 99c7.59961 7.59961 20.5 2.2002 20.5 -8.5v-67h116c6.59961 0 12 -5.40039 12 -12z" />
|
||||
<glyph glyph-name="arrow-alt-circle-right" unicode=""
|
||||
d="M504 192c0 -137 -111 -248 -248 -248s-248 111 -248 248s111 248 248 248s248 -111 248 -248zM56 192c0 -110.5 89.5 -200 200 -200s200 89.5 200 200s-89.5 200 -200 200s-200 -89.5 -200 -200zM128 172v40c0 6.59961 5.40039 12 12 12h116v67
|
||||
c0 10.7002 12.9004 16 20.5 8.5l99 -99c4.7002 -4.7002 4.7002 -12.2998 0 -17l-99 -99c-7.59961 -7.59961 -20.5 -2.2002 -20.5 8.5v67h-116c-6.59961 0 -12 5.40039 -12 12z" />
|
||||
<glyph glyph-name="arrow-alt-circle-up" unicode=""
|
||||
d="M256 -56c-137 0 -248 111 -248 248s111 248 248 248s248 -111 248 -248s-111 -248 -248 -248zM256 392c-110.5 0 -200 -89.5 -200 -200s89.5 -200 200 -200s200 89.5 200 200s-89.5 200 -200 200zM276 64h-40c-6.59961 0 -12 5.40039 -12 12v116h-67
|
||||
c-10.7002 0 -16 12.9004 -8.5 20.5l99 99c4.7002 4.7002 12.2998 4.7002 17 0l99 -99c7.59961 -7.59961 2.2002 -20.5 -8.5 -20.5h-67v-116c0 -6.59961 -5.40039 -12 -12 -12z" />
|
||||
<glyph glyph-name="gem" unicode="" horiz-adv-x="576"
|
||||
d="M464 448c4.09961 0 7.7998 -2 10.0996 -5.40039l99.9004 -147.199c2.90039 -4.40039 2.59961 -10.1006 -0.700195 -14.2002l-276 -340.8c-4.7998 -5.90039 -13.7998 -5.90039 -18.5996 0l-276 340.8c-3.2998 4 -3.60059 9.7998 -0.700195 14.2002l100 147.199
|
||||
c2.2002 3.40039 6 5.40039 10 5.40039h352zM444.7 400h-56.7998l51.6992 -96h68.4004zM242.6 400l-51.5996 -96h194l-51.7002 96h-90.7002zM131.3 400l-63.2998 -96h68.4004l51.6992 96h-56.7998zM88.2998 256l119.7 -160l-68.2998 160h-51.4004zM191.2 256l96.7998 -243.3
|
||||
l96.7998 243.3h-193.6zM368 96l119.6 160h-51.3994z" />
|
||||
<glyph glyph-name="money-bill-alt" unicode="" horiz-adv-x="640"
|
||||
d="M320 304c53.0195 0 96 -50.1396 96 -112c0 -61.8701 -43 -112 -96 -112c-53.0195 0 -96 50.1504 -96 112c0 61.8604 42.9805 112 96 112zM360 136v16c0 4.41992 -3.58008 8 -8 8h-16v88c0 4.41992 -3.58008 8 -8 8h-13.5801h-0.000976562
|
||||
c-4.01074 0 -9.97266 -1.80566 -13.3086 -4.03027l-15.3301 -10.2197c-1.96777 -1.30957 -3.56445 -4.29004 -3.56445 -6.65332c0 -1.33691 0.601562 -3.32422 1.34375 -4.43652l8.88086 -13.3105c1.30859 -1.9668 4.29004 -3.56445 6.65332 -3.56445
|
||||
c1.33691 0 3.32422 0.602539 4.43652 1.34473l0.469727 0.310547v-55.4404h-16c-4.41992 0 -8 -3.58008 -8 -8v-16c0 -4.41992 3.58008 -8 8 -8h64c4.41992 0 8 3.58008 8 8zM608 384c17.6699 0 32 -14.3301 32 -32v-320c0 -17.6699 -14.3301 -32 -32 -32h-576
|
||||
c-17.6699 0 -32 14.3301 -32 32v320c0 17.6699 14.3301 32 32 32h576zM592 112v160c-35.3496 0 -64 28.6504 -64 64h-416c0 -35.3496 -28.6504 -64 -64 -64v-160c35.3496 0 64 -28.6504 64 -64h416c0 35.3496 28.6504 64 64 64z" />
|
||||
<glyph glyph-name="window-close" unicode=""
|
||||
d="M464 416c26.5 0 48 -21.5 48 -48v-352c0 -26.5 -21.5 -48 -48 -48h-416c-26.5 0 -48 21.5 -48 48v352c0 26.5 21.5 48 48 48h416zM464 22v340c0 3.2998 -2.7002 6 -6 6h-404c-3.2998 0 -6 -2.7002 -6 -6v-340c0 -3.2998 2.7002 -6 6 -6h404c3.2998 0 6 2.7002 6 6z
|
||||
M356.5 253.4l-61.4004 -61.4004l61.4004 -61.4004c4.59961 -4.59961 4.59961 -12.0996 0 -16.7998l-22.2998 -22.2998c-4.60059 -4.59961 -12.1006 -4.59961 -16.7998 0l-61.4004 61.4004l-61.4004 -61.4004c-4.59961 -4.59961 -12.0996 -4.59961 -16.7998 0
|
||||
l-22.2998 22.2998c-4.59961 4.60059 -4.59961 12.1006 0 16.7998l61.4004 61.4004l-61.4004 61.4004c-4.59961 4.59961 -4.59961 12.0996 0 16.7998l22.2998 22.2998c4.60059 4.59961 12.1006 4.59961 16.7998 0l61.4004 -61.4004l61.4004 61.4004
|
||||
c4.59961 4.59961 12.0996 4.59961 16.7998 0l22.2998 -22.2998c4.7002 -4.60059 4.7002 -12.1006 0 -16.7998z" />
|
||||
<glyph glyph-name="comment-dots" unicode=""
|
||||
d="M144 240c17.7002 0 32 -14.2998 32 -32s-14.2998 -32 -32 -32s-32 14.2998 -32 32s14.2998 32 32 32zM256 240c17.7002 0 32 -14.2998 32 -32s-14.2998 -32 -32 -32s-32 14.2998 -32 32s14.2998 32 32 32zM368 240c17.7002 0 32 -14.2998 32 -32s-14.2998 -32 -32 -32
|
||||
s-32 14.2998 -32 32s14.2998 32 32 32zM256 416c141.4 0 256 -93.0996 256 -208s-114.6 -208 -256 -208c-32.7998 0 -64 5.2002 -92.9004 14.2998c-29.0996 -20.5996 -77.5996 -46.2998 -139.1 -46.2998c-9.59961 0 -18.2998 5.7002 -22.0996 14.5
|
||||
c-3.80078 8.7998 -2 19 4.59961 26c0.5 0.400391 31.5 33.7998 46.4004 73.2002c-33 35.0996 -52.9004 78.7002 -52.9004 126.3c0 114.9 114.6 208 256 208zM256 48c114.7 0 208 71.7998 208 160s-93.2998 160 -208 160s-208 -71.7998 -208 -160
|
||||
c0 -42.2002 21.7002 -74.0996 39.7998 -93.4004l20.6006 -21.7998l-10.6006 -28.0996c-5.5 -14.5 -12.5996 -28.1006 -19.8994 -40.2002c23.5996 7.59961 43.1992 18.9004 57.5 29l19.5 13.7998l22.6992 -7.2002c25.3008 -8 51.7002 -12.0996 78.4004 -12.0996z" />
|
||||
<glyph glyph-name="smile-wink" unicode="" horiz-adv-x="496"
|
||||
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8c110.3 0 200 89.7002 200 200s-89.7002 200 -200 200s-200 -89.7002 -200 -200s89.7002 -200 200 -200zM365.8 138.4c10.2002 -8.5 11.6006 -23.6006 3.10059 -33.8008
|
||||
c-30 -36 -74.1006 -56.5996 -120.9 -56.5996s-90.9004 20.5996 -120.9 56.5996c-8.39941 10.2002 -7.09961 25.3008 3.10059 33.8008c10.0996 8.39941 25.2998 7.09961 33.7998 -3.10059c20.7998 -25.0996 51.5 -39.3994 84 -39.3994s63.2002 14.3994 84 39.3994
|
||||
c8.5 10.2002 23.5996 11.6006 33.7998 3.10059zM168 208c-17.7002 0 -32 14.2998 -32 32s14.2998 32 32 32s32 -14.2998 32 -32s-14.2998 -32 -32 -32zM328 268c25.7002 0 55.9004 -16.9004 59.7002 -42.0996c1.7998 -11.1006 -11.2998 -18.2002 -19.7998 -10.8008l-9.5 8.5
|
||||
c-14.8008 13.2002 -46.2002 13.2002 -61 0l-9.5 -8.5c-8.30078 -7.39941 -21.5 -0.399414 -19.8008 10.8008c4 25.1992 34.2002 42.0996 59.9004 42.0996z" />
|
||||
<glyph glyph-name="angry" unicode="" horiz-adv-x="496"
|
||||
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8c110.3 0 200 89.7002 200 200s-89.7002 200 -200 200s-200 -89.7002 -200 -200s89.7002 -200 200 -200zM248 136c33.5996 0 65.2002 -14.7998 86.7998 -40.5996
|
||||
c8.40039 -10.2002 7.10059 -25.3008 -3.09961 -33.8008c-10.6006 -8.89941 -25.7002 -6.69922 -33.7998 3c-24.8008 29.7002 -75 29.7002 -99.8008 0c-8.5 -10.1992 -23.5996 -11.5 -33.7998 -3s-11.5996 23.6006 -3.09961 33.8008
|
||||
c21.5996 25.7998 53.2002 40.5996 86.7998 40.5996zM200 208c0 -17.7002 -14.2998 -32.0996 -32 -32.0996s-32 14.2998 -32 32c0 6.19922 2.2002 11.6992 5.2998 16.5996l-28.2002 8.5c-12.6992 3.7998 -19.8994 17.2002 -16.0996 29.9004
|
||||
c3.7998 12.6992 17.0996 20 29.9004 16.0996l80 -24c12.6992 -3.7998 19.8994 -17.2002 16.0996 -29.9004c-3.09961 -10.3994 -12.7002 -17.0996 -23 -17.0996zM399 262.9c3.7998 -12.7002 -3.40039 -26.1006 -16.0996 -29.8008l-28.2002 -8.5
|
||||
c3.09961 -4.89941 5.2998 -10.3994 5.2998 -16.5996c0 -17.7002 -14.2998 -32 -32 -32s-32 14.2998 -32 32c-10.2998 0 -19.9004 6.7002 -23 17.0996c-3.7998 12.7002 3.40039 26.1006 16.0996 29.9004l80 24c12.8008 3.7998 26.1006 -3.40039 29.9004 -16.0996z" />
|
||||
<glyph glyph-name="dizzy" unicode="" horiz-adv-x="496"
|
||||
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8c110.3 0 200 89.7002 200 200s-89.7002 200 -200 200s-200 -89.7002 -200 -200s89.7002 -200 200 -200zM214.2 209.9
|
||||
c-7.90039 -7.90039 -20.5 -7.90039 -28.4004 -0.200195l-17.7998 17.7998l-17.7998 -17.7998c-7.7998 -7.7998 -20.5 -7.7998 -28.2998 0c-7.80078 7.7998 -7.80078 20.5 0 28.2998l17.8994 17.9004l-17.8994 17.8994c-7.80078 7.7998 -7.80078 20.5 0 28.2998
|
||||
c7.7998 7.80078 20.5 7.80078 28.2998 0l17.7998 -17.7998l17.9004 17.9004c7.7998 7.7998 20.5 7.7998 28.2998 0s7.7998 -20.5 0 -28.2998l-17.9004 -17.9004l17.9004 -17.7998c7.7998 -7.7998 7.7998 -20.5 0 -28.2998zM374.2 302.1
|
||||
c7.7002 -7.7998 7.7002 -20.3994 0 -28.1992l-17.9004 -17.9004l17.7998 -18c7.80078 -7.7998 7.80078 -20.5 0 -28.2998c-7.7998 -7.7998 -20.5 -7.7998 -28.2998 0l-17.7998 17.7998l-17.7998 -17.7998c-7.7998 -7.7998 -20.5 -7.7998 -28.2998 0
|
||||
c-7.80078 7.7998 -7.80078 20.5 0 28.2998l17.8994 17.9004l-17.8994 17.8994c-7.80078 7.7998 -7.80078 20.5 0 28.2998c7.7998 7.80078 20.5 7.80078 28.2998 0l17.7998 -17.7998l17.9004 17.7998c7.7998 7.80078 20.5 7.80078 28.2998 0zM248 176
|
||||
c35.2998 0 64 -28.7002 64 -64s-28.7002 -64 -64 -64s-64 28.7002 -64 64s28.7002 64 64 64z" />
|
||||
<glyph glyph-name="flushed" unicode="" horiz-adv-x="496"
|
||||
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8c110.3 0 200 89.7002 200 200s-89.7002 200 -200 200s-200 -89.7002 -200 -200s89.7002 -200 200 -200zM344 304c44.2002 0 80 -35.7998 80 -80s-35.7998 -80 -80 -80
|
||||
s-80 35.7998 -80 80s35.7998 80 80 80zM344 176c26.5 0 48 21.5 48 48s-21.5 48 -48 48s-48 -21.5 -48 -48s21.5 -48 48 -48zM344 248c13.2998 0 24 -10.7002 24 -24s-10.7002 -24 -24 -24s-24 10.7002 -24 24s10.7002 24 24 24zM232 224c0 -44.2002 -35.7998 -80 -80 -80
|
||||
s-80 35.7998 -80 80s35.7998 80 80 80s80 -35.7998 80 -80zM152 176c26.5 0 48 21.5 48 48s-21.5 48 -48 48s-48 -21.5 -48 -48s21.5 -48 48 -48zM152 248c13.2998 0 24 -10.7002 24 -24s-10.7002 -24 -24 -24s-24 10.7002 -24 24s10.7002 24 24 24zM312 104
|
||||
c13.2002 0 24 -10.7998 24 -24s-10.7998 -24 -24 -24h-128c-13.2002 0 -24 10.7998 -24 24s10.7998 24 24 24h128z" />
|
||||
<glyph glyph-name="frown-open" unicode="" horiz-adv-x="496"
|
||||
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8c110.3 0 200 89.7002 200 200s-89.7002 200 -200 200s-200 -89.7002 -200 -200s89.7002 -200 200 -200zM200 240c0 -17.7002 -14.2998 -32 -32 -32s-32 14.2998 -32 32
|
||||
s14.2998 32 32 32s32 -14.2998 32 -32zM328 272c17.7002 0 32 -14.2998 32 -32s-14.2998 -32 -32 -32s-32 14.2998 -32 32s14.2998 32 32 32zM248 160c35.5996 0 88.7998 -21.2998 95.7998 -61.2002c2 -11.7998 -9.09961 -21.5996 -20.5 -18.0996
|
||||
c-31.2002 9.59961 -59.3994 15.2998 -75.2998 15.2998s-44.0996 -5.7002 -75.2998 -15.2998c-11.5 -3.40039 -22.5 6.2998 -20.5 18.0996c7 39.9004 60.2002 61.2002 95.7998 61.2002z" />
|
||||
<glyph glyph-name="grimace" unicode="" horiz-adv-x="496"
|
||||
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8c110.3 0 200 89.7002 200 200s-89.7002 200 -200 200s-200 -89.7002 -200 -200s89.7002 -200 200 -200zM168 208c-17.7002 0 -32 14.2998 -32 32s14.2998 32 32 32
|
||||
s32 -14.2998 32 -32s-14.2998 -32 -32 -32zM328 208c-17.7002 0 -32 14.2998 -32 32s14.2998 32 32 32s32 -14.2998 32 -32s-14.2998 -32 -32 -32zM344 192c26.5 0 48 -21.5 48 -48v-32c0 -26.5 -21.5 -48 -48 -48h-192c-26.5 0 -48 21.5 -48 48v32c0 26.5 21.5 48 48 48
|
||||
h192zM176 96v24h-40v-8c0 -8.7998 7.2002 -16 16 -16h24zM176 136v24h-24c-8.7998 0 -16 -7.2002 -16 -16v-8h40zM240 96v24h-48v-24h48zM240 136v24h-48v-24h48zM304 96v24h-48v-24h48zM304 136v24h-48v-24h48zM360 112v8h-40v-24h24c8.7998 0 16 7.2002 16 16zM360 136v8
|
||||
c0 8.7998 -7.2002 16 -16 16h-24v-24h40z" />
|
||||
<glyph glyph-name="grin" unicode="" horiz-adv-x="496"
|
||||
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8c110.3 0 200 89.7002 200 200s-89.7002 200 -200 200s-200 -89.7002 -200 -200s89.7002 -200 200 -200zM353.6 143.4c10 3.09961 19.3008 -5.5 17.7002 -15.3008
|
||||
c-8 -47.0996 -71.2998 -80 -123.3 -80s-115.4 32.9004 -123.3 80c-1.7002 9.90039 7.7998 18.4004 17.7002 15.3008c26 -8.30078 64.3994 -13.1006 105.6 -13.1006s79.7002 4.7998 105.6 13.1006zM168 208c-17.7002 0 -32 14.2998 -32 32s14.2998 32 32 32
|
||||
s32 -14.2998 32 -32s-14.2998 -32 -32 -32zM328 208c-17.7002 0 -32 14.2998 -32 32s14.2998 32 32 32s32 -14.2998 32 -32s-14.2998 -32 -32 -32z" />
|
||||
<glyph glyph-name="grin-alt" unicode="" horiz-adv-x="496"
|
||||
d="M200.3 200c-7.5 -11.4004 -24.5996 -12 -32.7002 0c-12.3994 18.7002 -15.1992 37.2998 -15.6992 56c0.599609 18.7002 3.2998 37.2998 15.6992 56c7.60059 11.4004 24.7002 12 32.7002 0c12.4004 -18.7002 15.2002 -37.2998 15.7002 -56
|
||||
c-0.599609 -18.7002 -3.2998 -37.2998 -15.7002 -56zM328.3 200c-7.5 -11.4004 -24.5996 -12 -32.7002 0c-12.3994 18.7002 -15.1992 37.2998 -15.6992 56c0.599609 18.7002 3.2998 37.2998 15.6992 56c7.60059 11.4004 24.7002 12 32.7002 0
|
||||
c12.4004 -18.7002 15.2002 -37.2998 15.7002 -56c-0.599609 -18.7002 -3.2998 -37.2998 -15.7002 -56zM248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8c110.3 0 200 89.7002 200 200s-89.7002 200 -200 200
|
||||
s-200 -89.7002 -200 -200s89.7002 -200 200 -200zM353.6 143.4c10 3.09961 19.3008 -5.5 17.7002 -15.3008c-8 -47.0996 -71.2998 -80 -123.3 -80s-115.4 32.8008 -123.3 80c-1.7002 10 7.7998 18.4004 17.7002 15.3008c26 -8.30078 64.3994 -13.1006 105.6 -13.1006
|
||||
s79.7002 4.7998 105.6 13.1006z" />
|
||||
<glyph glyph-name="grin-beam" unicode="" horiz-adv-x="496"
|
||||
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8c110.3 0 200 89.7002 200 200s-89.7002 200 -200 200s-200 -89.7002 -200 -200s89.7002 -200 200 -200zM353.6 143.4c10 3.09961 19.3008 -5.5 17.7002 -15.3008
|
||||
c-8 -47.0996 -71.2998 -80 -123.3 -80s-115.4 32.9004 -123.3 80c-1.7002 10 7.89941 18.4004 17.7002 15.3008c26 -8.30078 64.3994 -13.1006 105.6 -13.1006s79.7002 4.7998 105.6 13.1006zM117.7 216.3c-3.60059 1.10059 -6 4.60059 -5.7002 8.2998
|
||||
c3.2998 42.1006 32.2002 71.4004 56 71.4004s52.7002 -29.2998 56 -71.4004c0.299805 -3.7998 -2.09961 -7.19922 -5.7002 -8.2998c-3.09961 -1 -7.2002 0 -9.2998 3.7002l-9.5 17c-7.7002 13.7002 -19.2002 21.5996 -31.5 21.5996s-23.7998 -7.89941 -31.5 -21.5996
|
||||
l-9.5 -17c-1.90039 -3.2002 -5.7998 -4.7998 -9.2998 -3.7002zM277.7 216.3c-3.60059 1.10059 -6 4.60059 -5.7002 8.2998c3.2998 42.1006 32.2002 71.4004 56 71.4004s52.7002 -29.2998 56 -71.4004c0.299805 -3.7998 -2.09961 -7.19922 -5.7002 -8.2998
|
||||
c-3.09961 -1 -7.2002 0 -9.2998 3.7002l-9.5 17c-7.7002 13.7002 -19.2002 21.5996 -31.5 21.5996s-23.7998 -7.89941 -31.5 -21.5996l-9.5 -17c-1.90039 -3.2002 -5.7998 -4.7998 -9.2998 -3.7002z" />
|
||||
<glyph glyph-name="grin-beam-sweat" unicode="" horiz-adv-x="496"
|
||||
d="M440 288c-29.5 0 -53.2998 26.2998 -53.2998 58.7002c0 25 31.7002 75.5 46.2002 97.2998c3.5 5.2998 10.5996 5.2998 14.1992 0c14.5 -21.7998 46.2002 -72.2998 46.2002 -97.2998c0 -32.4004 -23.7998 -58.7002 -53.2998 -58.7002zM248 48
|
||||
c-51.9004 0 -115.3 32.9004 -123.3 80c-1.7002 10 7.89941 18.4004 17.7002 15.2998c26 -8.2998 64.3994 -13.0996 105.6 -13.0996s79.7002 4.7998 105.6 13.0996c10 3.2002 19.4004 -5.39941 17.7002 -15.2998c-8 -47.0996 -71.3994 -80 -123.3 -80zM378.3 216.3
|
||||
c-3.09961 -0.899414 -7.2002 0.100586 -9.2998 3.7002l-9.5 17c-7.7002 13.7002 -19.2002 21.5996 -31.5 21.5996s-23.7998 -7.89941 -31.5 -21.5996l-9.5 -17c-1.90039 -3.2002 -5.7998 -4.7998 -9.2998 -3.7002c-3.60059 1.10059 -6 4.60059 -5.7002 8.2998
|
||||
c3.2998 42.1006 32.2002 71.4004 56 71.4004s52.7002 -29.2998 56 -71.4004c0.299805 -3.7998 -2.09961 -7.19922 -5.7002 -8.2998zM483.6 269.2c8 -24.2998 12.4004 -50.2002 12.4004 -77.2002c0 -137 -111 -248 -248 -248s-248 111 -248 248s111 248 248 248
|
||||
c45.7002 0 88.4004 -12.5996 125.2 -34.2002c-10.9004 -21.5996 -15.5 -36.2002 -17.2002 -45.7002c-31.2002 20.1006 -68.2002 31.9004 -108 31.9004c-110.3 0 -200 -89.7002 -200 -200s89.7002 -200 200 -200s200 89.7002 200 200
|
||||
c0 22.5 -3.90039 44.0996 -10.7998 64.2998c0.399414 0 21.7998 -2.7998 46.3994 12.9004zM168 258.6c-12.2998 0 -23.7998 -7.7998 -31.5 -21.5996l-9.5 -17c-1.90039 -3.2002 -5.7998 -4.7998 -9.2998 -3.7002c-3.60059 1.10059 -6 4.60059 -5.7002 8.2998
|
||||
c3.2998 42.1006 32.2002 71.4004 56 71.4004s52.7002 -29.2998 56 -71.4004c0.299805 -3.7998 -2.09961 -7.19922 -5.7002 -8.2998c-3.09961 -1 -7.2002 0 -9.2998 3.7002l-9.5 17c-7.7002 13.7002 -19.2002 21.5996 -31.5 21.5996z" />
|
||||
<glyph glyph-name="grin-hearts" unicode="" horiz-adv-x="496"
|
||||
d="M353.6 143.4c10 3.09961 19.3008 -5.5 17.7002 -15.3008c-8 -47.0996 -71.2998 -80 -123.3 -80s-115.4 32.8008 -123.3 80c-1.7002 10 7.89941 18.4004 17.7002 15.3008c26 -8.30078 64.3994 -13.1006 105.6 -13.1006s79.7002 4.7998 105.6 13.1006zM200.8 192.3
|
||||
l-70.2002 18.1006c-20.3994 5.2998 -31.8994 27 -24.1992 47.1992c6.69922 17.7002 26.6992 26.7002 44.8994 22l7.10059 -1.89941l2 7.09961c5.09961 18.1006 22.8994 30.9004 41.5 27.9004c21.3994 -3.40039 34.3994 -24.2002 28.7998 -44.5l-19.4004 -69.9004
|
||||
c-1.2998 -4.5 -6 -7.2002 -10.5 -6zM389.6 257.6c7.7002 -20.1992 -3.7998 -41.7998 -24.1992 -47.0996l-70.2002 -18.2002c-4.60059 -1.2002 -9.2998 1.5 -10.5 6l-19.4004 69.9004c-5.59961 20.2998 7.40039 41.0996 28.7998 44.5c18.7002 3 36.5 -9.7998 41.5 -27.9004
|
||||
l2 -7.09961l7.10059 1.89941c18.2002 4.7002 38.2002 -4.39941 44.8994 -22zM248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8c110.3 0 200 89.7002 200 200s-89.7002 200 -200 200s-200 -89.7002 -200 -200
|
||||
s89.7002 -200 200 -200z" />
|
||||
<glyph glyph-name="grin-squint" unicode="" horiz-adv-x="496"
|
||||
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8c110.3 0 200 89.7002 200 200s-89.7002 200 -200 200s-200 -89.7002 -200 -200s89.7002 -200 200 -200zM353.6 143.4c10 3.09961 19.3008 -5.5 17.7002 -15.3008
|
||||
c-8 -47.0996 -71.2998 -80 -123.3 -80s-115.4 32.9004 -123.3 80c-1.7002 9.90039 7.7998 18.4004 17.7002 15.3008c26 -8.30078 64.3994 -13.1006 105.6 -13.1006s79.7002 4.7998 105.6 13.1006zM118.9 184.2c-3.80078 4.39941 -3.90039 11 -0.100586 15.5l33.6006 40.2998
|
||||
l-33.6006 40.2998c-3.7002 4.5 -3.7002 11 0.100586 15.5c3.89941 4.40039 10.1992 5.5 15.2998 2.5l80 -48c3.59961 -2.2002 5.7998 -6.09961 5.7998 -10.2998s-2.2002 -8.09961 -5.7998 -10.2998l-80 -48c-5.40039 -3.2002 -11.7002 -1.7002 -15.2998 2.5zM361.8 181.7
|
||||
l-80 48c-3.59961 2.2002 -5.7998 6.09961 -5.7998 10.2998s2.2002 8.09961 5.7998 10.2998l80 48c5.10059 2.90039 11.5 1.90039 15.2998 -2.5c3.80078 -4.5 3.90039 -11 0.100586 -15.5l-33.6006 -40.2998l33.6006 -40.2998c3.7002 -4.5 3.7002 -11 -0.100586 -15.5
|
||||
c-3.59961 -4.2002 -9.89941 -5.7002 -15.2998 -2.5z" />
|
||||
<glyph glyph-name="grin-squint-tears" unicode=""
|
||||
d="M117.1 63.9004c6.30078 0.899414 11.7002 -4.5 10.9004 -10.9004c-3.7002 -25.7998 -13.7002 -84 -30.5996 -100.9c-22 -21.8994 -57.9004 -21.5 -80.3008 0.900391c-22.3994 22.4004 -22.7998 58.4004 -0.899414 80.2998
|
||||
c16.8994 16.9004 75.0996 26.9004 100.899 30.6006zM75.9004 105.6c-19.6006 -3.89941 -35.1006 -8.09961 -47.3008 -12.1992c-39.2998 90.5996 -22.0996 199.899 52 274c48.5 48.3994 111.9 72.5996 175.4 72.5996c38.9004 0 77.7998 -9.2002 113.2 -27.4004
|
||||
c-4 -12.1992 -8.2002 -28 -12 -48.2998c-30.4004 17.9004 -65 27.7002 -101.2 27.7002c-53.4004 0 -103.6 -20.7998 -141.4 -58.5996c-61.5996 -61.5 -74.2998 -153.4 -38.6992 -227.801zM428.2 293.2c20.2998 3.89941 36.2002 8 48.5 12
|
||||
c47.8994 -93.2002 32.8994 -210.5 -45.2002 -288.601c-48.5 -48.3994 -111.9 -72.5996 -175.4 -72.5996c-33.6992 0 -67.2998 7 -98.6992 20.5996c4.19922 12.2002 8.2998 27.7002 12.1992 47.2002c26.6006 -12.7998 55.9004 -19.7998 86.4004 -19.7998
|
||||
c53.4004 0 103.6 20.7998 141.4 58.5996c65.6992 65.7002 75.7998 166 30.7998 242.601zM394.9 320.1c-6.30078 -0.899414 -11.7002 4.5 -10.9004 10.9004c3.7002 25.7998 13.7002 84 30.5996 100.9c22 21.8994 57.9004 21.5 80.3008 -0.900391
|
||||
c22.3994 -22.4004 22.7998 -58.4004 0.899414 -80.2998c-16.8994 -16.9004 -75.0996 -26.9004 -100.899 -30.6006zM207.9 211.8c3 -3 4.19922 -7.2998 3.19922 -11.5l-22.5996 -90.5c-1.40039 -5.39941 -6.2002 -9.09961 -11.7002 -9.09961h-0.899414
|
||||
c-5.80078 0.5 -10.5 5.09961 -11 10.8994l-4.80078 52.3008l-52.2998 4.7998c-5.7998 0.5 -10.3994 5.2002 -10.8994 11c-0.400391 5.89941 3.39941 11.2002 9.09961 12.5996l90.5 22.7002c4.2002 1 8.40039 -0.200195 11.4004 -3.2002zM247.6 236.9
|
||||
c-0.0996094 0 -6.39941 -1.80078 -11.3994 3.19922c-3 3 -4.2002 7.30078 -3.2002 11.4004l22.5996 90.5c1.40039 5.7002 7 9.2002 12.6006 9.09961c5.7998 -0.5 10.5 -5.09961 11 -10.8994l4.7998 -52.2998l52.2998 -4.80078c5.7998 -0.5 10.4004 -5.19922 10.9004 -11
|
||||
c0.399414 -5.89941 -3.40039 -11.1992 -9.10059 -12.5996zM299.6 148.4c29.1006 29.0996 53 59.5996 65.3008 83.7998c4.89941 9.2998 17.5996 9.89941 23.3994 1.7002c27.7002 -38.9004 6.10059 -106.9 -30.5996 -143.7s-104.8 -58.2998 -143.7 -30.6006
|
||||
c-8.2998 5.90039 -7.5 18.6006 1.7002 23.4004c24.2002 12.5 54.7998 36.2998 83.8994 65.4004z" />
|
||||
<glyph glyph-name="grin-stars" unicode="" horiz-adv-x="496"
|
||||
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8c110.3 0 200 89.7002 200 200s-89.7002 200 -200 200s-200 -89.7002 -200 -200s89.7002 -200 200 -200zM353.6 143.4c10 3.09961 19.3008 -5.5 17.7002 -15.3008
|
||||
c-8 -47.0996 -71.2998 -80 -123.3 -80s-115.4 32.8008 -123.3 80c-1.7002 10 7.89941 18.4004 17.7002 15.3008c26 -8.30078 64.3994 -13.1006 105.6 -13.1006s79.7002 4.7998 105.6 13.1006zM125.7 200.9l6.09961 34.8994l-25.3994 24.6006
|
||||
c-4.60059 4.59961 -1.90039 12.2998 4.2998 13.1992l34.8994 5l15.5 31.6006c2.90039 5.7998 11 5.7998 13.9004 0l15.5 -31.6006l34.9004 -5c6.19922 -1 8.7998 -8.69922 4.2998 -13.1992l-25.4004 -24.6006l6 -34.8994c1 -6.2002 -5.39941 -11 -11 -7.90039
|
||||
l-31.2998 16.2998l-31.2998 -16.2998c-5.60059 -3.09961 -12 1.7002 -11 7.90039zM385.4 273.6c6.19922 -1 8.89941 -8.59961 4.39941 -13.1992l-25.3994 -24.6006l6 -34.8994c1 -6.2002 -5.40039 -11 -11 -7.90039l-31.3008 16.2998l-31.2998 -16.2998
|
||||
c-5.59961 -3.09961 -12 1.7002 -11 7.90039l6 34.8994l-25.3994 24.6006c-4.60059 4.59961 -1.90039 12.2998 4.2998 13.1992l34.8994 5l15.5 31.6006c2.90039 5.7998 11 5.7998 13.9004 0l15.5 -31.6006z" />
|
||||
<glyph glyph-name="grin-tears" unicode="" horiz-adv-x="640"
|
||||
d="M117.1 191.9c6.30078 0.899414 11.7002 -4.5 10.9004 -10.9004c-3.7002 -25.7998 -13.7002 -84 -30.5996 -100.9c-22 -21.8994 -57.9004 -21.5 -80.3008 0.900391c-22.3994 22.4004 -22.7998 58.4004 -0.899414 80.2998c16.8994 16.9004 75.0996 26.9004 100.899 30.6006
|
||||
zM623.8 161.3c21.9004 -21.8994 21.5 -57.8994 -0.799805 -80.2002c-22.4004 -22.3994 -58.4004 -22.7998 -80.2998 -0.899414c-16.9004 16.8994 -26.9004 75.0996 -30.6006 100.899c-0.899414 6.30078 4.5 11.7002 10.8008 10.8008
|
||||
c25.7998 -3.7002 84 -13.7002 100.899 -30.6006zM497.2 99.5996c12.3994 -37.2998 25.0996 -43.7998 28.2998 -46.5c-44.5996 -65.7998 -120 -109.1 -205.5 -109.1s-160.9 43.2998 -205.5 109.1c3.09961 2.60059 15.7998 9.10059 28.2998 46.5
|
||||
c33.4004 -63.8994 100.3 -107.6 177.2 -107.6s143.8 43.7002 177.2 107.6zM122.7 223.5c-2.40039 0.299805 -5 2.5 -49.5 -6.90039c12.3994 125.4 118.1 223.4 246.8 223.4s234.4 -98 246.8 -223.5c-44.2998 9.40039 -47.3994 7.2002 -49.5 7
|
||||
c-15.2002 95.2998 -97.7998 168.5 -197.3 168.5s-182.1 -73.2002 -197.3 -168.5zM320 48c-51.9004 0 -115.3 32.9004 -123.3 80c-1.7002 10 7.89941 18.4004 17.7002 15.2998c26 -8.2998 64.3994 -13.0996 105.6 -13.0996s79.7002 4.7998 105.6 13.0996
|
||||
c10 3.2002 19.4004 -5.39941 17.7002 -15.2998c-8 -47.0996 -71.3994 -80 -123.3 -80zM450.3 216.3c-3.09961 -0.899414 -7.2002 0.100586 -9.2998 3.7002l-9.5 17c-7.7002 13.7002 -19.2002 21.5996 -31.5 21.5996s-23.7998 -7.89941 -31.5 -21.5996l-9.5 -17
|
||||
c-1.90039 -3.2002 -5.7998 -4.7998 -9.2998 -3.7002c-3.60059 1.10059 -6 4.60059 -5.7002 8.2998c3.2998 42.1006 32.2002 71.4004 56 71.4004s52.7002 -29.2998 56 -71.4004c0.299805 -3.7998 -2.09961 -7.19922 -5.7002 -8.2998zM240 258.6
|
||||
c-12.2998 0 -23.7998 -7.7998 -31.5 -21.5996l-9.5 -17c-1.90039 -3.2002 -5.7998 -4.7998 -9.2998 -3.7002c-3.60059 1.10059 -6 4.60059 -5.7002 8.2998c3.2998 42.1006 32.2002 71.4004 56 71.4004s52.7002 -29.2998 56 -71.4004
|
||||
c0.299805 -3.7998 -2.09961 -7.19922 -5.7002 -8.2998c-3.09961 -1 -7.2002 0 -9.2998 3.7002l-9.5 17c-7.7002 13.7002 -19.2002 21.5996 -31.5 21.5996z" />
|
||||
<glyph glyph-name="grin-tongue" unicode="" horiz-adv-x="496"
|
||||
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM312 40h0.0996094v43.7998l-17.6992 8.7998c-15.1006 7.60059 -31.5 -1.69922 -34.9004 -16.5l-2.7998 -12.0996c-2.10059 -9.2002 -15.2002 -9.2002 -17.2998 0
|
||||
l-2.80078 12.0996c-3.39941 14.8008 -19.8994 24 -34.8994 16.5l-17.7002 -8.7998v-42.7998c0 -35.2002 28 -64.5 63.0996 -65c35.8008 -0.5 64.9004 28.4004 64.9004 64zM340.2 14.7002c64 33.3994 107.8 100.3 107.8 177.3c0 110.3 -89.7002 200 -200 200
|
||||
s-200 -89.7002 -200 -200c0 -77 43.7998 -143.9 107.8 -177.3c-2.2002 8.09961 -3.7998 16.5 -3.7998 25.2998v43.5c-14.2002 12.4004 -24.4004 27.5 -27.2998 44.5c-1.7002 10 7.7998 18.4004 17.7002 15.2998c26 -8.2998 64.3994 -13.0996 105.6 -13.0996
|
||||
s79.7002 4.7998 105.6 13.0996c10 3.2002 19.4004 -5.39941 17.7002 -15.2998c-2.89941 -17 -13.0996 -32.0996 -27.2998 -44.5v-43.5c0 -8.7998 -1.59961 -17.2002 -3.7998 -25.2998zM168 272c17.7002 0 32 -14.2998 32 -32s-14.2998 -32 -32 -32s-32 14.2998 -32 32
|
||||
s14.2998 32 32 32zM328 272c17.7002 0 32 -14.2998 32 -32s-14.2998 -32 -32 -32s-32 14.2998 -32 32s14.2998 32 32 32z" />
|
||||
<glyph glyph-name="grin-tongue-squint" unicode="" horiz-adv-x="496"
|
||||
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM312 40h0.0996094v43.7998l-17.6992 8.7998c-15.1006 7.60059 -31.5 -1.69922 -34.9004 -16.5l-2.7998 -12.0996c-2.10059 -9.2002 -15.2002 -9.2002 -17.2998 0
|
||||
l-2.80078 12.0996c-3.39941 14.8008 -19.8994 24 -34.8994 16.5l-17.7002 -8.7998v-42.7998c0 -35.2002 28 -64.5 63.0996 -65c35.8008 -0.5 64.9004 28.4004 64.9004 64zM340.2 14.7002c64 33.3994 107.8 100.3 107.8 177.3c0 110.3 -89.7002 200 -200 200
|
||||
s-200 -89.7002 -200 -200c0 -77 43.7998 -143.9 107.8 -177.3c-2.2002 8.09961 -3.7998 16.5 -3.7998 25.2998v43.5c-14.2002 12.4004 -24.4004 27.5 -27.2998 44.5c-1.7002 10 7.7998 18.4004 17.7002 15.2998c26 -8.2998 64.3994 -13.0996 105.6 -13.0996
|
||||
s79.7002 4.7998 105.6 13.0996c10 3.2002 19.4004 -5.39941 17.7002 -15.2998c-2.89941 -17 -13.0996 -32.0996 -27.2998 -44.5v-43.5c0 -8.7998 -1.59961 -17.2002 -3.7998 -25.2998zM377.1 295.8c3.80078 -4.39941 3.90039 -11 0.100586 -15.5l-33.6006 -40.2998
|
||||
l33.6006 -40.2998c3.7002 -4.5 3.7002 -11 -0.100586 -15.5c-3.59961 -4.2002 -9.89941 -5.7002 -15.2998 -2.5l-80 48c-3.59961 2.2002 -5.7998 6.09961 -5.7998 10.2998s2.2002 8.09961 5.7998 10.2998l80 48c5 3 11.5 1.90039 15.2998 -2.5zM214.2 250.3
|
||||
c3.59961 -2.2002 5.7998 -6.09961 5.7998 -10.2998s-2.2002 -8.09961 -5.7998 -10.2998l-80 -48c-5.40039 -3.2002 -11.7002 -1.7002 -15.2998 2.5c-3.80078 4.5 -3.90039 11 -0.100586 15.5l33.6006 40.2998l-33.6006 40.2998c-3.7002 4.5 -3.7002 11 0.100586 15.5
|
||||
c3.89941 4.5 10.2998 5.5 15.2998 2.5z" />
|
||||
<glyph glyph-name="grin-tongue-wink" unicode="" horiz-adv-x="496"
|
||||
d="M152 268c25.7002 0 55.9004 -16.9004 59.7998 -42.0996c0.799805 -5 -1.7002 -10 -6.09961 -12.4004c-5.7002 -3.09961 -11.2002 -0.599609 -13.7002 1.59961l-9.5 8.5c-14.7998 13.2002 -46.2002 13.2002 -61 0l-9.5 -8.5
|
||||
c-3.7998 -3.39941 -9.2998 -4 -13.7002 -1.59961c-4.39941 2.40039 -6.89941 7.40039 -6.09961 12.4004c3.89941 25.1992 34.0996 42.0996 59.7998 42.0996zM328 320c44.2002 0 80 -35.7998 80 -80s-35.7998 -80 -80 -80s-80 35.7998 -80 80s35.7998 80 80 80zM328 192
|
||||
c26.5 0 48 21.5 48 48s-21.5 48 -48 48s-48 -21.5 -48 -48s21.5 -48 48 -48zM328 264c13.2998 0 24 -10.7002 24 -24s-10.7002 -24 -24 -24s-24 10.7002 -24 24s10.7002 24 24 24zM248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248z
|
||||
M312 40h0.0996094v43.7998l-17.6992 8.7998c-15.1006 7.60059 -31.5 -1.69922 -34.9004 -16.5l-2.7998 -12.0996c-2.10059 -9.2002 -15.2002 -9.2002 -17.2998 0l-2.80078 12.0996c-3.39941 14.8008 -19.8994 24 -34.8994 16.5l-17.7002 -8.7998v-42.7998
|
||||
c0 -35.2002 28 -64.5 63.0996 -65c35.8008 -0.5 64.9004 28.4004 64.9004 64zM340.2 14.7002c64 33.3994 107.8 100.3 107.8 177.3c0 110.3 -89.7002 200 -200 200s-200 -89.7002 -200 -200c0 -77 43.7998 -143.9 107.8 -177.3
|
||||
c-2.2002 8.09961 -3.7998 16.5 -3.7998 25.2998v43.5c-14.2002 12.4004 -24.4004 27.5 -27.2998 44.5c-1.7002 10 7.7998 18.4004 17.7002 15.2998c26 -8.2998 64.3994 -13.0996 105.6 -13.0996s79.7002 4.7998 105.6 13.0996c10 3.2002 19.4004 -5.39941 17.7002 -15.2998
|
||||
c-2.89941 -17 -13.0996 -32.0996 -27.2998 -44.5v-43.5c0 -8.7998 -1.59961 -17.2002 -3.7998 -25.2998z" />
|
||||
<glyph glyph-name="grin-wink" unicode="" horiz-adv-x="496"
|
||||
d="M328 268c25.6904 0 55.8799 -16.9199 59.8701 -42.1201c1.72949 -11.0898 -11.3506 -18.2695 -19.8301 -10.8398l-9.5498 8.47949c-14.8105 13.1904 -46.1602 13.1904 -60.9707 0l-9.5498 -8.47949c-8.33008 -7.40039 -21.5801 -0.379883 -19.8301 10.8398
|
||||
c3.98047 25.2002 34.1699 42.1201 59.8604 42.1201zM168 208c-17.6699 0 -32 14.3301 -32 32s14.3301 32 32 32s32 -14.3301 32 -32s-14.3301 -32 -32 -32zM353.55 143.36c10.04 3.13965 19.3906 -5.4502 17.71 -15.3408
|
||||
c-7.92969 -47.1494 -71.3193 -80.0195 -123.26 -80.0195s-115.33 32.8701 -123.26 80.0195c-1.69043 9.9707 7.76953 18.4707 17.71 15.3408c25.9297 -8.31055 64.3994 -13.0605 105.55 -13.0605s79.6201 4.75977 105.55 13.0605zM248 440c136.97 0 248 -111.03 248 -248
|
||||
s-111.03 -248 -248 -248s-248 111.03 -248 248s111.03 248 248 248zM248 -8c110.28 0 200 89.7197 200 200s-89.7197 200 -200 200s-200 -89.7197 -200 -200s89.7197 -200 200 -200z" />
|
||||
<glyph glyph-name="kiss" unicode="" horiz-adv-x="496"
|
||||
d="M168 272c17.7002 0 32 -14.2998 32 -32s-14.2998 -32 -32 -32s-32 14.2998 -32 32s14.2998 32 32 32zM304 140c0 -13 -13.4004 -27.2998 -35.0996 -36.4004c21.7998 -8.69922 35.1992 -23 35.1992 -36c0 -19.1992 -28.6992 -41.5 -71.5 -44h-0.5
|
||||
c-3.69922 0 -7 2.60059 -7.7998 6.2002c-0.899414 3.7998 1.10059 7.7002 4.7002 9.2002l17 7.2002c12.9004 5.5 20.7002 13.5 20.7002 21.5s-7.7998 16 -20.7998 21.5l-16.9004 7.2002c-6 2.59961 -5.7002 12.3994 0 14.7998l17 7.2002
|
||||
c12.9004 5.5 20.7002 13.5 20.7002 21.5s-7.7998 16 -20.7998 21.5l-16.9004 7.19922c-3.59961 1.5 -5.59961 5.40039 -4.7002 9.2002c0.799805 3.7998 4.40039 6.60059 8.2002 6.2002c42.7002 -2.5 71.5 -24.7998 71.5 -44zM248 440c137 0 248 -111 248 -248
|
||||
s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8c110.3 0 200 89.7002 200 200s-89.7002 200 -200 200s-200 -89.7002 -200 -200s89.7002 -200 200 -200zM328 272c17.7002 0 32 -14.2998 32 -32s-14.2998 -32 -32 -32s-32 14.2998 -32 32s14.2998 32 32 32z
|
||||
" />
|
||||
<glyph glyph-name="kiss-beam" unicode="" horiz-adv-x="496"
|
||||
d="M168 296c23.7998 0 52.7002 -29.2998 55.7998 -71.4004c0.299805 -3.7998 -2 -7.19922 -5.59961 -8.2998c-3.10059 -1 -7.2002 0 -9.2998 3.7002l-9.5 17c-7.7002 13.7002 -19.2002 21.5996 -31.5 21.5996c-12.3008 0 -23.8008 -7.89941 -31.5 -21.5996l-9.5 -17
|
||||
c-1.80078 -3.2002 -5.80078 -4.7002 -9.30078 -3.7002c-3.59961 1.10059 -5.89941 4.60059 -5.59961 8.2998c3.2998 42.1006 32.2002 71.4004 56 71.4004zM248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8
|
||||
c110.3 0 200 89.7002 200 200s-89.7002 200 -200 200s-200 -89.7002 -200 -200s89.7002 -200 200 -200zM304 140c0 -13 -13.4004 -27.2998 -35.0996 -36.4004c21.7998 -8.69922 35.1992 -23 35.1992 -36c0 -19.1992 -28.6992 -41.5 -71.5 -44h-0.5
|
||||
c-3.69922 0 -7 2.60059 -7.7998 6.2002c-0.899414 3.7998 1.10059 7.7002 4.7002 9.2002l17 7.2002c12.9004 5.5 20.7002 13.5 20.7002 21.5s-7.7998 16 -20.7998 21.5l-16.9004 7.2002c-6 2.59961 -5.7002 12.3994 0 14.7998l17 7.2002
|
||||
c12.9004 5.5 20.7002 13.5 20.7002 21.5s-7.7998 16 -20.7998 21.5l-16.9004 7.19922c-3.59961 1.5 -5.59961 5.40039 -4.7002 9.2002c0.799805 3.7998 4.40039 6.60059 8.2002 6.2002c42.7002 -2.5 71.5 -24.7998 71.5 -44zM328 296
|
||||
c23.7998 0 52.7002 -29.2998 55.7998 -71.4004c0.299805 -3.7998 -2 -7.19922 -5.59961 -8.2998c-3.10059 -1 -7.2002 0 -9.2998 3.7002l-9.5 17c-7.7002 13.7002 -19.2002 21.5996 -31.5 21.5996c-12.3008 0 -23.8008 -7.89941 -31.5 -21.5996l-9.5 -17
|
||||
c-1.80078 -3.2002 -5.80078 -4.7002 -9.30078 -3.7002c-3.59961 1.10059 -5.89941 4.60059 -5.59961 8.2998c3.2998 42.1006 32.2002 71.4004 56 71.4004z" />
|
||||
<glyph glyph-name="kiss-wink-heart" unicode="" horiz-adv-x="504"
|
||||
d="M304 139.5c0 -13 -13.4004 -27.2998 -35.0996 -36.4004c21.7998 -8.69922 35.1992 -23 35.1992 -36c0 -19.1992 -28.6992 -41.5 -71.5 -44h-0.5c-3.69922 0 -7 2.60059 -7.7998 6.2002c-0.899414 3.7998 1.10059 7.7002 4.7002 9.2002l17 7.2002
|
||||
c12.9004 5.5 20.7002 13.5 20.7002 21.5s-7.7998 16 -20.7998 21.5l-16.9004 7.2002c-6 2.59961 -5.7002 12.3994 0 14.7998l17 7.2002c12.9004 5.5 20.7002 13.5 20.7002 21.5s-7.7998 16 -20.7998 21.5l-16.9004 7.19922c-3.59961 1.5 -5.59961 5.40039 -4.7002 9.2002
|
||||
c0.799805 3.7998 4.40039 6.60059 8.2002 6.2002c42.7002 -2.5 71.5 -24.7998 71.5 -44zM374.5 223c-14.7998 13.2002 -46.2002 13.2002 -61 0l-9.5 -8.5c-2.5 -2.2998 -7.90039 -4.7002 -13.7002 -1.59961c-4.39941 2.39941 -6.89941 7.39941 -6.09961 12.3994
|
||||
c3.89941 25.2002 34.2002 42.1006 59.7998 42.1006s55.7998 -16.9004 59.7998 -42.1006c0.799805 -5 -1.7002 -10 -6.09961 -12.3994c-4.40039 -2.40039 -9.90039 -1.7002 -13.7002 1.59961zM136 239.5c0 17.7002 14.2998 32 32 32s32 -14.2998 32 -32s-14.2998 -32 -32 -32
|
||||
s-32 14.2998 -32 32zM501.1 45.5c9.2002 -23.9004 -4.39941 -49.4004 -28.5 -55.7002l-83 -21.5c-5.39941 -1.39941 -10.8994 1.7998 -12.3994 7.10059l-22.9004 82.5996c-6.59961 24 8.7998 48.5996 34 52.5996c22 3.5 43.1006 -11.5996 49 -33l2.2998 -8.39941
|
||||
l8.40039 2.2002c21.5996 5.59961 45.0996 -5.10059 53.0996 -25.9004zM334 11.7002c17.7002 -64 10.9004 -39.5 13.4004 -46.7998c-30.5 -13.4004 -64 -20.9004 -99.4004 -20.9004c-137 0 -248 111 -248 248s111 248 248 248s248 -111 247.9 -248
|
||||
c0 -31.7998 -6.2002 -62.0996 -17.1006 -90c-6 1.5 -12.2002 2.7998 -18.5996 2.90039c-5.60059 9.69922 -13.6006 17.5 -22.6006 23.8994c6.7002 19.9004 10.4004 41.1006 10.4004 63.2002c0 110.3 -89.7002 200 -200 200s-200 -89.7002 -200 -200s89.7002 -200 200 -200
|
||||
c30.7998 0 59.9004 7.2002 86 19.7002z" />
|
||||
<glyph glyph-name="laugh" unicode="" horiz-adv-x="496"
|
||||
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM389.4 50.5996c37.7998 37.8008 58.5996 88 58.5996 141.4s-20.7998 103.6 -58.5996 141.4c-37.8008 37.7998 -88 58.5996 -141.4 58.5996s-103.6 -20.7998 -141.4 -58.5996
|
||||
c-37.7998 -37.8008 -58.5996 -88 -58.5996 -141.4s20.7998 -103.6 58.5996 -141.4c37.8008 -37.7998 88 -58.5996 141.4 -58.5996s103.6 20.7998 141.4 58.5996zM328 224c-17.7002 0 -32 14.2998 -32 32s14.2998 32 32 32s32 -14.2998 32 -32s-14.2998 -32 -32 -32zM168 224
|
||||
c-17.7002 0 -32 14.2998 -32 32s14.2998 32 32 32s32 -14.2998 32 -32s-14.2998 -32 -32 -32zM362.4 160c8.19922 0 14.5 -7 13.5 -15c-7.5 -59.2002 -58.9004 -105 -121.101 -105h-13.5996c-62.2002 0 -113.601 45.7998 -121.101 105c-1 8 5.30078 15 13.5 15h228.801z" />
|
||||
<glyph glyph-name="laugh-beam" unicode="" horiz-adv-x="496"
|
||||
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM389.4 50.5996c37.7998 37.8008 58.5996 88 58.5996 141.4s-20.7998 103.6 -58.5996 141.4c-37.8008 37.7998 -88 58.5996 -141.4 58.5996s-103.6 -20.7998 -141.4 -58.5996
|
||||
c-37.7998 -37.8008 -58.5996 -88 -58.5996 -141.4s20.7998 -103.6 58.5996 -141.4c37.8008 -37.7998 88 -58.5996 141.4 -58.5996s103.6 20.7998 141.4 58.5996zM328 296c23.7998 0 52.7002 -29.2998 55.7998 -71.4004c0.700195 -8.5 -10.7998 -11.8994 -14.8994 -4.5
|
||||
l-9.5 17c-7.7002 13.7002 -19.2002 21.6006 -31.5 21.6006c-12.3008 0 -23.8008 -7.90039 -31.5 -21.6006l-9.5 -17c-4.10059 -7.39941 -15.6006 -4.09961 -14.9004 4.5c3.2998 42.1006 32.2002 71.4004 56 71.4004zM127 220.1c-4.2002 -7.39941 -15.7002 -4 -15.0996 4.5
|
||||
c3.2998 42.1006 32.1992 71.4004 56 71.4004c23.7998 0 52.6992 -29.2998 56 -71.4004c0.699219 -8.5 -10.8008 -11.8994 -14.9004 -4.5l-9.5 17c-7.7002 13.7002 -19.2002 21.6006 -31.5 21.6006s-23.7998 -7.90039 -31.5 -21.6006zM362.4 160c8.19922 0 14.5 -7 13.5 -15
|
||||
c-7.5 -59.2002 -58.9004 -105 -121.101 -105h-13.5996c-62.2002 0 -113.601 45.7998 -121.101 105c-1 8 5.30078 15 13.5 15h228.801z" />
|
||||
<glyph glyph-name="laugh-squint" unicode="" horiz-adv-x="496"
|
||||
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM389.4 50.5996c37.7998 37.8008 58.5996 88 58.5996 141.4s-20.7998 103.6 -58.5996 141.4c-37.8008 37.7998 -88 58.5996 -141.4 58.5996s-103.6 -20.7998 -141.4 -58.5996
|
||||
c-37.7998 -37.8008 -58.5996 -88 -58.5996 -141.4s20.7998 -103.6 58.5996 -141.4c37.8008 -37.7998 88 -58.5996 141.4 -58.5996s103.6 20.7998 141.4 58.5996zM343.6 252l33.6006 -40.2998c8.59961 -10.4004 -3.90039 -24.7998 -15.4004 -18l-80 48
|
||||
c-7.7998 4.7002 -7.7998 15.8994 0 20.5996l80 48c11.6006 6.7998 24 -7.7002 15.4004 -18zM134.2 193.7c-11.6006 -6.7998 -24.1006 7.59961 -15.4004 18l33.6006 40.2998l-33.6006 40.2998c-8.59961 10.2998 3.7998 24.9004 15.4004 18l80 -48
|
||||
c7.7998 -4.7002 7.7998 -15.8994 0 -20.5996zM362.4 160c8.19922 0 14.5 -7 13.5 -15c-7.5 -59.2002 -58.9004 -105 -121.101 -105h-13.5996c-62.2002 0 -113.601 45.7998 -121.101 105c-1 8 5.30078 15 13.5 15h228.801z" />
|
||||
<glyph glyph-name="laugh-wink" unicode="" horiz-adv-x="496"
|
||||
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM389.4 50.5996c37.7998 37.8008 58.5996 88 58.5996 141.4s-20.7998 103.6 -58.5996 141.4c-37.8008 37.7998 -88 58.5996 -141.4 58.5996s-103.6 -20.7998 -141.4 -58.5996
|
||||
c-37.7998 -37.8008 -58.5996 -88 -58.5996 -141.4s20.7998 -103.6 58.5996 -141.4c37.8008 -37.7998 88 -58.5996 141.4 -58.5996s103.6 20.7998 141.4 58.5996zM328 284c25.7002 0 55.9004 -16.9004 59.7002 -42.0996c1.7998 -11.1006 -11.2998 -18.2002 -19.7998 -10.8008
|
||||
l-9.5 8.5c-14.8008 13.2002 -46.2002 13.2002 -61 0l-9.5 -8.5c-8.30078 -7.39941 -21.5 -0.399414 -19.8008 10.8008c4 25.1992 34.2002 42.0996 59.9004 42.0996zM168 224c-17.7002 0 -32 14.2998 -32 32s14.2998 32 32 32s32 -14.2998 32 -32s-14.2998 -32 -32 -32z
|
||||
M362.4 160c8.19922 0 14.5 -7 13.5 -15c-7.5 -59.2002 -58.9004 -105 -121.101 -105h-13.5996c-62.2002 0 -113.601 45.7998 -121.101 105c-1 8 5.30078 15 13.5 15h228.801z" />
|
||||
<glyph glyph-name="meh-blank" unicode="" horiz-adv-x="496"
|
||||
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8c110.3 0 200 89.7002 200 200s-89.7002 200 -200 200s-200 -89.7002 -200 -200s89.7002 -200 200 -200zM168 272c17.7002 0 32 -14.2998 32 -32s-14.2998 -32 -32 -32
|
||||
s-32 14.2998 -32 32s14.2998 32 32 32zM328 272c17.7002 0 32 -14.2998 32 -32s-14.2998 -32 -32 -32s-32 14.2998 -32 32s14.2998 32 32 32z" />
|
||||
<glyph glyph-name="meh-rolling-eyes" unicode="" horiz-adv-x="496"
|
||||
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8c110.3 0 200 89.7002 200 200s-89.7002 200 -200 200s-200 -89.7002 -200 -200s89.7002 -200 200 -200zM336 296c39.7998 0 72 -32.2002 72 -72s-32.2002 -72 -72 -72
|
||||
s-72 32.2002 -72 72s32.2002 72 72 72zM336 184c22.0996 0 40 17.9004 40 40c0 13.5996 -7.2998 25.0996 -17.7002 32.2998c1 -2.59961 1.7002 -5.39941 1.7002 -8.2998c0 -13.2998 -10.7002 -24 -24 -24s-24 10.7002 -24 24c0 3 0.700195 5.7002 1.7002 8.2998
|
||||
c-10.4004 -7.2002 -17.7002 -18.7002 -17.7002 -32.2998c0 -22.0996 17.9004 -40 40 -40zM232 224c0 -39.7998 -32.2002 -72 -72 -72s-72 32.2002 -72 72s32.2002 72 72 72s72 -32.2002 72 -72zM120 224c0 -22.0996 17.9004 -40 40 -40s40 17.9004 40 40
|
||||
c0 13.5996 -7.2998 25.0996 -17.7002 32.2998c1 -2.59961 1.7002 -5.39941 1.7002 -8.2998c0 -13.2998 -10.7002 -24 -24 -24s-24 10.7002 -24 24c0 3 0.700195 5.7002 1.7002 8.2998c-10.4004 -7.2002 -17.7002 -18.7002 -17.7002 -32.2998zM312 96
|
||||
c13.2002 0 24 -10.7998 24 -24s-10.7998 -24 -24 -24h-128c-13.2002 0 -24 10.7998 -24 24s10.7998 24 24 24h128z" />
|
||||
<glyph glyph-name="sad-cry" unicode="" horiz-adv-x="496"
|
||||
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM392 53.5996c34.5996 35.9004 56 84.7002 56 138.4c0 110.3 -89.7002 200 -200 200s-200 -89.7002 -200 -200c0 -53.7002 21.4004 -102.4 56 -138.4v114.4
|
||||
c0 13.2002 10.7998 24 24 24s24 -10.7998 24 -24v-151.4c28.5 -15.5996 61.2002 -24.5996 96 -24.5996s67.5 9 96 24.5996v151.4c0 13.2002 10.7998 24 24 24s24 -10.7998 24 -24v-114.4zM205.8 213.5c-5.7998 -3.2002 -11.2002 -0.700195 -13.7002 1.59961l-9.5 8.5
|
||||
c-14.7998 13.2002 -46.1992 13.2002 -61 0l-9.5 -8.5c-3.7998 -3.39941 -9.2998 -4 -13.6992 -1.59961c-4.40039 2.40039 -6.90039 7.40039 -6.10059 12.4004c3.90039 25.1992 34.2002 42.0996 59.7998 42.0996c25.6006 0 55.8008 -16.9004 59.8008 -42.0996
|
||||
c0.799805 -5 -1.7002 -10 -6.10059 -12.4004zM344 268c25.7002 0 55.9004 -16.9004 59.7998 -42.0996c0.799805 -5 -1.7002 -10 -6.09961 -12.4004c-5.7002 -3.09961 -11.2002 -0.599609 -13.7002 1.59961l-9.5 8.5c-14.7998 13.2002 -46.2002 13.2002 -61 0l-9.5 -8.5
|
||||
c-3.7998 -3.39941 -9.2002 -4 -13.7002 -1.59961c-4.39941 2.40039 -6.89941 7.40039 -6.09961 12.4004c3.89941 25.1992 34.0996 42.0996 59.7998 42.0996zM248 176c30.9004 0 56 -28.7002 56 -64s-25.0996 -64 -56 -64s-56 28.7002 -56 64s25.0996 64 56 64z" />
|
||||
<glyph glyph-name="sad-tear" unicode="" horiz-adv-x="496"
|
||||
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8c110.3 0 200 89.7002 200 200s-89.7002 200 -200 200s-200 -89.7002 -200 -200s89.7002 -200 200 -200zM256 144c38.0996 0 74 -16.7998 98.5 -46.0996
|
||||
c8.5 -10.2002 7.09961 -25.3008 -3.09961 -33.8008c-10.6006 -8.7998 -25.7002 -6.69922 -33.8008 3.10059c-15.2998 18.2998 -37.7998 28.7998 -61.5996 28.7998c-13.2002 0 -24 10.7998 -24 24s10.7998 24 24 24zM168 208c-17.7002 0 -32 14.2998 -32 32s14.2998 32 32 32
|
||||
s32 -14.2998 32 -32s-14.2998 -32 -32 -32zM328 272c17.7002 0 32 -14.2998 32 -32s-14.2998 -32 -32 -32s-32 14.2998 -32 32s14.2998 32 32 32zM162.4 173.2c2.7998 3.7002 8.39941 3.7002 11.1992 0c11.4004 -15.2998 36.4004 -50.6006 36.4004 -68.1006
|
||||
c0 -22.6992 -18.7998 -41.0996 -42 -41.0996s-42 18.4004 -42 41.0996c0 17.5 25 52.8008 36.4004 68.1006z" />
|
||||
<glyph glyph-name="smile-beam" unicode="" horiz-adv-x="496"
|
||||
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8c110.3 0 200 89.7002 200 200s-89.7002 200 -200 200s-200 -89.7002 -200 -200s89.7002 -200 200 -200zM332 135.4c8.5 10.1992 23.5996 11.5 33.7998 3.09961
|
||||
c10.2002 -8.5 11.6006 -23.5996 3.10059 -33.7998c-30 -36 -74.1006 -56.6006 -120.9 -56.6006s-90.9004 20.6006 -120.9 56.6006c-8.39941 10.2002 -7.09961 25.2998 3.10059 33.7998c10.2002 8.40039 25.2998 7.09961 33.7998 -3.09961
|
||||
c20.7998 -25.1006 51.5 -39.4004 84 -39.4004s63.2002 14.4004 84 39.4004zM136.5 237l-9.5 -17c-1.90039 -3.2002 -5.90039 -4.7998 -9.2998 -3.7002c-3.60059 1.10059 -6 4.60059 -5.7002 8.2998c3.2998 42.1006 32.2002 71.4004 56 71.4004s52.7002 -29.2998 56 -71.4004
|
||||
c0.299805 -3.7998 -2.09961 -7.19922 -5.7002 -8.2998c-3.09961 -1 -7.2002 0 -9.2998 3.7002l-9.5 17c-7.7002 13.7002 -19.2002 21.5996 -31.5 21.5996s-23.7998 -7.89941 -31.5 -21.5996zM328 296c23.7998 0 52.7002 -29.2998 56 -71.4004
|
||||
c0.299805 -3.7998 -2.09961 -7.19922 -5.7002 -8.2998c-3.09961 -1 -7.2002 0 -9.2998 3.7002l-9.5 17c-7.7002 13.7002 -19.2002 21.5996 -31.5 21.5996s-23.7998 -7.89941 -31.5 -21.5996l-9.5 -17c-1.90039 -3.2002 -5.7998 -4.7998 -9.2998 -3.7002
|
||||
c-3.60059 1.10059 -6 4.60059 -5.7002 8.2998c3.2998 42.1006 32.2002 71.4004 56 71.4004z" />
|
||||
<glyph glyph-name="surprise" unicode="" horiz-adv-x="496"
|
||||
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8c110.3 0 200 89.7002 200 200s-89.7002 200 -200 200s-200 -89.7002 -200 -200s89.7002 -200 200 -200zM248 168c35.2998 0 64 -28.7002 64 -64s-28.7002 -64 -64 -64
|
||||
s-64 28.7002 -64 64s28.7002 64 64 64zM200 240c0 -17.7002 -14.2998 -32 -32 -32s-32 14.2998 -32 32s14.2998 32 32 32s32 -14.2998 32 -32zM328 272c17.7002 0 32 -14.2998 32 -32s-14.2998 -32 -32 -32s-32 14.2998 -32 32s14.2998 32 32 32z" />
|
||||
<glyph glyph-name="tired" unicode="" horiz-adv-x="496"
|
||||
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8c110.3 0 200 89.7002 200 200s-89.7002 200 -200 200s-200 -89.7002 -200 -200s89.7002 -200 200 -200zM377.1 295.8c3.80078 -4.39941 3.90039 -11 0.100586 -15.5
|
||||
l-33.6006 -40.2998l33.6006 -40.2998c3.7998 -4.5 3.7002 -11 -0.100586 -15.5c-3.5 -4.10059 -9.89941 -5.7002 -15.2998 -2.5l-80 48c-3.59961 2.2002 -5.7998 6.09961 -5.7998 10.2998s2.2002 8.09961 5.7998 10.2998l80 48c5 2.90039 11.5 1.90039 15.2998 -2.5z
|
||||
M220 240c0 -4.2002 -2.2002 -8.09961 -5.7998 -10.2998l-80 -48c-5.40039 -3.2002 -11.7998 -1.60059 -15.2998 2.5c-3.80078 4.5 -3.90039 11 -0.100586 15.5l33.6006 40.2998l-33.6006 40.2998c-3.7998 4.5 -3.7002 11 0.100586 15.5
|
||||
c3.7998 4.40039 10.2998 5.5 15.2998 2.5l80 -48c3.59961 -2.2002 5.7998 -6.09961 5.7998 -10.2998zM248 176c45.4004 0 100.9 -38.2998 107.8 -93.2998c1.5 -11.9004 -7 -21.6006 -15.5 -17.9004c-22.7002 9.7002 -56.2998 15.2002 -92.2998 15.2002
|
||||
s-69.5996 -5.5 -92.2998 -15.2002c-8.60059 -3.7002 -17 6.10059 -15.5 17.9004c6.89941 55 62.3994 93.2998 107.8 93.2998z" />
|
||||
</font>
|
||||
</defs></svg>
|
Before Width: | Height: | Size: 141 KiB |
Before Width: | Height: | Size: 876 KiB |
@ -1,408 +0,0 @@
|
||||
/*global mock, converse */
|
||||
|
||||
const _ = converse.env._;
|
||||
const $msg = converse.env.$msg;
|
||||
const u = converse.env.utils;
|
||||
const Strophe = converse.env.Strophe;
|
||||
const sizzle = converse.env.sizzle;
|
||||
|
||||
|
||||
describe("The Controlbox", function () {
|
||||
|
||||
it("can be opened by clicking a DOM element with class 'toggle-controlbox'",
|
||||
mock.initConverse(
|
||||
['rosterGroupsFetched'], {},
|
||||
function (done, _converse) {
|
||||
|
||||
// This spec will only pass if the controlbox is not currently
|
||||
// open yet.
|
||||
let el = document.querySelector("div#controlbox");
|
||||
expect(_.isElement(el)).toBe(true);
|
||||
expect(u.isVisible(el)).toBe(false);
|
||||
spyOn(_converse.controlboxtoggle, 'onClick').and.callThrough();
|
||||
spyOn(_converse.controlboxtoggle, 'showControlBox').and.callThrough();
|
||||
spyOn(_converse.api, "trigger").and.callThrough();
|
||||
// Redelegate so that the spies are now registered as the event handlers (specifically for 'onClick')
|
||||
_converse.controlboxtoggle.delegateEvents();
|
||||
document.querySelector('.toggle-controlbox').click();
|
||||
expect(_converse.controlboxtoggle.onClick).toHaveBeenCalled();
|
||||
expect(_converse.controlboxtoggle.showControlBox).toHaveBeenCalled();
|
||||
expect(_converse.api.trigger).toHaveBeenCalledWith('controlBoxOpened', jasmine.any(Object));
|
||||
el = document.querySelector("div#controlbox");
|
||||
expect(u.isVisible(el)).toBe(true);
|
||||
done();
|
||||
}));
|
||||
|
||||
|
||||
it("can be closed by clicking a DOM element with class 'close-chatbox-button'",
|
||||
mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
|
||||
|
||||
await mock.openControlBox(_converse);
|
||||
const controlview = _converse.chatboxviews.get('controlbox');
|
||||
|
||||
spyOn(controlview, 'close').and.callThrough();
|
||||
spyOn(_converse.api, "trigger").and.callThrough();
|
||||
|
||||
// We need to rebind all events otherwise our spy won't be called
|
||||
controlview.delegateEvents();
|
||||
|
||||
controlview.el.querySelector('.close-chatbox-button').click();
|
||||
expect(controlview.close).toHaveBeenCalled();
|
||||
await new Promise(resolve => _converse.api.listen.once('chatBoxClosed', resolve));
|
||||
expect(_converse.api.trigger).toHaveBeenCalledWith('chatBoxClosed', jasmine.any(Object));
|
||||
done();
|
||||
}));
|
||||
|
||||
|
||||
describe("The \"Contacts\" section", function () {
|
||||
|
||||
it("can be used to add contact and it checks for case-sensivity",
|
||||
mock.initConverse(
|
||||
['rosterGroupsFetched'], {},
|
||||
async function (done, _converse) {
|
||||
|
||||
spyOn(_converse.api, "trigger").and.callThrough();
|
||||
spyOn(_converse.rosterview, 'update').and.callThrough();
|
||||
await mock.openControlBox(_converse);
|
||||
// Adding two contacts one with Capital initials and one with small initials of same JID (Case sensitive check)
|
||||
_converse.roster.create({
|
||||
jid: mock.pend_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit',
|
||||
subscription: 'none',
|
||||
ask: 'subscribe',
|
||||
fullname: mock.pend_names[0]
|
||||
});
|
||||
_converse.roster.create({
|
||||
jid: mock.pend_names[0].replace(/ /g,'.') + '@montague.lit',
|
||||
subscription: 'none',
|
||||
ask: 'subscribe',
|
||||
fullname: mock.pend_names[0]
|
||||
});
|
||||
await u.waitUntil(() => _.filter(_converse.rosterview.el.querySelectorAll('.roster-group li'), u.isVisible).length, 700);
|
||||
// Checking that only one entry is created because both JID is same (Case sensitive check)
|
||||
expect(_.filter(_converse.rosterview.el.querySelectorAll('li'), u.isVisible).length).toBe(1);
|
||||
expect(_converse.rosterview.update).toHaveBeenCalled();
|
||||
done();
|
||||
}));
|
||||
|
||||
it("shows the number of unread mentions received",
|
||||
mock.initConverse(
|
||||
['rosterGroupsFetched', 'chatBoxesFetched'], {},
|
||||
async function (done, _converse) {
|
||||
|
||||
await mock.waitForRoster(_converse, 'all');
|
||||
await mock.openControlBox(_converse);
|
||||
|
||||
const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
await mock.openChatBoxFor(_converse, sender_jid);
|
||||
await u.waitUntil(() => _converse.chatboxes.length);
|
||||
const chatview = _converse.chatboxviews.get(sender_jid);
|
||||
chatview.model.set({'minimized': true});
|
||||
|
||||
expect(_converse.chatboxviews.el.querySelector('.restore-chat .message-count') === null).toBeTruthy();
|
||||
expect(_converse.rosterview.el.querySelector('.msgs-indicator') === null).toBeTruthy();
|
||||
|
||||
let msg = $msg({
|
||||
from: sender_jid,
|
||||
to: _converse.connection.jid,
|
||||
type: 'chat',
|
||||
id: u.getUniqueId()
|
||||
}).c('body').t('hello').up()
|
||||
.c('active', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree();
|
||||
_converse.handleMessageStanza(msg);
|
||||
await u.waitUntil(() => _converse.rosterview.el.querySelectorAll(".msgs-indicator").length);
|
||||
spyOn(chatview.model, 'handleUnreadMessage').and.callThrough();
|
||||
await u.waitUntil(() => _converse.chatboxviews.el.querySelector('.restore-chat .message-count')?.textContent === '1');
|
||||
expect(_converse.rosterview.el.querySelector('.msgs-indicator').textContent).toBe('1');
|
||||
|
||||
msg = $msg({
|
||||
from: sender_jid,
|
||||
to: _converse.connection.jid,
|
||||
type: 'chat',
|
||||
id: u.getUniqueId()
|
||||
}).c('body').t('hello again').up()
|
||||
.c('active', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree();
|
||||
_converse.handleMessageStanza(msg);
|
||||
await u.waitUntil(() => chatview.model.handleUnreadMessage.calls.count());
|
||||
await u.waitUntil(() => _converse.chatboxviews.el.querySelector('.restore-chat .message-count')?.textContent === '2');
|
||||
expect(_converse.rosterview.el.querySelector('.msgs-indicator').textContent).toBe('2');
|
||||
chatview.model.set({'minimized': false});
|
||||
expect(_converse.chatboxviews.el.querySelector('.restore-chat .message-count')).toBe(null);
|
||||
await u.waitUntil(() => _converse.rosterview.el.querySelector('.msgs-indicator') === null);
|
||||
done();
|
||||
}));
|
||||
});
|
||||
|
||||
describe("The Status Widget", function () {
|
||||
|
||||
it("shows the user's chat status, which is online by default",
|
||||
mock.initConverse(
|
||||
['rosterGroupsFetched'], {},
|
||||
function (done, _converse) {
|
||||
|
||||
mock.openControlBox(_converse);
|
||||
var view = _converse.xmppstatusview;
|
||||
expect(u.hasClass('online', view.el.querySelector('.xmpp-status span:first-child'))).toBe(true);
|
||||
expect(view.el.querySelector('.xmpp-status span.online').textContent.trim()).toBe('I am online');
|
||||
done();
|
||||
}));
|
||||
|
||||
it("can be used to set the current user's chat status",
|
||||
mock.initConverse(
|
||||
['rosterGroupsFetched'], {},
|
||||
async function (done, _converse) {
|
||||
|
||||
await mock.openControlBox(_converse);
|
||||
var cbview = _converse.chatboxviews.get('controlbox');
|
||||
cbview.el.querySelector('.change-status').click()
|
||||
var modal = _converse.xmppstatusview.status_modal;
|
||||
|
||||
await u.waitUntil(() => u.isVisible(modal.el), 1000);
|
||||
const view = _converse.xmppstatusview;
|
||||
modal.el.querySelector('label[for="radio-busy"]').click(); // Change status to "dnd"
|
||||
modal.el.querySelector('[type="submit"]').click();
|
||||
const sent_stanzas = _converse.connection.sent_stanzas;
|
||||
const sent_presence = await u.waitUntil(() => sent_stanzas.filter(s => Strophe.serialize(s).match('presence')).pop());
|
||||
expect(Strophe.serialize(sent_presence)).toBe(
|
||||
`<presence xmlns="jabber:client">`+
|
||||
`<show>dnd</show>`+
|
||||
`<priority>0</priority>`+
|
||||
`<c hash="sha-1" node="https://conversejs.org" ver="PxXfr6uz8ClMWIga0OB/MhKNH/M=" xmlns="http://jabber.org/protocol/caps"/>`+
|
||||
`</presence>`);
|
||||
const first_child = view.el.querySelector('.xmpp-status span:first-child');
|
||||
expect(u.hasClass('online', first_child)).toBe(false);
|
||||
expect(u.hasClass('dnd', first_child)).toBe(true);
|
||||
expect(view.el.querySelector('.xmpp-status span:first-child').textContent.trim()).toBe('I am busy');
|
||||
done();
|
||||
}));
|
||||
|
||||
it("can be used to set a custom status message",
|
||||
mock.initConverse(
|
||||
['rosterGroupsFetched'], {},
|
||||
async function (done, _converse) {
|
||||
|
||||
await mock.openControlBox(_converse);
|
||||
const cbview = _converse.chatboxviews.get('controlbox');
|
||||
cbview.el.querySelector('.change-status').click()
|
||||
const modal = _converse.xmppstatusview.status_modal;
|
||||
|
||||
await u.waitUntil(() => u.isVisible(modal.el), 1000);
|
||||
const view = _converse.xmppstatusview;
|
||||
const msg = 'I am happy';
|
||||
modal.el.querySelector('input[name="status_message"]').value = msg;
|
||||
modal.el.querySelector('[type="submit"]').click();
|
||||
const sent_stanzas = _converse.connection.sent_stanzas;
|
||||
const sent_presence = await u.waitUntil(() => sent_stanzas.filter(s => Strophe.serialize(s).match('presence')).pop());
|
||||
expect(Strophe.serialize(sent_presence)).toBe(
|
||||
`<presence xmlns="jabber:client">`+
|
||||
`<status>I am happy</status>`+
|
||||
`<priority>0</priority>`+
|
||||
`<c hash="sha-1" node="https://conversejs.org" ver="PxXfr6uz8ClMWIga0OB/MhKNH/M=" xmlns="http://jabber.org/protocol/caps"/>`+
|
||||
`</presence>`);
|
||||
|
||||
const first_child = view.el.querySelector('.xmpp-status span:first-child');
|
||||
expect(u.hasClass('online', first_child)).toBe(true);
|
||||
expect(view.el.querySelector('.xmpp-status span:first-child').textContent.trim()).toBe(msg);
|
||||
done();
|
||||
}));
|
||||
});
|
||||
});
|
||||
|
||||
describe("The 'Add Contact' widget", function () {
|
||||
|
||||
it("opens up an add modal when you click on it",
|
||||
mock.initConverse(
|
||||
['rosterGroupsFetched'], {},
|
||||
async function (done, _converse) {
|
||||
|
||||
await mock.waitForRoster(_converse, 'all');
|
||||
await mock.openControlBox(_converse);
|
||||
|
||||
const cbview = _converse.chatboxviews.get('controlbox');
|
||||
cbview.el.querySelector('.add-contact').click()
|
||||
const modal = _converse.rosterview.add_contact_modal;
|
||||
await u.waitUntil(() => u.isVisible(modal.el), 1000);
|
||||
expect(modal.el.querySelector('form.add-xmpp-contact')).not.toBe(null);
|
||||
|
||||
const input_jid = modal.el.querySelector('input[name="jid"]');
|
||||
const input_name = modal.el.querySelector('input[name="name"]');
|
||||
input_jid.value = 'someone@';
|
||||
|
||||
const evt = new Event('input');
|
||||
input_jid.dispatchEvent(evt);
|
||||
expect(modal.el.querySelector('.suggestion-box li').textContent).toBe('someone@montague.lit');
|
||||
input_jid.value = 'someone@montague.lit';
|
||||
input_name.value = 'Someone';
|
||||
modal.el.querySelector('button[type="submit"]').click();
|
||||
|
||||
const sent_IQs = _converse.connection.IQ_stanzas;
|
||||
const sent_stanza = await u.waitUntil(() => sent_IQs.filter(iq => iq.querySelector(`iq[type="set"] query[xmlns="${Strophe.NS.ROSTER}"]`)).pop());
|
||||
expect(Strophe.serialize(sent_stanza)).toEqual(
|
||||
`<iq id="${sent_stanza.getAttribute('id')}" type="set" xmlns="jabber:client">`+
|
||||
`<query xmlns="jabber:iq:roster"><item jid="someone@montague.lit" name="Someone"/></query>`+
|
||||
`</iq>`);
|
||||
done();
|
||||
}));
|
||||
|
||||
it("can be configured to not provide search suggestions",
|
||||
mock.initConverse(
|
||||
['rosterGroupsFetched'], {'autocomplete_add_contact': false},
|
||||
async function (done, _converse) {
|
||||
|
||||
await mock.waitForRoster(_converse, 'all', 0);
|
||||
mock.openControlBox(_converse);
|
||||
const cbview = _converse.chatboxviews.get('controlbox');
|
||||
cbview.el.querySelector('.add-contact').click()
|
||||
const modal = _converse.rosterview.add_contact_modal;
|
||||
expect(modal.jid_auto_complete).toBe(undefined);
|
||||
expect(modal.name_auto_complete).toBe(undefined);
|
||||
|
||||
await u.waitUntil(() => u.isVisible(modal.el), 1000);
|
||||
expect(modal.el.querySelector('form.add-xmpp-contact')).not.toBe(null);
|
||||
const input_jid = modal.el.querySelector('input[name="jid"]');
|
||||
input_jid.value = 'someone@montague.lit';
|
||||
modal.el.querySelector('button[type="submit"]').click();
|
||||
|
||||
const IQ_stanzas = _converse.connection.IQ_stanzas;
|
||||
const sent_stanza = await u.waitUntil(
|
||||
() => IQ_stanzas.filter(s => sizzle(`iq[type="set"] query[xmlns="${Strophe.NS.ROSTER}"]`, s).length).pop()
|
||||
);
|
||||
expect(Strophe.serialize(sent_stanza)).toEqual(
|
||||
`<iq id="${sent_stanza.getAttribute('id')}" type="set" xmlns="jabber:client">`+
|
||||
`<query xmlns="jabber:iq:roster"><item jid="someone@montague.lit"/></query>`+
|
||||
`</iq>`
|
||||
);
|
||||
done();
|
||||
}));
|
||||
|
||||
|
||||
it("integrates with xhr_user_search_url to search for contacts",
|
||||
mock.initConverse(
|
||||
['rosterGroupsFetched'],
|
||||
{ 'xhr_user_search_url': 'http://example.org/?' },
|
||||
async function (done, _converse) {
|
||||
|
||||
await mock.waitForRoster(_converse, 'all', 0);
|
||||
|
||||
const xhr = {
|
||||
'open': function open () {},
|
||||
'send': function () {
|
||||
xhr.responseText = JSON.stringify([
|
||||
{"jid": "marty@mcfly.net", "fullname": "Marty McFly"},
|
||||
{"jid": "doc@brown.com", "fullname": "Doc Brown"}
|
||||
]);
|
||||
xhr.onload();
|
||||
}
|
||||
};
|
||||
const XMLHttpRequestBackup = window.XMLHttpRequest;
|
||||
window.XMLHttpRequest = jasmine.createSpy('XMLHttpRequest');
|
||||
XMLHttpRequest.and.callFake(() => xhr);
|
||||
|
||||
const cbview = _converse.chatboxviews.get('controlbox');
|
||||
cbview.el.querySelector('.add-contact').click()
|
||||
const modal = _converse.rosterview.add_contact_modal;
|
||||
await u.waitUntil(() => u.isVisible(modal.el), 1000);
|
||||
|
||||
// We only have autocomplete for the name input
|
||||
expect(modal.jid_auto_complete).toBe(undefined);
|
||||
expect(modal.name_auto_complete instanceof _converse.AutoComplete).toBe(true);
|
||||
|
||||
const input_el = modal.el.querySelector('input[name="name"]');
|
||||
input_el.value = 'marty';
|
||||
input_el.dispatchEvent(new Event('input'));
|
||||
await u.waitUntil(() => modal.el.querySelector('.suggestion-box li'), 1000);
|
||||
expect(modal.el.querySelectorAll('.suggestion-box li').length).toBe(1);
|
||||
const suggestion = modal.el.querySelector('.suggestion-box li');
|
||||
expect(suggestion.textContent).toBe('Marty McFly');
|
||||
|
||||
// Mock selection
|
||||
modal.name_auto_complete.select(suggestion);
|
||||
|
||||
expect(input_el.value).toBe('Marty McFly');
|
||||
expect(modal.el.querySelector('input[name="jid"]').value).toBe('marty@mcfly.net');
|
||||
modal.el.querySelector('button[type="submit"]').click();
|
||||
|
||||
const sent_IQs = _converse.connection.IQ_stanzas;
|
||||
const sent_stanza = await u.waitUntil(() => sent_IQs.filter(iq => iq.querySelector(`iq[type="set"] query[xmlns="${Strophe.NS.ROSTER}"]`)).pop());
|
||||
expect(Strophe.serialize(sent_stanza)).toEqual(
|
||||
`<iq id="${sent_stanza.getAttribute('id')}" type="set" xmlns="jabber:client">`+
|
||||
`<query xmlns="jabber:iq:roster"><item jid="marty@mcfly.net" name="Marty McFly"/></query>`+
|
||||
`</iq>`);
|
||||
window.XMLHttpRequest = XMLHttpRequestBackup;
|
||||
done();
|
||||
}));
|
||||
|
||||
it("can be configured to not provide search suggestions for XHR search results",
|
||||
mock.initConverse(
|
||||
['rosterGroupsFetched'],
|
||||
{ 'autocomplete_add_contact': false,
|
||||
'xhr_user_search_url': 'http://example.org/?' },
|
||||
async function (done, _converse) {
|
||||
|
||||
await mock.waitForRoster(_converse, 'all');
|
||||
await mock.openControlBox(_converse);
|
||||
var modal;
|
||||
const xhr = {
|
||||
'open': function open () {},
|
||||
'send': function () {
|
||||
const value = modal.el.querySelector('input[name="name"]').value;
|
||||
if (value === 'existing') {
|
||||
const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
xhr.responseText = JSON.stringify([{"jid": contact_jid, "fullname": mock.cur_names[0]}]);
|
||||
} else if (value === 'romeo') {
|
||||
xhr.responseText = JSON.stringify([{"jid": "romeo@montague.lit", "fullname": "Romeo Montague"}]);
|
||||
} else if (value === 'ambiguous') {
|
||||
xhr.responseText = JSON.stringify([
|
||||
{"jid": "marty@mcfly.net", "fullname": "Marty McFly"},
|
||||
{"jid": "doc@brown.com", "fullname": "Doc Brown"}
|
||||
]);
|
||||
} else if (value === 'insufficient') {
|
||||
xhr.responseText = JSON.stringify([]);
|
||||
} else {
|
||||
xhr.responseText = JSON.stringify([{"jid": "marty@mcfly.net", "fullname": "Marty McFly"}]);
|
||||
}
|
||||
xhr.onload();
|
||||
}
|
||||
};
|
||||
const XMLHttpRequestBackup = window.XMLHttpRequest;
|
||||
window.XMLHttpRequest = jasmine.createSpy('XMLHttpRequest');
|
||||
XMLHttpRequest.and.callFake(() => xhr);
|
||||
|
||||
const cbview = _converse.chatboxviews.get('controlbox');
|
||||
cbview.el.querySelector('.add-contact').click()
|
||||
modal = _converse.rosterview.add_contact_modal;
|
||||
await u.waitUntil(() => u.isVisible(modal.el), 1000);
|
||||
|
||||
expect(modal.jid_auto_complete).toBe(undefined);
|
||||
expect(modal.name_auto_complete).toBe(undefined);
|
||||
|
||||
const input_el = modal.el.querySelector('input[name="name"]');
|
||||
input_el.value = 'ambiguous';
|
||||
modal.el.querySelector('button[type="submit"]').click();
|
||||
let feedback_el = modal.el.querySelector('.invalid-feedback');
|
||||
expect(feedback_el.textContent).toBe('Sorry, could not find a contact with that name');
|
||||
feedback_el.textContent = '';
|
||||
|
||||
input_el.value = 'insufficient';
|
||||
modal.el.querySelector('button[type="submit"]').click();
|
||||
feedback_el = modal.el.querySelector('.invalid-feedback');
|
||||
expect(feedback_el.textContent).toBe('Sorry, could not find a contact with that name');
|
||||
feedback_el.textContent = '';
|
||||
|
||||
input_el.value = 'existing';
|
||||
modal.el.querySelector('button[type="submit"]').click();
|
||||
feedback_el = modal.el.querySelector('.invalid-feedback');
|
||||
expect(feedback_el.textContent).toBe('This contact has already been added');
|
||||
|
||||
input_el.value = 'Marty McFly';
|
||||
modal.el.querySelector('button[type="submit"]').click();
|
||||
|
||||
const sent_IQs = _converse.connection.IQ_stanzas;
|
||||
const sent_stanza = await u.waitUntil(() => sent_IQs.filter(iq => iq.querySelector(`iq[type="set"] query[xmlns="${Strophe.NS.ROSTER}"]`)).pop());
|
||||
expect(Strophe.serialize(sent_stanza)).toEqual(
|
||||
`<iq id="${sent_stanza.getAttribute('id')}" type="set" xmlns="jabber:client">`+
|
||||
`<query xmlns="jabber:iq:roster"><item jid="marty@mcfly.net" name="Marty McFly"/></query>`+
|
||||
`</iq>`);
|
||||
window.XMLHttpRequest = XMLHttpRequestBackup;
|
||||
done();
|
||||
}));
|
||||
});
|
@ -1,624 +0,0 @@
|
||||
/*global mock, converse */
|
||||
|
||||
const { Promise, $msg, $pres, Strophe, sizzle } = converse.env;
|
||||
const u = converse.env.utils;
|
||||
|
||||
describe("A Chat Message", function () {
|
||||
|
||||
it("can be sent as a correction by using the up arrow",
|
||||
mock.initConverse(
|
||||
['rosterGroupsFetched', 'chatBoxesFetched'], {},
|
||||
async function (done, _converse) {
|
||||
|
||||
await mock.waitForRoster(_converse, 'current', 1);
|
||||
await mock.openControlBox(_converse);
|
||||
const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
await mock.openChatBoxFor(_converse, contact_jid)
|
||||
const view = _converse.api.chatviews.get(contact_jid);
|
||||
const textarea = view.el.querySelector('textarea.chat-textarea');
|
||||
expect(textarea.value).toBe('');
|
||||
view.onKeyDown({
|
||||
target: textarea,
|
||||
keyCode: 38 // Up arrow
|
||||
});
|
||||
expect(textarea.value).toBe('');
|
||||
|
||||
textarea.value = 'But soft, what light through yonder airlock breaks?';
|
||||
view.onKeyDown({
|
||||
target: textarea,
|
||||
preventDefault: function preventDefault () {},
|
||||
keyCode: 13 // Enter
|
||||
});
|
||||
await new Promise(resolve => view.model.messages.once('rendered', resolve));
|
||||
expect(view.el.querySelectorAll('.chat-msg').length).toBe(1);
|
||||
expect(view.el.querySelector('.chat-msg__text').textContent)
|
||||
.toBe('But soft, what light through yonder airlock breaks?');
|
||||
|
||||
const first_msg = view.model.messages.findWhere({'message': 'But soft, what light through yonder airlock breaks?'});
|
||||
expect(textarea.value).toBe('');
|
||||
view.onKeyDown({
|
||||
target: textarea,
|
||||
keyCode: 38 // Up arrow
|
||||
});
|
||||
expect(textarea.value).toBe('But soft, what light through yonder airlock breaks?');
|
||||
expect(view.model.messages.at(0).get('correcting')).toBe(true);
|
||||
expect(view.el.querySelectorAll('.chat-msg').length).toBe(1);
|
||||
await u.waitUntil(() => u.hasClass('correcting', view.el.querySelector('.chat-msg')), 500);
|
||||
|
||||
spyOn(_converse.connection, 'send');
|
||||
textarea.value = 'But soft, what light through yonder window breaks?';
|
||||
view.onKeyDown({
|
||||
target: textarea,
|
||||
preventDefault: function preventDefault () {},
|
||||
keyCode: 13 // Enter
|
||||
});
|
||||
expect(_converse.connection.send).toHaveBeenCalled();
|
||||
await new Promise(resolve => view.model.messages.once('rendered', resolve));
|
||||
|
||||
const msg = _converse.connection.send.calls.all()[0].args[0];
|
||||
expect(msg.toLocaleString())
|
||||
.toBe(`<message from="romeo@montague.lit/orchard" id="${msg.nodeTree.getAttribute("id")}" `+
|
||||
`to="mercutio@montague.lit" type="chat" `+
|
||||
`xmlns="jabber:client">`+
|
||||
`<body>But soft, what light through yonder window breaks?</body>`+
|
||||
`<active xmlns="http://jabber.org/protocol/chatstates"/>`+
|
||||
`<request xmlns="urn:xmpp:receipts"/>`+
|
||||
`<replace id="${first_msg.get("msgid")}" xmlns="urn:xmpp:message-correct:0"/>`+
|
||||
`<origin-id id="${msg.nodeTree.querySelector('origin-id').getAttribute("id")}" xmlns="urn:xmpp:sid:0"/>`+
|
||||
`</message>`);
|
||||
expect(view.model.messages.models.length).toBe(1);
|
||||
const corrected_message = view.model.messages.at(0);
|
||||
expect(corrected_message.get('msgid')).toBe(first_msg.get('msgid'));
|
||||
expect(corrected_message.get('correcting')).toBe(false);
|
||||
|
||||
const older_versions = corrected_message.get('older_versions');
|
||||
const keys = Object.keys(older_versions);
|
||||
expect(keys.length).toBe(1);
|
||||
expect(older_versions[keys[0]]).toBe('But soft, what light through yonder airlock breaks?');
|
||||
|
||||
expect(view.el.querySelectorAll('.chat-msg').length).toBe(1);
|
||||
await u.waitUntil(() => (u.hasClass('correcting', view.el.querySelector('.chat-msg')) === false), 500);
|
||||
|
||||
// Test that pressing the down arrow cancels message correction
|
||||
expect(textarea.value).toBe('');
|
||||
view.onKeyDown({
|
||||
target: textarea,
|
||||
keyCode: 38 // Up arrow
|
||||
});
|
||||
expect(textarea.value).toBe('But soft, what light through yonder window breaks?');
|
||||
expect(view.model.messages.at(0).get('correcting')).toBe(true);
|
||||
expect(view.el.querySelectorAll('.chat-msg').length).toBe(1);
|
||||
await u.waitUntil(() => u.hasClass('correcting', view.el.querySelector('.chat-msg')), 500);
|
||||
expect(textarea.value).toBe('But soft, what light through yonder window breaks?');
|
||||
view.onKeyDown({
|
||||
target: textarea,
|
||||
keyCode: 40 // Down arrow
|
||||
});
|
||||
expect(textarea.value).toBe('');
|
||||
expect(view.model.messages.at(0).get('correcting')).toBe(false);
|
||||
expect(view.el.querySelectorAll('.chat-msg').length).toBe(1);
|
||||
await u.waitUntil(() => (u.hasClass('correcting', view.el.querySelector('.chat-msg')) === false), 500);
|
||||
|
||||
textarea.value = 'It is the east, and Juliet is the one.';
|
||||
view.onKeyDown({
|
||||
target: textarea,
|
||||
preventDefault: function preventDefault () {},
|
||||
keyCode: 13 // Enter
|
||||
});
|
||||
await new Promise(resolve => view.model.messages.once('rendered', resolve));
|
||||
expect(view.el.querySelectorAll('.chat-msg').length).toBe(2);
|
||||
|
||||
textarea.value = 'Arise, fair sun, and kill the envious moon';
|
||||
view.onKeyDown({
|
||||
target: textarea,
|
||||
preventDefault: function preventDefault () {},
|
||||
keyCode: 13 // Enter
|
||||
});
|
||||
await new Promise(resolve => view.model.messages.once('rendered', resolve));
|
||||
expect(view.el.querySelectorAll('.chat-msg').length).toBe(3);
|
||||
|
||||
view.onKeyDown({
|
||||
target: textarea,
|
||||
keyCode: 38 // Up arrow
|
||||
});
|
||||
expect(textarea.value).toBe('Arise, fair sun, and kill the envious moon');
|
||||
expect(view.model.messages.at(0).get('correcting')).toBeFalsy();
|
||||
expect(view.model.messages.at(1).get('correcting')).toBeFalsy();
|
||||
expect(view.model.messages.at(2).get('correcting')).toBe(true);
|
||||
await u.waitUntil(() => u.hasClass('correcting', sizzle('.chat-msg:last', view.el).pop()), 500);
|
||||
|
||||
textarea.selectionEnd = 0; // Happens by pressing up,
|
||||
// but for some reason not in tests, so we set it manually.
|
||||
view.onKeyDown({
|
||||
target: textarea,
|
||||
keyCode: 38 // Up arrow
|
||||
});
|
||||
expect(textarea.value).toBe('It is the east, and Juliet is the one.');
|
||||
expect(view.model.messages.at(0).get('correcting')).toBeFalsy();
|
||||
expect(view.model.messages.at(1).get('correcting')).toBe(true);
|
||||
expect(view.model.messages.at(2).get('correcting')).toBeFalsy();
|
||||
await u.waitUntil(() => u.hasClass('correcting', sizzle('.chat-msg', view.el)[1]), 500);
|
||||
|
||||
textarea.value = 'It is the east, and Juliet is the sun.';
|
||||
view.onKeyDown({
|
||||
target: textarea,
|
||||
preventDefault: function preventDefault () {},
|
||||
keyCode: 13 // Enter
|
||||
});
|
||||
await new Promise(resolve => view.model.messages.once('rendered', resolve));
|
||||
await u.waitUntil(() => textarea.value === '');
|
||||
const messages = view.el.querySelectorAll('.chat-msg');
|
||||
expect(messages.length).toBe(3);
|
||||
expect(messages[0].querySelector('.chat-msg__text').textContent)
|
||||
.toBe('But soft, what light through yonder window breaks?');
|
||||
expect(messages[1].querySelector('.chat-msg__text').textContent)
|
||||
.toBe('It is the east, and Juliet is the sun.');
|
||||
expect(messages[2].querySelector('.chat-msg__text').textContent)
|
||||
.toBe('Arise, fair sun, and kill the envious moon');
|
||||
|
||||
expect(view.model.messages.at(0).get('correcting')).toBeFalsy();
|
||||
expect(view.model.messages.at(1).get('correcting')).toBeFalsy();
|
||||
expect(view.model.messages.at(2).get('correcting')).toBeFalsy();
|
||||
done();
|
||||
}));
|
||||
|
||||
|
||||
it("can be sent as a correction by clicking the pencil icon",
|
||||
mock.initConverse(
|
||||
['rosterGroupsFetched', 'chatBoxesFetched'], {},
|
||||
async function (done, _converse) {
|
||||
|
||||
await mock.waitForRoster(_converse, 'current', 1);
|
||||
await mock.openControlBox(_converse);
|
||||
const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
await mock.openChatBoxFor(_converse, contact_jid);
|
||||
const view = _converse.api.chatviews.get(contact_jid);
|
||||
const textarea = view.el.querySelector('textarea.chat-textarea');
|
||||
|
||||
textarea.value = 'But soft, what light through yonder airlock breaks?';
|
||||
view.onKeyDown({
|
||||
target: textarea,
|
||||
preventDefault: function preventDefault () {},
|
||||
keyCode: 13 // Enter
|
||||
});
|
||||
await new Promise(resolve => view.model.messages.once('rendered', resolve));
|
||||
|
||||
expect(view.el.querySelectorAll('.chat-msg').length).toBe(1);
|
||||
expect(view.el.querySelector('.chat-msg__text').textContent)
|
||||
.toBe('But soft, what light through yonder airlock breaks?');
|
||||
expect(textarea.value).toBe('');
|
||||
|
||||
const first_msg = view.model.messages.findWhere({'message': 'But soft, what light through yonder airlock breaks?'});
|
||||
await u.waitUntil(() => view.el.querySelectorAll('.chat-msg .chat-msg__action').length === 2);
|
||||
let action = view.el.querySelector('.chat-msg .chat-msg__action');
|
||||
expect(action.textContent.trim()).toBe('Edit');
|
||||
|
||||
action.style.opacity = 1;
|
||||
action.click();
|
||||
|
||||
expect(textarea.value).toBe('But soft, what light through yonder airlock breaks?');
|
||||
expect(view.model.messages.at(0).get('correcting')).toBe(true);
|
||||
expect(view.el.querySelectorAll('.chat-msg').length).toBe(1);
|
||||
await u.waitUntil(() => u.hasClass('correcting', view.el.querySelector('.chat-msg')));
|
||||
|
||||
spyOn(_converse.connection, 'send');
|
||||
textarea.value = 'But soft, what light through yonder window breaks?';
|
||||
view.onKeyDown({
|
||||
target: textarea,
|
||||
preventDefault: function preventDefault () {},
|
||||
keyCode: 13 // Enter
|
||||
});
|
||||
expect(_converse.connection.send).toHaveBeenCalled();
|
||||
|
||||
const msg = _converse.connection.send.calls.all()[0].args[0];
|
||||
expect(msg.toLocaleString())
|
||||
.toBe(`<message from="romeo@montague.lit/orchard" id="${msg.nodeTree.getAttribute("id")}" `+
|
||||
`to="mercutio@montague.lit" type="chat" `+
|
||||
`xmlns="jabber:client">`+
|
||||
`<body>But soft, what light through yonder window breaks?</body>`+
|
||||
`<active xmlns="http://jabber.org/protocol/chatstates"/>`+
|
||||
`<request xmlns="urn:xmpp:receipts"/>`+
|
||||
`<replace id="${first_msg.get("msgid")}" xmlns="urn:xmpp:message-correct:0"/>`+
|
||||
`<origin-id id="${msg.nodeTree.querySelector('origin-id').getAttribute("id")}" xmlns="urn:xmpp:sid:0"/>`+
|
||||
`</message>`);
|
||||
expect(view.model.messages.models.length).toBe(1);
|
||||
const corrected_message = view.model.messages.at(0);
|
||||
expect(corrected_message.get('msgid')).toBe(first_msg.get('msgid'));
|
||||
expect(corrected_message.get('correcting')).toBe(false);
|
||||
|
||||
const older_versions = corrected_message.get('older_versions');
|
||||
const keys = Object.keys(older_versions);
|
||||
expect(keys.length).toBe(1);
|
||||
expect(older_versions[keys[0]]).toBe('But soft, what light through yonder airlock breaks?');
|
||||
|
||||
await u.waitUntil(() => u.hasClass('correcting', view.el.querySelector('.chat-msg')) === false);
|
||||
expect(view.el.querySelectorAll('.chat-msg').length).toBe(1);
|
||||
|
||||
// Test that clicking the pencil icon a second time cancels editing.
|
||||
action = view.el.querySelector('.chat-msg .chat-msg__action');
|
||||
action.style.opacity = 1;
|
||||
action.click();
|
||||
|
||||
expect(textarea.value).toBe('But soft, what light through yonder window breaks?');
|
||||
expect(view.model.messages.at(0).get('correcting')).toBe(true);
|
||||
expect(view.el.querySelectorAll('.chat-msg').length).toBe(1);
|
||||
await u.waitUntil(() => u.hasClass('correcting', view.el.querySelector('.chat-msg')) === true);
|
||||
|
||||
action = view.el.querySelector('.chat-msg .chat-msg__action');
|
||||
action.style.opacity = 1;
|
||||
action.click();
|
||||
expect(textarea.value).toBe('');
|
||||
expect(view.model.messages.at(0).get('correcting')).toBe(false);
|
||||
expect(view.el.querySelectorAll('.chat-msg').length).toBe(1);
|
||||
await u.waitUntil(() => (u.hasClass('correcting', view.el.querySelector('.chat-msg')) === false), 500);
|
||||
|
||||
// Test that messages from other users don't have the pencil icon
|
||||
_converse.handleMessageStanza(
|
||||
$msg({
|
||||
'from': contact_jid,
|
||||
'to': _converse.connection.jid,
|
||||
'type': 'chat',
|
||||
'id': u.getUniqueId()
|
||||
}).c('body').t('Hello').up()
|
||||
.c('active', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree()
|
||||
);
|
||||
await new Promise(resolve => view.model.messages.once('rendered', resolve));
|
||||
expect(view.el.querySelectorAll('.chat-msg .chat-msg__action').length).toBe(2);
|
||||
|
||||
// Test confirmation dialog
|
||||
spyOn(window, 'confirm').and.returnValue(true);
|
||||
textarea.value = 'But soft, what light through yonder airlock breaks?';
|
||||
action = view.el.querySelector('.chat-msg .chat-msg__action');
|
||||
action.style.opacity = 1;
|
||||
action.click();
|
||||
expect(window.confirm).toHaveBeenCalledWith(
|
||||
'You have an unsent message which will be lost if you continue. Are you sure?');
|
||||
expect(view.model.messages.at(0).get('correcting')).toBe(true);
|
||||
expect(textarea.value).toBe('But soft, what light through yonder window breaks?');
|
||||
|
||||
textarea.value = 'But soft, what light through yonder airlock breaks?'
|
||||
action.click();
|
||||
expect(view.model.messages.at(0).get('correcting')).toBe(false);
|
||||
expect(window.confirm.calls.count()).toBe(2);
|
||||
expect(window.confirm.calls.argsFor(0)).toEqual(
|
||||
['You have an unsent message which will be lost if you continue. Are you sure?']);
|
||||
expect(window.confirm.calls.argsFor(1)).toEqual(
|
||||
['You have an unsent message which will be lost if you continue. Are you sure?']);
|
||||
done();
|
||||
}));
|
||||
|
||||
|
||||
describe("when received from someone else", function () {
|
||||
|
||||
it("can be replaced with a correction",
|
||||
mock.initConverse(
|
||||
['rosterGroupsFetched', 'chatBoxesFetched'], {},
|
||||
async function (done, _converse) {
|
||||
|
||||
await mock.waitForRoster(_converse, 'current', 1);
|
||||
await mock.openControlBox(_converse);
|
||||
const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
const msg_id = u.getUniqueId();
|
||||
const view = await mock.openChatBoxFor(_converse, sender_jid);
|
||||
_converse.handleMessageStanza($msg({
|
||||
'from': sender_jid,
|
||||
'to': _converse.connection.jid,
|
||||
'type': 'chat',
|
||||
'id': msg_id,
|
||||
}).c('body').t('But soft, what light through yonder airlock breaks?').tree());
|
||||
await new Promise(resolve => view.model.messages.once('rendered', resolve));
|
||||
expect(view.el.querySelectorAll('.chat-msg').length).toBe(1);
|
||||
expect(view.el.querySelector('.chat-msg__text').textContent)
|
||||
.toBe('But soft, what light through yonder airlock breaks?');
|
||||
|
||||
_converse.handleMessageStanza($msg({
|
||||
'from': sender_jid,
|
||||
'to': _converse.connection.jid,
|
||||
'type': 'chat',
|
||||
'id': u.getUniqueId(),
|
||||
}).c('body').t('But soft, what light through yonder chimney breaks?').up()
|
||||
.c('replace', {'id': msg_id, 'xmlns': 'urn:xmpp:message-correct:0'}).tree());
|
||||
await new Promise(resolve => view.model.messages.once('rendered', resolve));
|
||||
|
||||
expect(view.el.querySelector('.chat-msg__text').textContent)
|
||||
.toBe('But soft, what light through yonder chimney breaks?');
|
||||
expect(view.el.querySelectorAll('.chat-msg').length).toBe(1);
|
||||
expect(view.el.querySelectorAll('.chat-msg__content .fa-edit').length).toBe(1);
|
||||
expect(view.model.messages.models.length).toBe(1);
|
||||
|
||||
_converse.handleMessageStanza($msg({
|
||||
'from': sender_jid,
|
||||
'to': _converse.connection.jid,
|
||||
'type': 'chat',
|
||||
'id': u.getUniqueId(),
|
||||
}).c('body').t('But soft, what light through yonder window breaks?').up()
|
||||
.c('replace', {'id': msg_id, 'xmlns': 'urn:xmpp:message-correct:0'}).tree());
|
||||
await new Promise(resolve => view.model.messages.once('rendered', resolve));
|
||||
|
||||
expect(view.el.querySelector('.chat-msg__text').textContent)
|
||||
.toBe('But soft, what light through yonder window breaks?');
|
||||
expect(view.el.querySelectorAll('.chat-msg').length).toBe(1);
|
||||
expect(view.el.querySelectorAll('.chat-msg__content .fa-edit').length).toBe(1);
|
||||
view.el.querySelector('.chat-msg__content .fa-edit').click();
|
||||
const modal = await u.waitUntil(() => view.el.querySelector('converse-chat-message').message_versions_modal);
|
||||
await u.waitUntil(() => u.isVisible(modal.el), 1000);
|
||||
const older_msgs = modal.el.querySelectorAll('.older-msg');
|
||||
expect(older_msgs.length).toBe(2);
|
||||
expect(older_msgs[0].childNodes[0].nodeName).toBe('TIME');
|
||||
expect(older_msgs[0].childNodes[2].textContent).toBe('But soft, what light through yonder airlock breaks?');
|
||||
expect(view.model.messages.models.length).toBe(1);
|
||||
done();
|
||||
}));
|
||||
});
|
||||
});
|
||||
|
||||
describe("A Groupchat Message", function () {
|
||||
|
||||
it("can be replaced with a correction",
|
||||
mock.initConverse(
|
||||
['rosterGroupsFetched'], {},
|
||||
async function (done, _converse) {
|
||||
|
||||
const muc_jid = 'lounge@montague.lit';
|
||||
await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
|
||||
const view = _converse.api.chatviews.get(muc_jid);
|
||||
const stanza = $pres({
|
||||
to: 'romeo@montague.lit/_converse.js-29092160',
|
||||
from: 'coven@chat.shakespeare.lit/newguy'
|
||||
})
|
||||
.c('x', {xmlns: Strophe.NS.MUC_USER})
|
||||
.c('item', {
|
||||
'affiliation': 'none',
|
||||
'jid': 'newguy@montague.lit/_converse.js-290929789',
|
||||
'role': 'participant'
|
||||
}).tree();
|
||||
_converse.connection._dataRecv(mock.createRequest(stanza));
|
||||
const msg_id = u.getUniqueId();
|
||||
await view.model.handleMessageStanza($msg({
|
||||
'from': 'lounge@montague.lit/newguy',
|
||||
'to': _converse.connection.jid,
|
||||
'type': 'groupchat',
|
||||
'id': msg_id,
|
||||
}).c('body').t('But soft, what light through yonder airlock breaks?').tree());
|
||||
|
||||
await u.waitUntil(() => view.el.querySelectorAll('.chat-msg').length);
|
||||
expect(view.el.querySelectorAll('.chat-msg').length).toBe(1);
|
||||
expect(view.el.querySelector('.chat-msg__text').textContent)
|
||||
.toBe('But soft, what light through yonder airlock breaks?');
|
||||
|
||||
await view.model.handleMessageStanza($msg({
|
||||
'from': 'lounge@montague.lit/newguy',
|
||||
'to': _converse.connection.jid,
|
||||
'type': 'groupchat',
|
||||
'id': u.getUniqueId(),
|
||||
}).c('body').t('But soft, what light through yonder chimney breaks?').up()
|
||||
.c('replace', {'id': msg_id, 'xmlns': 'urn:xmpp:message-correct:0'}).tree());
|
||||
await u.waitUntil(() => view.el.querySelector('.chat-msg__text').textContent ===
|
||||
'But soft, what light through yonder chimney breaks?', 500);
|
||||
expect(view.el.querySelectorAll('.chat-msg').length).toBe(1);
|
||||
await u.waitUntil(() => view.el.querySelector('.chat-msg__content .fa-edit'));
|
||||
|
||||
await view.model.handleMessageStanza($msg({
|
||||
'from': 'lounge@montague.lit/newguy',
|
||||
'to': _converse.connection.jid,
|
||||
'type': 'groupchat',
|
||||
'id': u.getUniqueId(),
|
||||
}).c('body').t('But soft, what light through yonder window breaks?').up()
|
||||
.c('replace', {'id': msg_id, 'xmlns': 'urn:xmpp:message-correct:0'}).tree());
|
||||
|
||||
await u.waitUntil(() => view.el.querySelector('.chat-msg__text').textContent ===
|
||||
'But soft, what light through yonder window breaks?', 500);
|
||||
expect(view.el.querySelectorAll('.chat-msg').length).toBe(1);
|
||||
expect(view.el.querySelectorAll('.chat-msg__content .fa-edit').length).toBe(1);
|
||||
const edit = await u.waitUntil(() => view.el.querySelector('.chat-msg__content .fa-edit'));
|
||||
edit.click();
|
||||
const modal = await u.waitUntil(() => view.el.querySelector('converse-chat-message').message_versions_modal);
|
||||
await u.waitUntil(() => u.isVisible(modal.el), 1000);
|
||||
const older_msgs = modal.el.querySelectorAll('.older-msg');
|
||||
expect(older_msgs.length).toBe(2);
|
||||
expect(older_msgs[0].childNodes[2].textContent).toBe('But soft, what light through yonder airlock breaks?');
|
||||
expect(older_msgs[0].childNodes[0].nodeName).toBe('TIME');
|
||||
expect(older_msgs[1].childNodes[0].nodeName).toBe('TIME');
|
||||
expect(older_msgs[1].childNodes[2].textContent).toBe('But soft, what light through yonder chimney breaks?');
|
||||
done();
|
||||
}));
|
||||
|
||||
it("keeps the same position in history after a correction",
|
||||
mock.initConverse(
|
||||
['rosterGroupsFetched'], {},
|
||||
async function (done, _converse) {
|
||||
|
||||
const muc_jid = 'lounge@montague.lit';
|
||||
await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
|
||||
const view = _converse.api.chatviews.get(muc_jid);
|
||||
const stanza = $pres({
|
||||
to: 'romeo@montague.lit/_converse.js-29092160',
|
||||
from: 'coven@chat.shakespeare.lit/newguy'
|
||||
})
|
||||
.c('x', {xmlns: Strophe.NS.MUC_USER})
|
||||
.c('item', {
|
||||
'affiliation': 'none',
|
||||
'jid': 'newguy@montague.lit/_converse.js-290929789',
|
||||
'role': 'participant'
|
||||
}).tree();
|
||||
_converse.connection._dataRecv(mock.createRequest(stanza));
|
||||
const msg_id = u.getUniqueId();
|
||||
|
||||
// Receiving the first message
|
||||
await view.model.handleMessageStanza($msg({
|
||||
'from': 'lounge@montague.lit/newguy',
|
||||
'to': _converse.connection.jid,
|
||||
'type': 'groupchat',
|
||||
'id': msg_id,
|
||||
}).c('body').t('But soft, what light through yonder airlock breaks?').tree());
|
||||
|
||||
// Receiving own message to check order against
|
||||
await view.model.handleMessageStanza($msg({
|
||||
'from': 'lounge@montague.lit/romeo',
|
||||
'to': _converse.connection.jid,
|
||||
'type': 'groupchat',
|
||||
'id': msg_id,
|
||||
}).c('body').t('But soft, what light through yonder airlock breaks?').tree());
|
||||
|
||||
await u.waitUntil(() => view.el.querySelectorAll('.chat-msg').length === 2);
|
||||
expect(view.el.querySelectorAll('.chat-msg').length).toBe(2);
|
||||
expect(view.el.querySelectorAll('.chat-msg__text')[0].textContent)
|
||||
.toBe('But soft, what light through yonder airlock breaks?');
|
||||
expect(view.el.querySelectorAll('.chat-msg__text')[1].textContent)
|
||||
.toBe('But soft, what light through yonder airlock breaks?');
|
||||
|
||||
// First message correction
|
||||
await view.model.handleMessageStanza($msg({
|
||||
'from': 'lounge@montague.lit/newguy',
|
||||
'to': _converse.connection.jid,
|
||||
'type': 'groupchat',
|
||||
'id': u.getUniqueId(),
|
||||
}).c('body').t('But soft, what light through yonder chimney breaks?').up()
|
||||
.c('replace', {'id': msg_id, 'xmlns': 'urn:xmpp:message-correct:0'}).tree());
|
||||
|
||||
await u.waitUntil(() => view.el.querySelector('.chat-msg__text').textContent ===
|
||||
'But soft, what light through yonder chimney breaks?', 500);
|
||||
expect(view.el.querySelectorAll('.chat-msg').length).toBe(2);
|
||||
await u.waitUntil(() => view.el.querySelector('.chat-msg__content .fa-edit'));
|
||||
|
||||
// Second message correction
|
||||
await view.model.handleMessageStanza($msg({
|
||||
'from': 'lounge@montague.lit/newguy',
|
||||
'to': _converse.connection.jid,
|
||||
'type': 'groupchat',
|
||||
'id': u.getUniqueId(),
|
||||
}).c('body').t('But soft, what light through yonder window breaks?').up()
|
||||
.c('replace', {'id': msg_id, 'xmlns': 'urn:xmpp:message-correct:0'}).tree());
|
||||
|
||||
// Second own message
|
||||
await view.model.handleMessageStanza($msg({
|
||||
'from': 'lounge@montague.lit/romeo',
|
||||
'to': _converse.connection.jid,
|
||||
'type': 'groupchat',
|
||||
'id': u.getUniqueId(),
|
||||
}).c('body').t('But soft, what light through yonder window breaks?').tree());
|
||||
|
||||
await u.waitUntil(() => view.el.querySelectorAll('.chat-msg__text')[0].textContent ===
|
||||
'But soft, what light through yonder window breaks?', 500);
|
||||
await u.waitUntil(() => view.el.querySelectorAll('.chat-msg__text').length === 3);
|
||||
await u.waitUntil(() => view.el.querySelectorAll('.chat-msg__text')[2].textContent ===
|
||||
'But soft, what light through yonder window breaks?', 500);
|
||||
|
||||
expect(view.el.querySelectorAll('.chat-msg').length).toBe(3);
|
||||
expect(view.el.querySelectorAll('.chat-msg__content .fa-edit').length).toBe(1);
|
||||
const edit = await u.waitUntil(() => view.el.querySelector('.chat-msg__content .fa-edit'));
|
||||
edit.click();
|
||||
const modal = await u.waitUntil(() => view.el.querySelectorAll('converse-chat-message')[0].message_versions_modal);
|
||||
await u.waitUntil(() => u.isVisible(modal.el), 1000);
|
||||
const older_msgs = modal.el.querySelectorAll('.older-msg');
|
||||
expect(older_msgs.length).toBe(2);
|
||||
expect(older_msgs[0].childNodes[2].textContent).toBe('But soft, what light through yonder airlock breaks?');
|
||||
expect(older_msgs[0].childNodes[0].nodeName).toBe('TIME');
|
||||
expect(older_msgs[1].childNodes[0].nodeName).toBe('TIME');
|
||||
expect(older_msgs[1].childNodes[2].textContent).toBe('But soft, what light through yonder chimney breaks?');
|
||||
done();
|
||||
}));
|
||||
|
||||
it("can be sent as a correction by using the up arrow",
|
||||
mock.initConverse(
|
||||
['rosterGroupsFetched'], {},
|
||||
async function (done, _converse) {
|
||||
|
||||
const muc_jid = 'lounge@montague.lit';
|
||||
await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
|
||||
const view = _converse.api.chatviews.get(muc_jid);
|
||||
const textarea = view.el.querySelector('textarea.chat-textarea');
|
||||
expect(textarea.value).toBe('');
|
||||
view.onKeyDown({
|
||||
target: textarea,
|
||||
keyCode: 38 // Up arrow
|
||||
});
|
||||
expect(textarea.value).toBe('');
|
||||
|
||||
textarea.value = 'But soft, what light through yonder airlock breaks?';
|
||||
view.onKeyDown({
|
||||
target: textarea,
|
||||
preventDefault: function preventDefault () {},
|
||||
keyCode: 13 // Enter
|
||||
});
|
||||
await u.waitUntil(() => view.el.querySelectorAll('.chat-msg').length === 1);
|
||||
expect(view.el.querySelector('.chat-msg__text').textContent)
|
||||
.toBe('But soft, what light through yonder airlock breaks?');
|
||||
|
||||
const first_msg = view.model.messages.findWhere({'message': 'But soft, what light through yonder airlock breaks?'});
|
||||
expect(textarea.value).toBe('');
|
||||
view.onKeyDown({
|
||||
target: textarea,
|
||||
keyCode: 38 // Up arrow
|
||||
});
|
||||
expect(textarea.value).toBe('But soft, what light through yonder airlock breaks?');
|
||||
expect(view.model.messages.at(0).get('correcting')).toBe(true);
|
||||
expect(view.el.querySelectorAll('.chat-msg').length).toBe(1);
|
||||
await u.waitUntil(() => u.hasClass('correcting', view.el.querySelector('.chat-msg')));
|
||||
|
||||
spyOn(_converse.connection, 'send');
|
||||
textarea.value = 'But soft, what light through yonder window breaks?';
|
||||
view.onKeyDown({
|
||||
target: textarea,
|
||||
preventDefault: function preventDefault () {},
|
||||
keyCode: 13 // Enter
|
||||
});
|
||||
expect(_converse.connection.send).toHaveBeenCalled();
|
||||
await new Promise(resolve => view.model.messages.once('rendered', resolve));
|
||||
|
||||
const msg = _converse.connection.send.calls.all()[0].args[0];
|
||||
expect(msg.toLocaleString())
|
||||
.toBe(`<message from="romeo@montague.lit/orchard" id="${msg.nodeTree.getAttribute("id")}" `+
|
||||
`to="lounge@montague.lit" type="groupchat" `+
|
||||
`xmlns="jabber:client">`+
|
||||
`<body>But soft, what light through yonder window breaks?</body>`+
|
||||
`<active xmlns="http://jabber.org/protocol/chatstates"/>`+
|
||||
`<replace id="${first_msg.get("msgid")}" xmlns="urn:xmpp:message-correct:0"/>`+
|
||||
`<origin-id id="${msg.nodeTree.querySelector('origin-id').getAttribute("id")}" xmlns="urn:xmpp:sid:0"/>`+
|
||||
`</message>`);
|
||||
|
||||
expect(view.model.messages.models.length).toBe(1);
|
||||
const corrected_message = view.model.messages.at(0);
|
||||
expect(corrected_message.get('msgid')).toBe(first_msg.get('msgid'));
|
||||
expect(corrected_message.get('correcting')).toBe(false);
|
||||
|
||||
const older_versions = corrected_message.get('older_versions');
|
||||
const keys = Object.keys(older_versions);
|
||||
expect(keys.length).toBe(1);
|
||||
expect(older_versions[keys[0]]).toBe('But soft, what light through yonder airlock breaks?');
|
||||
|
||||
expect(view.el.querySelectorAll('.chat-msg').length).toBe(1);
|
||||
expect(u.hasClass('correcting', view.el.querySelector('.chat-msg'))).toBe(false);
|
||||
|
||||
// Check that messages from other users are skipped
|
||||
await view.model.handleMessageStanza($msg({
|
||||
'from': muc_jid+'/someone-else',
|
||||
'id': u.getUniqueId(),
|
||||
'to': 'romeo@montague.lit',
|
||||
'type': 'groupchat'
|
||||
}).c('body').t('Hello world').tree());
|
||||
await new Promise(resolve => view.model.messages.once('rendered', resolve));
|
||||
expect(view.el.querySelectorAll('.chat-msg').length).toBe(2);
|
||||
|
||||
// Test that pressing the down arrow cancels message correction
|
||||
expect(textarea.value).toBe('');
|
||||
view.onKeyDown({
|
||||
target: textarea,
|
||||
keyCode: 38 // Up arrow
|
||||
});
|
||||
expect(textarea.value).toBe('But soft, what light through yonder window breaks?');
|
||||
expect(view.model.messages.at(0).get('correcting')).toBe(true);
|
||||
expect(view.el.querySelectorAll('.chat-msg').length).toBe(2);
|
||||
await u.waitUntil(() => u.hasClass('correcting', view.el.querySelector('.chat-msg')), 500);
|
||||
expect(textarea.value).toBe('But soft, what light through yonder window breaks?');
|
||||
view.onKeyDown({
|
||||
target: textarea,
|
||||
keyCode: 40 // Down arrow
|
||||
});
|
||||
expect(textarea.value).toBe('');
|
||||
expect(view.model.messages.at(0).get('correcting')).toBe(false);
|
||||
expect(view.el.querySelectorAll('.chat-msg').length).toBe(2);
|
||||
await u.waitUntil(() => !u.hasClass('correcting', view.el.querySelector('.chat-msg')), 500);
|
||||
done();
|
||||
}));
|
||||
});
|
431
spec/emojis.js
@ -1,431 +0,0 @@
|
||||
/*global mock, converse */
|
||||
|
||||
const { Promise, $msg, $pres, sizzle } = converse.env;
|
||||
const u = converse.env.utils;
|
||||
const original_timeout = jasmine.DEFAULT_TIMEOUT_INTERVAL;
|
||||
|
||||
|
||||
describe("Emojis", function () {
|
||||
describe("The emoji picker", function () {
|
||||
|
||||
beforeEach(() => (jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000));
|
||||
afterEach(() => (jasmine.DEFAULT_TIMEOUT_INTERVAL = original_timeout));
|
||||
|
||||
it("can be opened by clicking a button in the chat toolbar",
|
||||
mock.initConverse(
|
||||
['rosterGroupsFetched', 'chatBoxesFetched'], {},
|
||||
async function (done, _converse) {
|
||||
|
||||
const contact_jid = mock.cur_names[2].replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
await mock.waitForRoster(_converse, 'current');
|
||||
await mock.openControlBox(_converse);
|
||||
await mock.openChatBoxFor(_converse, contact_jid);
|
||||
const view = _converse.chatboxviews.get(contact_jid);
|
||||
const toolbar = await u.waitUntil(() => view.el.querySelector('converse-chat-toolbar'));
|
||||
toolbar.querySelector('.toggle-emojis').click();
|
||||
await u.waitUntil(() => u.isVisible(view.el.querySelector('.emoji-picker__lists')), 1000);
|
||||
const item = view.el.querySelector('.emoji-picker li.insert-emoji a');
|
||||
item.click()
|
||||
expect(view.el.querySelector('textarea.chat-textarea').value).toBe(':smiley: ');
|
||||
toolbar.querySelector('.toggle-emojis').click(); // Close the panel again
|
||||
done();
|
||||
}));
|
||||
|
||||
it("is opened to autocomplete emojis in the textarea",
|
||||
mock.initConverse(
|
||||
['rosterGroupsFetched', 'chatBoxesFetched'], {},
|
||||
async function (done, _converse) {
|
||||
|
||||
const muc_jid = 'lounge@montague.lit';
|
||||
await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
|
||||
const view = _converse.chatboxviews.get(muc_jid);
|
||||
await u.waitUntil(() => view.el.querySelector('converse-emoji-dropdown'));
|
||||
const textarea = view.el.querySelector('textarea.chat-textarea');
|
||||
textarea.value = ':gri';
|
||||
|
||||
// Press tab
|
||||
const tab_event = {
|
||||
'target': textarea,
|
||||
'preventDefault': function preventDefault () {},
|
||||
'stopPropagation': function stopPropagation () {},
|
||||
'keyCode': 9,
|
||||
'key': 'Tab'
|
||||
}
|
||||
view.onKeyDown(tab_event);
|
||||
await u.waitUntil(() => view.el.querySelector('converse-emoji-picker .emoji-search').value === ':gri');
|
||||
await u.waitUntil(() => sizzle('.emojis-lists__container--search .insert-emoji', view.el).length === 3, 1000);
|
||||
let visible_emojis = sizzle('.emojis-lists__container--search .insert-emoji', view.el);
|
||||
expect(visible_emojis[0].getAttribute('data-emoji')).toBe(':grimacing:');
|
||||
expect(visible_emojis[1].getAttribute('data-emoji')).toBe(':grin:');
|
||||
expect(visible_emojis[2].getAttribute('data-emoji')).toBe(':grinning:');
|
||||
|
||||
const picker = view.el.querySelector('converse-emoji-picker');
|
||||
const input = picker.querySelector('.emoji-search');
|
||||
// Test that TAB autocompletes the to first match
|
||||
input.dispatchEvent(new KeyboardEvent('keydown', tab_event));
|
||||
|
||||
await u.waitUntil(() => sizzle(".emojis-lists__container--search .insert-emoji:not('.hidden')", picker).length === 1, 1000);
|
||||
visible_emojis = sizzle(".emojis-lists__container--search .insert-emoji:not('.hidden')", picker);
|
||||
expect(visible_emojis[0].getAttribute('data-emoji')).toBe(':grimacing:');
|
||||
expect(input.value).toBe(':grimacing:');
|
||||
|
||||
// Check that ENTER now inserts the match
|
||||
const enter_event = Object.assign({}, tab_event, {'keyCode': 13, 'key': 'Enter', 'target': input});
|
||||
input.dispatchEvent(new KeyboardEvent('keydown', enter_event));
|
||||
|
||||
await u.waitUntil(() => input.value === '');
|
||||
await u.waitUntil(() => textarea.value === ':grimacing: ');
|
||||
|
||||
// Test that username starting with : doesn't cause issues
|
||||
const presence = $pres({
|
||||
'from': `${muc_jid}/:username`,
|
||||
'id': '27C55F89-1C6A-459A-9EB5-77690145D624',
|
||||
'to': _converse.jid
|
||||
})
|
||||
.c('x', { 'xmlns': 'http://jabber.org/protocol/muc#user'})
|
||||
.c('item', {
|
||||
'jid': 'some1@montague.lit',
|
||||
'affiliation': 'member',
|
||||
'role': 'participant'
|
||||
});
|
||||
_converse.connection._dataRecv(mock.createRequest(presence));
|
||||
|
||||
textarea.value = ':use';
|
||||
view.onKeyDown(tab_event);
|
||||
await u.waitUntil(() => u.isVisible(view.el.querySelector('.emoji-picker__lists')));
|
||||
await u.waitUntil(() => input.value === ':use');
|
||||
visible_emojis = sizzle('.insert-emoji:not(.hidden)', picker);
|
||||
expect(visible_emojis.length).toBe(0);
|
||||
done();
|
||||
}));
|
||||
|
||||
it("is focused to autocomplete emojis in the textarea",
|
||||
mock.initConverse(
|
||||
['rosterGroupsFetched', 'chatBoxesFetched'], {},
|
||||
async function (done, _converse) {
|
||||
|
||||
const muc_jid = 'lounge@montague.lit';
|
||||
await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
|
||||
const view = _converse.chatboxviews.get(muc_jid);
|
||||
await u.waitUntil(() => view.el.querySelector('converse-emoji-dropdown'));
|
||||
const textarea = view.el.querySelector('textarea.chat-textarea');
|
||||
textarea.value = ':';
|
||||
// Press tab
|
||||
const tab_event = {
|
||||
'target': textarea,
|
||||
'preventDefault': function preventDefault () {},
|
||||
'stopPropagation': function stopPropagation () {},
|
||||
'keyCode': 9,
|
||||
'key': 'Tab'
|
||||
}
|
||||
view.onKeyDown(tab_event);
|
||||
await u.waitUntil(() => u.isVisible(view.el.querySelector('.emoji-picker__lists')));
|
||||
|
||||
const picker = view.el.querySelector('converse-emoji-picker');
|
||||
const input = picker.querySelector('.emoji-search');
|
||||
expect(input.value).toBe(':');
|
||||
input.value = ':gri';
|
||||
const event = {
|
||||
'target': input,
|
||||
'preventDefault': function preventDefault () {},
|
||||
'stopPropagation': function stopPropagation () {}
|
||||
};
|
||||
input.dispatchEvent(new KeyboardEvent('keydown', event));
|
||||
await u.waitUntil(() => sizzle('.emojis-lists__container--search .insert-emoji', view.el).length === 3, 1000);
|
||||
let emoji = sizzle('.emojis-lists__container--search .insert-emoji:not(.hidden) a', view.el).pop();
|
||||
emoji.click();
|
||||
await u.waitUntil(() => textarea.value === ':grinning: ');
|
||||
textarea.value = ':grinning: :';
|
||||
view.onKeyDown(tab_event);
|
||||
|
||||
await u.waitUntil(() => input.value === ':');
|
||||
input.value = ':grimacing';
|
||||
input.dispatchEvent(new KeyboardEvent('keydown', event));
|
||||
await u.waitUntil(() => sizzle('.emojis-lists__container--search .insert-emoji', view.el).length === 1, 1000);
|
||||
emoji = sizzle('.emojis-lists__container--search .insert-emoji:not(.hidden) a', view.el).pop();
|
||||
emoji.click();
|
||||
await u.waitUntil(() => textarea.value === ':grinning: :grimacing: ');
|
||||
done();
|
||||
}));
|
||||
|
||||
|
||||
it("properly inserts emojis into the chat textarea",
|
||||
mock.initConverse(
|
||||
['rosterGroupsFetched', 'chatBoxesFetched'], {},
|
||||
async function (done, _converse) {
|
||||
|
||||
const muc_jid = 'lounge@montague.lit';
|
||||
await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
|
||||
const view = _converse.chatboxviews.get(muc_jid);
|
||||
await u.waitUntil(() => view.el.querySelector('converse-emoji-dropdown'));
|
||||
const textarea = view.el.querySelector('textarea.chat-textarea');
|
||||
textarea.value = ':gri';
|
||||
|
||||
// Press tab
|
||||
const tab_event = {
|
||||
'target': textarea,
|
||||
'preventDefault': function preventDefault () {},
|
||||
'stopPropagation': function stopPropagation () {},
|
||||
'keyCode': 9,
|
||||
'key': 'Tab'
|
||||
}
|
||||
textarea.value = ':';
|
||||
view.onKeyDown(tab_event);
|
||||
await u.waitUntil(() => u.isVisible(view.el.querySelector('.emoji-picker__lists')));
|
||||
const picker = view.el.querySelector('converse-emoji-picker');
|
||||
const input = picker.querySelector('.emoji-search');
|
||||
input.dispatchEvent(new KeyboardEvent('keydown', tab_event));
|
||||
await u.waitUntil(() => input.value === ':100:');
|
||||
const enter_event = Object.assign({}, tab_event, {'keyCode': 13, 'key': 'Enter', 'target': input});
|
||||
input.dispatchEvent(new KeyboardEvent('keydown', enter_event));
|
||||
expect(textarea.value).toBe(':100: ');
|
||||
|
||||
textarea.value = ':';
|
||||
view.onKeyDown(tab_event);
|
||||
await u.waitUntil(() => u.isVisible(view.el.querySelector('.emoji-picker__lists')));
|
||||
await u.waitUntil(() => input.value === ':');
|
||||
input.dispatchEvent(new KeyboardEvent('keydown', tab_event));
|
||||
await u.waitUntil(() => input.value === ':100:');
|
||||
await u.waitUntil(() => sizzle('.emojis-lists__container--search .insert-emoji:not(.hidden)', view.el).length === 1, 1000);
|
||||
const emoji = sizzle('.emojis-lists__container--search .insert-emoji:not(.hidden) a', view.el).pop();
|
||||
emoji.click();
|
||||
expect(textarea.value).toBe(':100: ');
|
||||
done();
|
||||
}));
|
||||
|
||||
|
||||
it("allows you to search for particular emojis",
|
||||
mock.initConverse(
|
||||
['rosterGroupsFetched', 'chatBoxesFetched'], {},
|
||||
async function (done, _converse) {
|
||||
|
||||
const muc_jid = 'lounge@montague.lit';
|
||||
await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
|
||||
const view = _converse.chatboxviews.get(muc_jid);
|
||||
await u.waitUntil(() => view.el.querySelector('converse-emoji-dropdown'));
|
||||
const toolbar = view.el.querySelector('converse-chat-toolbar');
|
||||
toolbar.querySelector('.toggle-emojis').click();
|
||||
await u.waitUntil(() => u.isVisible(view.el.querySelector('.emoji-picker__lists')));
|
||||
await u.waitUntil(() => sizzle('converse-chat-toolbar .insert-emoji:not(.hidden)', view.el).length === 1589);
|
||||
|
||||
const input = view.el.querySelector('.emoji-search');
|
||||
input.value = 'smiley';
|
||||
const event = {
|
||||
'target': input,
|
||||
'preventDefault': function preventDefault () {},
|
||||
'stopPropagation': function stopPropagation () {}
|
||||
};
|
||||
input.dispatchEvent(new KeyboardEvent('keydown', event));
|
||||
|
||||
await u.waitUntil(() => sizzle('.emojis-lists__container--search .insert-emoji:not(.hidden)', view.el).length === 2, 1000);
|
||||
let visible_emojis = sizzle('.emojis-lists__container--search .insert-emoji:not(.hidden)', view.el);
|
||||
expect(visible_emojis[0].getAttribute('data-emoji')).toBe(':smiley:');
|
||||
expect(visible_emojis[1].getAttribute('data-emoji')).toBe(':smiley_cat:');
|
||||
|
||||
// Check that pressing enter without an unambiguous match does nothing
|
||||
const enter_event = Object.assign({}, event, {'keyCode': 13});
|
||||
input.dispatchEvent(new KeyboardEvent('keydown', enter_event));
|
||||
expect(input.value).toBe('smiley');
|
||||
|
||||
// Check that search results update when chars are deleted
|
||||
input.value = 'sm';
|
||||
input.dispatchEvent(new KeyboardEvent('keydown', event));
|
||||
await u.waitUntil(() => sizzle('.emojis-lists__container--search .insert-emoji:not(.hidden)', view.el).length === 25, 1000);
|
||||
|
||||
input.value = 'smiley';
|
||||
input.dispatchEvent(new KeyboardEvent('keydown', event));
|
||||
await u.waitUntil(() => sizzle('.emojis-lists__container--search .insert-emoji:not(.hidden)', view.el).length === 2, 1000);
|
||||
|
||||
// Test that TAB autocompletes the to first match
|
||||
const tab_event = Object.assign({}, event, {'keyCode': 9, 'key': 'Tab'});
|
||||
input.dispatchEvent(new KeyboardEvent('keydown', tab_event));
|
||||
|
||||
await u.waitUntil(() => input.value === ':smiley:');
|
||||
await u.waitUntil(() => sizzle(".emojis-lists__container--search .insert-emoji:not('.hidden')", view.el).length === 1, 1000);
|
||||
visible_emojis = sizzle(".emojis-lists__container--search .insert-emoji:not('.hidden')", view.el);
|
||||
expect(visible_emojis[0].getAttribute('data-emoji')).toBe(':smiley:');
|
||||
|
||||
// Check that ENTER now inserts the match
|
||||
input.dispatchEvent(new KeyboardEvent('keydown', enter_event));
|
||||
await u.waitUntil(() => input.value === '');
|
||||
expect(view.el.querySelector('textarea.chat-textarea').value).toBe(':smiley: ');
|
||||
done();
|
||||
}));
|
||||
});
|
||||
|
||||
describe("A Chat Message", function () {
|
||||
|
||||
it("will display larger if it's only emojis",
|
||||
mock.initConverse(
|
||||
['rosterGroupsFetched', 'chatBoxesFetched'], {'use_system_emojis': true},
|
||||
async function (done, _converse) {
|
||||
|
||||
await mock.waitForRoster(_converse, 'current');
|
||||
const sender_jid = mock.cur_names[1].replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
_converse.handleMessageStanza($msg({
|
||||
'from': sender_jid,
|
||||
'to': _converse.connection.jid,
|
||||
'type': 'chat',
|
||||
'id': _converse.connection.getUniqueId()
|
||||
}).c('body').t('😇').up()
|
||||
.c('active', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree());
|
||||
await new Promise(resolve => _converse.on('chatBoxViewInitialized', resolve));
|
||||
const view = _converse.api.chatviews.get(sender_jid);
|
||||
await new Promise(resolve => view.model.messages.once('rendered', resolve));
|
||||
await u.waitUntil(() => u.hasClass('chat-msg__text--larger', view.content.querySelector('.chat-msg__text')));
|
||||
|
||||
_converse.handleMessageStanza($msg({
|
||||
'from': sender_jid,
|
||||
'to': _converse.connection.jid,
|
||||
'type': 'chat',
|
||||
'id': _converse.connection.getUniqueId()
|
||||
}).c('body').t('😇 Hello world! 😇 😇').up()
|
||||
.c('active', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree());
|
||||
await new Promise(resolve => view.model.messages.once('rendered', resolve));
|
||||
|
||||
let sel = '.message:last-child .chat-msg__text';
|
||||
await u.waitUntil(() => u.hasClass('chat-msg__text--larger', view.content.querySelector(sel)));
|
||||
|
||||
// Test that a modified message that no longer contains only
|
||||
// emojis now renders normally again.
|
||||
const textarea = view.el.querySelector('textarea.chat-textarea');
|
||||
textarea.value = ':poop: :innocent:';
|
||||
view.onKeyDown({
|
||||
target: textarea,
|
||||
preventDefault: function preventDefault () {},
|
||||
keyCode: 13 // Enter
|
||||
});
|
||||
await new Promise(resolve => view.model.messages.once('rendered', resolve));
|
||||
expect(view.el.querySelectorAll('.chat-msg').length).toBe(3);
|
||||
const last_msg_sel = 'converse-chat-message:last-child .chat-msg__text';
|
||||
await u.waitUntil(() => view.content.querySelector(last_msg_sel).textContent === '💩 😇');
|
||||
|
||||
expect(textarea.value).toBe('');
|
||||
view.onKeyDown({
|
||||
target: textarea,
|
||||
keyCode: 38 // Up arrow
|
||||
});
|
||||
expect(textarea.value).toBe('💩 😇');
|
||||
expect(view.model.messages.at(2).get('correcting')).toBe(true);
|
||||
sel = 'converse-chat-message:last-child .chat-msg'
|
||||
await u.waitUntil(() => u.hasClass('correcting', view.el.querySelector(sel)), 500);
|
||||
textarea.value = textarea.value += 'This is no longer an emoji-only message';
|
||||
view.onKeyDown({
|
||||
target: textarea,
|
||||
preventDefault: function preventDefault () {},
|
||||
keyCode: 13 // Enter
|
||||
});
|
||||
await new Promise(resolve => view.model.messages.once('rendered', resolve));
|
||||
expect(view.model.messages.models.length).toBe(3);
|
||||
let message = view.content.querySelector(last_msg_sel);
|
||||
expect(u.hasClass('chat-msg__text--larger', message)).toBe(false);
|
||||
|
||||
textarea.value = ':smile: Hello world!';
|
||||
view.onKeyDown({
|
||||
target: textarea,
|
||||
preventDefault: function preventDefault () {},
|
||||
keyCode: 13 // Enter
|
||||
});
|
||||
await new Promise(resolve => view.model.messages.once('rendered', resolve));
|
||||
|
||||
textarea.value = ':smile: :smiley: :imp:';
|
||||
view.onKeyDown({
|
||||
target: textarea,
|
||||
preventDefault: function preventDefault () {},
|
||||
keyCode: 13 // Enter
|
||||
});
|
||||
await new Promise(resolve => view.model.messages.once('rendered', resolve));
|
||||
|
||||
message = view.content.querySelector('.message:last-child .chat-msg__text');
|
||||
expect(u.hasClass('chat-msg__text--larger', message)).toBe(true);
|
||||
done()
|
||||
}));
|
||||
|
||||
it("can render emojis as images",
|
||||
mock.initConverse(
|
||||
['rosterGroupsFetched', 'chatBoxesFetched'], {'use_system_emojis': false},
|
||||
async function (done, _converse) {
|
||||
|
||||
await mock.waitForRoster(_converse, 'current');
|
||||
const sender_jid = mock.cur_names[1].replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
_converse.handleMessageStanza($msg({
|
||||
'from': sender_jid,
|
||||
'to': _converse.connection.jid,
|
||||
'type': 'chat',
|
||||
'id': _converse.connection.getUniqueId()
|
||||
}).c('body').t('😇').up()
|
||||
.c('active', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree());
|
||||
await new Promise(resolve => _converse.on('chatBoxViewInitialized', resolve));
|
||||
const view = _converse.api.chatviews.get(sender_jid);
|
||||
await new Promise(resolve => view.model.messages.once('rendered', resolve));
|
||||
await u.waitUntil(() => u.hasClass('chat-msg__text--larger', view.content.querySelector('.chat-msg__text')));
|
||||
|
||||
const last_msg_sel = 'converse-chat-message:last-child .chat-msg__text';
|
||||
let message = view.content.querySelector(last_msg_sel);
|
||||
await u.waitUntil(() => u.isVisible(message.querySelector('.emoji')), 1000);
|
||||
let imgs = message.querySelectorAll('.emoji');
|
||||
expect(imgs.length).toBe(1);
|
||||
expect(imgs[0].src).toBe(_converse.api.settings.get('emoji_image_path')+'/72x72/1f607.png');
|
||||
|
||||
const textarea = view.el.querySelector('textarea.chat-textarea');
|
||||
textarea.value = ':poop: :innocent:';
|
||||
view.onKeyDown({
|
||||
target: textarea,
|
||||
preventDefault: function preventDefault () {},
|
||||
keyCode: 13 // Enter
|
||||
});
|
||||
await new Promise(resolve => view.model.messages.once('rendered', resolve));
|
||||
message = view.content.querySelector(last_msg_sel);
|
||||
await u.waitUntil(() => u.isVisible(message.querySelector('.emoji')), 1000);
|
||||
imgs = message.querySelectorAll('.emoji');
|
||||
expect(imgs.length).toBe(2);
|
||||
expect(imgs[0].src).toBe(_converse.api.settings.get('emoji_image_path')+'/72x72/1f4a9.png');
|
||||
expect(imgs[1].src).toBe(_converse.api.settings.get('emoji_image_path')+'/72x72/1f607.png');
|
||||
done()
|
||||
}));
|
||||
|
||||
it("can show custom emojis",
|
||||
mock.initConverse(
|
||||
['rosterGroupsFetched', 'chatBoxesFetched'],
|
||||
{ emoji_categories: {
|
||||
"smileys": ":grinning:",
|
||||
"people": ":thumbsup:",
|
||||
"activity": ":soccer:",
|
||||
"travel": ":motorcycle:",
|
||||
"objects": ":bomb:",
|
||||
"nature": ":rainbow:",
|
||||
"food": ":hotdog:",
|
||||
"symbols": ":musical_note:",
|
||||
"flags": ":flag_ac:",
|
||||
"custom": ':xmpp:'
|
||||
} },
|
||||
async function (done, _converse) {
|
||||
|
||||
await mock.waitForRoster(_converse, 'current', 1);
|
||||
const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
await mock.openChatBoxFor(_converse, contact_jid);
|
||||
const view = _converse.api.chatviews.get(contact_jid);
|
||||
|
||||
const toolbar = await u.waitUntil(() => view.el.querySelector('.chat-toolbar'));
|
||||
toolbar.querySelector('.toggle-emojis').click();
|
||||
await u.waitUntil(() => u.isVisible(view.el.querySelector('.emoji-picker__lists')), 1000);
|
||||
const picker = await u.waitUntil(() => view.el.querySelector('converse-emoji-picker'), 1000);
|
||||
const custom_category = picker.querySelector('.pick-category[data-category="custom"]');
|
||||
expect(custom_category.innerHTML.replace(/<!---->/g, '').trim()).toBe(
|
||||
'<img class="emoji" draggable="false" title=":xmpp:" alt=":xmpp:" src="/dist/images/custom_emojis/xmpp.png">');
|
||||
|
||||
const textarea = view.el.querySelector('textarea.chat-textarea');
|
||||
textarea.value = 'Running tests for :converse:';
|
||||
view.onKeyDown({
|
||||
target: textarea,
|
||||
preventDefault: function preventDefault () {},
|
||||
keyCode: 13 // Enter
|
||||
});
|
||||
await new Promise(resolve => view.model.messages.once('rendered', resolve));
|
||||
const body = view.el.querySelector('converse-chat-message-body');
|
||||
await u.waitUntil(() => body.innerHTML.replace(/<!---->/g, '').trim() ===
|
||||
'Running tests for <img class="emoji" draggable="false" title=":converse:" alt=":converse:" src="/dist/images/custom_emojis/converse.png">');
|
||||
done();
|
||||
}));
|
||||
});
|
||||
});
|
@ -1,61 +0,0 @@
|
||||
/*global mock */
|
||||
|
||||
describe("The _converse Event Emitter", function() {
|
||||
|
||||
it("allows you to subscribe to emitted events", mock.initConverse((done, _converse) => {
|
||||
this.callback = function () {};
|
||||
spyOn(this, 'callback');
|
||||
_converse.on('connected', this.callback);
|
||||
_converse.api.trigger('connected');
|
||||
expect(this.callback).toHaveBeenCalled();
|
||||
_converse.api.trigger('connected');
|
||||
expect(this.callback.calls.count(), 2);
|
||||
_converse.api.trigger('connected');
|
||||
expect(this.callback.calls.count(), 3);
|
||||
done();
|
||||
}));
|
||||
|
||||
it("allows you to listen once for an emitted event", mock.initConverse((done, _converse) => {
|
||||
this.callback = function () {};
|
||||
spyOn(this, 'callback');
|
||||
_converse.once('connected', this.callback);
|
||||
_converse.api.trigger('connected');
|
||||
expect(this.callback).toHaveBeenCalled();
|
||||
_converse.api.trigger('connected');
|
||||
expect(this.callback.calls.count(), 1);
|
||||
_converse.api.trigger('connected');
|
||||
expect(this.callback.calls.count(), 1);
|
||||
done();
|
||||
}));
|
||||
|
||||
it("allows you to stop listening or subscribing to an event", mock.initConverse((done, _converse) => {
|
||||
this.callback = function () {};
|
||||
this.anotherCallback = function () {};
|
||||
this.neverCalled = function () {};
|
||||
|
||||
spyOn(this, 'callback');
|
||||
spyOn(this, 'anotherCallback');
|
||||
spyOn(this, 'neverCalled');
|
||||
_converse.on('connected', this.callback);
|
||||
_converse.on('connected', this.anotherCallback);
|
||||
|
||||
_converse.api.trigger('connected');
|
||||
expect(this.callback).toHaveBeenCalled();
|
||||
expect(this.anotherCallback).toHaveBeenCalled();
|
||||
|
||||
_converse.off('connected', this.callback);
|
||||
|
||||
_converse.api.trigger('connected');
|
||||
expect(this.callback.calls.count(), 1);
|
||||
expect(this.anotherCallback.calls.count(), 2);
|
||||
|
||||
_converse.once('connected', this.neverCalled);
|
||||
_converse.off('connected', this.neverCalled);
|
||||
|
||||
_converse.api.trigger('connected');
|
||||
expect(this.callback.calls.count(), 1);
|
||||
expect(this.anotherCallback.calls.count(), 3);
|
||||
expect(this.neverCalled).not.toHaveBeenCalled();
|
||||
done();
|
||||
}));
|
||||
});
|
683
spec/mock.js
@ -1,683 +0,0 @@
|
||||
/*global converse */
|
||||
|
||||
const mock = {};
|
||||
window.mock = mock;
|
||||
let _converse, initConverse;
|
||||
|
||||
const converseLoaded = new Promise(resolve => window.addEventListener('converse-loaded', resolve));
|
||||
|
||||
jasmine.DEFAULT_TIMEOUT_INTERVAL = 7000;
|
||||
|
||||
mock.initConverse = function (promise_names=[], settings=null, func) {
|
||||
if (typeof promise_names === "function") {
|
||||
func = promise_names;
|
||||
promise_names = []
|
||||
settings = null;
|
||||
}
|
||||
|
||||
return async done => {
|
||||
if (_converse && _converse.api.connection.connected()) {
|
||||
await _converse.api.user.logout();
|
||||
}
|
||||
const el = document.querySelector('#conversejs');
|
||||
if (el) {
|
||||
el.parentElement.removeChild(el);
|
||||
}
|
||||
document.title = "Converse Tests";
|
||||
|
||||
await converseLoaded;
|
||||
await initConverse(settings);
|
||||
await Promise.all((promise_names || []).map(_converse.api.waitUntil));
|
||||
try {
|
||||
await func(done, _converse);
|
||||
} catch(e) {
|
||||
console.error(e);
|
||||
fail(e);
|
||||
await done();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
window.addEventListener('converse-loaded', () => {
|
||||
const { u, sizzle, Strophe, dayjs, $iq, $msg, $pres } = converse.env;
|
||||
|
||||
mock.waitUntilDiscoConfirmed = async function (_converse, entity_jid, identities, features=[], items=[], type='info') {
|
||||
const iq = await u.waitUntil(() => {
|
||||
return _converse.connection.IQ_stanzas.filter(
|
||||
iq => sizzle(`iq[to="${entity_jid}"] query[xmlns="http://jabber.org/protocol/disco#${type}"]`, iq).length
|
||||
).pop();
|
||||
}, 300);
|
||||
const stanza = $iq({
|
||||
'type': 'result',
|
||||
'from': entity_jid,
|
||||
'to': 'romeo@montague.lit/orchard',
|
||||
'id': iq.getAttribute('id'),
|
||||
}).c('query', {'xmlns': 'http://jabber.org/protocol/disco#'+type});
|
||||
|
||||
identities?.forEach(identity => stanza.c('identity', {'category': identity.category, 'type': identity.type}).up());
|
||||
features?.forEach(feature => stanza.c('feature', {'var': feature}).up());
|
||||
items?.forEach(item => stanza.c('item', {'jid': item}).up());
|
||||
_converse.connection._dataRecv(mock.createRequest(stanza));
|
||||
}
|
||||
|
||||
mock.createRequest = function (iq) {
|
||||
iq = typeof iq.tree == "function" ? iq.tree() : iq;
|
||||
var req = new Strophe.Request(iq, function() {});
|
||||
req.getResponse = function () {
|
||||
var env = new Strophe.Builder('env', {type: 'mock'}).tree();
|
||||
env.appendChild(iq);
|
||||
return env;
|
||||
};
|
||||
return req;
|
||||
};
|
||||
|
||||
mock.closeAllChatBoxes = function (_converse) {
|
||||
return Promise.all(_converse.chatboxviews.map(view => view.close()));
|
||||
};
|
||||
|
||||
mock.toggleControlBox = function () {
|
||||
const toggle = document.querySelector(".toggle-controlbox");
|
||||
if (!u.isVisible(document.querySelector("#controlbox"))) {
|
||||
if (!u.isVisible(toggle)) {
|
||||
u.removeClass('hidden', toggle);
|
||||
}
|
||||
toggle.click();
|
||||
}
|
||||
}
|
||||
|
||||
mock.openControlBox = async function (_converse) {
|
||||
const model = await _converse.api.controlbox.open();
|
||||
await u.waitUntil(() => model.get('connected'));
|
||||
mock.toggleControlBox();
|
||||
return this;
|
||||
};
|
||||
|
||||
mock.closeControlBox = function () {
|
||||
const controlbox = document.querySelector("#controlbox");
|
||||
if (u.isVisible(controlbox)) {
|
||||
const button = controlbox.querySelector(".close-chatbox-button");
|
||||
(button !== null) && button.click();
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
mock.waitUntilBookmarksReturned = async function (_converse, bookmarks=[]) {
|
||||
await mock.waitUntilDiscoConfirmed(
|
||||
_converse, _converse.bare_jid,
|
||||
[{'category': 'pubsub', 'type': 'pep'}],
|
||||
['http://jabber.org/protocol/pubsub#publish-options']
|
||||
);
|
||||
const IQ_stanzas = _converse.connection.IQ_stanzas;
|
||||
const sent_stanza = await u.waitUntil(
|
||||
() => IQ_stanzas.filter(s => sizzle('items[node="storage:bookmarks"]', s).length).pop()
|
||||
);
|
||||
const stanza = $iq({
|
||||
'to': _converse.connection.jid,
|
||||
'type':'result',
|
||||
'id':sent_stanza.getAttribute('id')
|
||||
}).c('pubsub', {'xmlns': Strophe.NS.PUBSUB})
|
||||
.c('items', {'node': 'storage:bookmarks'})
|
||||
.c('item', {'id': 'current'})
|
||||
.c('storage', {'xmlns': 'storage:bookmarks'});
|
||||
bookmarks.forEach(bookmark => {
|
||||
stanza.c('conference', {
|
||||
'name': bookmark.name,
|
||||
'autojoin': bookmark.autojoin,
|
||||
'jid': bookmark.jid
|
||||
}).c('nick').t(bookmark.nick).up().up()
|
||||
});
|
||||
_converse.connection._dataRecv(mock.createRequest(stanza));
|
||||
await _converse.api.waitUntil('bookmarksInitialized');
|
||||
};
|
||||
|
||||
mock.openChatBoxes = function (converse, amount) {
|
||||
for (let i=0; i<amount; i++) {
|
||||
const jid = mock.cur_names[i].replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
converse.roster.get(jid).openChat();
|
||||
}
|
||||
};
|
||||
|
||||
mock.openChatBoxFor = async function (_converse, jid) {
|
||||
await _converse.api.waitUntil('rosterContactsFetched');
|
||||
_converse.roster.get(jid).openChat();
|
||||
return u.waitUntil(() => _converse.chatboxviews.get(jid), 1000);
|
||||
};
|
||||
|
||||
mock.openChatRoomViaModal = async function (_converse, jid, nick='') {
|
||||
// Opens a new chatroom
|
||||
const model = await _converse.api.controlbox.open('controlbox');
|
||||
await u.waitUntil(() => model.get('connected'));
|
||||
await mock.openControlBox(_converse);
|
||||
const view = await _converse.chatboxviews.get('controlbox');
|
||||
const roomspanel = view.roomspanel;
|
||||
roomspanel.el.querySelector('.show-add-muc-modal').click();
|
||||
mock.closeControlBox(_converse);
|
||||
const modal = roomspanel.add_room_modal;
|
||||
await u.waitUntil(() => u.isVisible(modal.el), 1500)
|
||||
modal.el.querySelector('input[name="chatroom"]').value = jid;
|
||||
if (nick) {
|
||||
modal.el.querySelector('input[name="nickname"]').value = nick;
|
||||
}
|
||||
modal.el.querySelector('form input[type="submit"]').click();
|
||||
await u.waitUntil(() => _converse.chatboxviews.get(jid), 1000);
|
||||
return _converse.chatboxviews.get(jid);
|
||||
};
|
||||
|
||||
mock.openChatRoom = function (_converse, room, server) {
|
||||
return _converse.api.rooms.open(`${room}@${server}`);
|
||||
};
|
||||
|
||||
mock.getRoomFeatures = async function (_converse, muc_jid, features=[]) {
|
||||
const room = Strophe.getNodeFromJid(muc_jid);
|
||||
muc_jid = muc_jid.toLowerCase();
|
||||
const stanzas = _converse.connection.IQ_stanzas;
|
||||
const stanza = await u.waitUntil(() => stanzas.filter(
|
||||
iq => iq.querySelector(
|
||||
`iq[to="${muc_jid}"] query[xmlns="http://jabber.org/protocol/disco#info"]`
|
||||
)).pop()
|
||||
);
|
||||
const features_stanza = $iq({
|
||||
'from': muc_jid,
|
||||
'id': stanza.getAttribute('id'),
|
||||
'to': 'romeo@montague.lit/desktop',
|
||||
'type': 'result'
|
||||
}).c('query', { 'xmlns': 'http://jabber.org/protocol/disco#info'})
|
||||
.c('identity', {
|
||||
'category': 'conference',
|
||||
'name': room[0].toUpperCase() + room.slice(1),
|
||||
'type': 'text'
|
||||
}).up();
|
||||
|
||||
features = features.length ? features : mock.default_muc_features;
|
||||
features.forEach(f => features_stanza.c('feature', {'var': f}).up());
|
||||
features_stanza.c('x', { 'xmlns':'jabber:x:data', 'type':'result'})
|
||||
.c('field', {'var':'FORM_TYPE', 'type':'hidden'})
|
||||
.c('value').t('http://jabber.org/protocol/muc#roominfo').up().up()
|
||||
.c('field', {'type':'text-single', 'var':'muc#roominfo_description', 'label':'Description'})
|
||||
.c('value').t('This is the description').up().up()
|
||||
.c('field', {'type':'text-single', 'var':'muc#roominfo_occupants', 'label':'Number of occupants'})
|
||||
.c('value').t(0);
|
||||
_converse.connection._dataRecv(mock.createRequest(features_stanza));
|
||||
};
|
||||
|
||||
|
||||
mock.waitForReservedNick = async function (_converse, muc_jid, nick) {
|
||||
const stanzas = _converse.connection.IQ_stanzas;
|
||||
const selector = `iq[to="${muc_jid.toLowerCase()}"] query[node="x-roomuser-item"]`;
|
||||
const iq = await u.waitUntil(() => stanzas.filter(s => sizzle(selector, s).length).pop());
|
||||
|
||||
// We remove the stanza, otherwise we might get stale stanzas returned in our filter above.
|
||||
stanzas.splice(stanzas.indexOf(iq), 1)
|
||||
|
||||
// The XMPP server returns the reserved nick for this user.
|
||||
const IQ_id = iq.getAttribute('id');
|
||||
const stanza = $iq({
|
||||
'type': 'result',
|
||||
'id': IQ_id,
|
||||
'from': muc_jid,
|
||||
'to': _converse.connection.jid
|
||||
}).c('query', {'xmlns': 'http://jabber.org/protocol/disco#info', 'node': 'x-roomuser-item'});
|
||||
if (nick) {
|
||||
stanza.c('identity', {'category': 'conference', 'name': nick, 'type': 'text'});
|
||||
}
|
||||
_converse.connection._dataRecv(mock.createRequest(stanza));
|
||||
if (nick) {
|
||||
return u.waitUntil(() => nick);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
mock.returnMemberLists = async function (_converse, muc_jid, members=[], affiliations=['member', 'owner', 'admin']) {
|
||||
if (affiliations.length === 0) {
|
||||
return;
|
||||
}
|
||||
const stanzas = _converse.connection.IQ_stanzas;
|
||||
|
||||
if (affiliations.includes('member')) {
|
||||
const member_IQ = await u.waitUntil(() =>
|
||||
stanzas.filter(s => sizzle(`iq[to="${muc_jid}"] query[xmlns="${Strophe.NS.MUC_ADMIN}"] item[affiliation="member"]`, s).length
|
||||
).pop());
|
||||
const member_list_stanza = $iq({
|
||||
'from': 'coven@chat.shakespeare.lit',
|
||||
'id': member_IQ.getAttribute('id'),
|
||||
'to': 'romeo@montague.lit/orchard',
|
||||
'type': 'result'
|
||||
}).c('query', {'xmlns': Strophe.NS.MUC_ADMIN});
|
||||
members.filter(m => m.affiliation === 'member').forEach(m => {
|
||||
member_list_stanza.c('item', {
|
||||
'affiliation': m.affiliation,
|
||||
'jid': m.jid,
|
||||
'nick': m.nick
|
||||
});
|
||||
});
|
||||
_converse.connection._dataRecv(mock.createRequest(member_list_stanza));
|
||||
}
|
||||
|
||||
if (affiliations.includes('admin')) {
|
||||
const admin_IQ = await u.waitUntil(() => stanzas.filter(
|
||||
s => sizzle(`iq[to="${muc_jid}"] query[xmlns="${Strophe.NS.MUC_ADMIN}"] item[affiliation="admin"]`, s).length
|
||||
).pop());
|
||||
const admin_list_stanza = $iq({
|
||||
'from': 'coven@chat.shakespeare.lit',
|
||||
'id': admin_IQ.getAttribute('id'),
|
||||
'to': 'romeo@montague.lit/orchard',
|
||||
'type': 'result'
|
||||
}).c('query', {'xmlns': Strophe.NS.MUC_ADMIN});
|
||||
members.filter(m => m.affiliation === 'admin').forEach(m => {
|
||||
admin_list_stanza.c('item', {
|
||||
'affiliation': m.affiliation,
|
||||
'jid': m.jid,
|
||||
'nick': m.nick
|
||||
});
|
||||
});
|
||||
_converse.connection._dataRecv(mock.createRequest(admin_list_stanza));
|
||||
}
|
||||
|
||||
if (affiliations.includes('owner')) {
|
||||
const owner_IQ = await u.waitUntil(() => stanzas.filter(
|
||||
s => sizzle(`iq[to="${muc_jid}"] query[xmlns="${Strophe.NS.MUC_ADMIN}"] item[affiliation="owner"]`, s).length
|
||||
).pop());
|
||||
const owner_list_stanza = $iq({
|
||||
'from': 'coven@chat.shakespeare.lit',
|
||||
'id': owner_IQ.getAttribute('id'),
|
||||
'to': 'romeo@montague.lit/orchard',
|
||||
'type': 'result'
|
||||
}).c('query', {'xmlns': Strophe.NS.MUC_ADMIN});
|
||||
members.filter(m => m.affiliation === 'owner').forEach(m => {
|
||||
owner_list_stanza.c('item', {
|
||||
'affiliation': m.affiliation,
|
||||
'jid': m.jid,
|
||||
'nick': m.nick
|
||||
});
|
||||
});
|
||||
_converse.connection._dataRecv(mock.createRequest(owner_list_stanza));
|
||||
}
|
||||
return new Promise(resolve => _converse.api.listen.on('membersFetched', resolve));
|
||||
};
|
||||
|
||||
mock.receiveOwnMUCPresence = async function (_converse, muc_jid, nick) {
|
||||
const sent_stanzas = _converse.connection.sent_stanzas;
|
||||
await u.waitUntil(() => sent_stanzas.filter(iq => sizzle('presence history', iq).length).pop());
|
||||
const presence = $pres({
|
||||
to: _converse.connection.jid,
|
||||
from: `${muc_jid}/${nick}`,
|
||||
id: u.getUniqueId()
|
||||
}).c('x').attrs({xmlns:'http://jabber.org/protocol/muc#user'})
|
||||
.c('item').attrs({
|
||||
affiliation: 'owner',
|
||||
jid: _converse.bare_jid,
|
||||
role: 'moderator'
|
||||
}).up()
|
||||
.c('status').attrs({code:'110'});
|
||||
_converse.connection._dataRecv(mock.createRequest(presence));
|
||||
};
|
||||
|
||||
|
||||
mock.openAndEnterChatRoom = async function (_converse, muc_jid, nick, features=[], members=[]) {
|
||||
muc_jid = muc_jid.toLowerCase();
|
||||
const room_creation_promise = _converse.api.rooms.open(muc_jid);
|
||||
await mock.getRoomFeatures(_converse, muc_jid, features);
|
||||
await mock.waitForReservedNick(_converse, muc_jid, nick);
|
||||
// The user has just entered the room (because join was called)
|
||||
// and receives their own presence from the server.
|
||||
// See example 24: https://xmpp.org/extensions/xep-0045.html#enter-pres
|
||||
await mock.receiveOwnMUCPresence(_converse, muc_jid, nick);
|
||||
|
||||
await room_creation_promise;
|
||||
const view = _converse.chatboxviews.get(muc_jid);
|
||||
await u.waitUntil(() => (view.model.session.get('connection_status') === converse.ROOMSTATUS.ENTERED));
|
||||
|
||||
const affs = _converse.muc_fetch_members;
|
||||
const all_affiliations = Array.isArray(affs) ? affs : (affs ? ['member', 'admin', 'owner'] : []);
|
||||
await mock.returnMemberLists(_converse, muc_jid, members, all_affiliations);
|
||||
await view.model.messages.fetched;
|
||||
};
|
||||
|
||||
mock.createContact = async function (_converse, name, ask, requesting, subscription) {
|
||||
const jid = name.replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||
if (_converse.roster.get(jid)) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
const contact = await new Promise((success, error) => {
|
||||
_converse.roster.create({
|
||||
'ask': ask,
|
||||
'fullname': name,
|
||||
'jid': jid,
|
||||
'requesting': requesting,
|
||||
'subscription': subscription
|
||||
}, {success, error});
|
||||
});
|
||||
return contact;
|
||||
};
|
||||
|
||||
mock.createContacts = async function (_converse, type, length) {
|
||||
/* Create current (as opposed to requesting or pending) contacts
|
||||
* for the user's roster.
|
||||
*
|
||||
* These contacts are not grouped. See below.
|
||||
*/
|
||||
await _converse.api.waitUntil('rosterContactsFetched');
|
||||
let names, subscription, requesting, ask;
|
||||
if (type === 'requesting') {
|
||||
names = mock.req_names;
|
||||
subscription = 'none';
|
||||
requesting = true;
|
||||
ask = null;
|
||||
} else if (type === 'pending') {
|
||||
names = mock.pend_names;
|
||||
subscription = 'none';
|
||||
requesting = false;
|
||||
ask = 'subscribe';
|
||||
} else if (type === 'current') {
|
||||
names = mock.cur_names;
|
||||
subscription = 'both';
|
||||
requesting = false;
|
||||
ask = null;
|
||||
} else if (type === 'all') {
|
||||
await this.createContacts(_converse, 'current');
|
||||
await this.createContacts(_converse, 'requesting')
|
||||
await this.createContacts(_converse, 'pending');
|
||||
return this;
|
||||
} else {
|
||||
throw Error("Need to specify the type of contact to create");
|
||||
}
|
||||
const promises = names.slice(0, length).map(n => this.createContact(_converse, n, ask, requesting, subscription));
|
||||
await Promise.all(promises);
|
||||
};
|
||||
|
||||
mock.waitForRoster = async function (_converse, type='current', length=-1, include_nick=true, grouped=true) {
|
||||
const s = `iq[type="get"] query[xmlns="${Strophe.NS.ROSTER}"]`;
|
||||
const iq = await u.waitUntil(() => _converse.connection.IQ_stanzas.filter(iq => sizzle(s, iq).length).pop());
|
||||
|
||||
const result = $iq({
|
||||
'to': _converse.connection.jid,
|
||||
'type': 'result',
|
||||
'id': iq.getAttribute('id')
|
||||
}).c('query', {
|
||||
'xmlns': 'jabber:iq:roster'
|
||||
});
|
||||
if (type === 'pending' || type === 'all') {
|
||||
const pend_names = (length > -1) ? mock.pend_names.slice(0, length) : mock.pend_names;
|
||||
pend_names.map(name =>
|
||||
result.c('item', {
|
||||
jid: name.replace(/ /g,'.').toLowerCase() + '@montague.lit',
|
||||
name: include_nick ? name : undefined,
|
||||
subscription: 'none',
|
||||
ask: 'subscribe'
|
||||
}).up()
|
||||
);
|
||||
}
|
||||
if (type === 'current' || type === 'all') {
|
||||
const cur_names = Object.keys(mock.current_contacts_map);
|
||||
const names = (length > -1) ? cur_names.slice(0, length) : cur_names;
|
||||
names.forEach(name => {
|
||||
result.c('item', {
|
||||
jid: name.replace(/ /g,'.').toLowerCase() + '@montague.lit',
|
||||
name: include_nick ? name : undefined,
|
||||
subscription: 'both',
|
||||
ask: null
|
||||
});
|
||||
if (grouped) {
|
||||
mock.current_contacts_map[name].forEach(g => result.c('group').t(g).up());
|
||||
}
|
||||
result.up();
|
||||
});
|
||||
}
|
||||
_converse.connection._dataRecv(mock.createRequest(result));
|
||||
await _converse.api.waitUntil('rosterContactsFetched');
|
||||
};
|
||||
|
||||
mock.createChatMessage = function (_converse, sender_jid, message) {
|
||||
return $msg({
|
||||
from: sender_jid,
|
||||
to: _converse.connection.jid,
|
||||
type: 'chat',
|
||||
id: (new Date()).getTime()
|
||||
})
|
||||
.c('body').t(message).up()
|
||||
.c('markable', {'xmlns': Strophe.NS.MARKERS}).up()
|
||||
.c('active', {'xmlns': Strophe.NS.CHATSTATES}).tree();
|
||||
}
|
||||
|
||||
mock.sendMessage = function (view, message) {
|
||||
const promise = new Promise(resolve => view.model.messages.once('rendered', resolve));
|
||||
view.el.querySelector('.chat-textarea').value = message;
|
||||
view.onKeyDown({
|
||||
target: view.el.querySelector('textarea.chat-textarea'),
|
||||
preventDefault: () => {},
|
||||
keyCode: 13
|
||||
});
|
||||
return promise;
|
||||
};
|
||||
|
||||
|
||||
window.libsignal = {
|
||||
'SignalProtocolAddress': function (name, device_id) {
|
||||
this.name = name;
|
||||
this.deviceId = device_id;
|
||||
},
|
||||
'SessionCipher': function (storage, remote_address) {
|
||||
this.remoteAddress = remote_address;
|
||||
this.storage = storage;
|
||||
this.encrypt = () => Promise.resolve({
|
||||
'type': 1,
|
||||
'body': 'c1ph3R73X7',
|
||||
'registrationId': '1337'
|
||||
});
|
||||
this.decryptPreKeyWhisperMessage = (key_and_tag) => {
|
||||
return Promise.resolve(key_and_tag);
|
||||
};
|
||||
this.decryptWhisperMessage = (key_and_tag) => {
|
||||
return Promise.resolve(key_and_tag);
|
||||
}
|
||||
},
|
||||
'SessionBuilder': function (storage, remote_address) { // eslint-disable-line no-unused-vars
|
||||
this.processPreKey = function () {
|
||||
return Promise.resolve();
|
||||
}
|
||||
},
|
||||
'KeyHelper': {
|
||||
'generateIdentityKeyPair': function () {
|
||||
return Promise.resolve({
|
||||
'pubKey': new TextEncoder('utf-8').encode('1234'),
|
||||
'privKey': new TextEncoder('utf-8').encode('4321')
|
||||
});
|
||||
},
|
||||
'generateRegistrationId': function () {
|
||||
return '123456789';
|
||||
},
|
||||
'generatePreKey': function (keyid) {
|
||||
return Promise.resolve({
|
||||
'keyId': keyid,
|
||||
'keyPair': {
|
||||
'pubKey': new TextEncoder('utf-8').encode('1234'),
|
||||
'privKey': new TextEncoder('utf-8').encode('4321')
|
||||
}
|
||||
});
|
||||
},
|
||||
'generateSignedPreKey': function (identity_keypair, keyid) {
|
||||
return Promise.resolve({
|
||||
'signature': new TextEncoder('utf-8').encode('11112222333344445555'),
|
||||
'keyId': keyid,
|
||||
'keyPair': {
|
||||
'pubKey': new TextEncoder('utf-8').encode('1234'),
|
||||
'privKey': new TextEncoder('utf-8').encode('4321')
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
mock.default_muc_features = [
|
||||
'http://jabber.org/protocol/muc',
|
||||
'jabber:iq:register',
|
||||
Strophe.NS.SID,
|
||||
Strophe.NS.MAM,
|
||||
'muc_passwordprotected',
|
||||
'muc_hidden',
|
||||
'muc_temporary',
|
||||
'muc_open',
|
||||
'muc_unmoderated',
|
||||
'muc_anonymous'
|
||||
];
|
||||
|
||||
mock.view_mode = 'overlayed';
|
||||
|
||||
// Names from http://www.fakenamegenerator.com/
|
||||
mock.req_names = [
|
||||
'Escalus, prince of Verona', 'The Nurse', 'Paris'
|
||||
];
|
||||
mock.pend_names = [
|
||||
'Lord Capulet', 'Guard', 'Servant'
|
||||
];
|
||||
mock.current_contacts_map = {
|
||||
'Mercutio': ['Colleagues', 'friends & acquaintences'],
|
||||
'Juliet Capulet': ['friends & acquaintences'],
|
||||
'Lady Montague': ['Colleagues', 'Family'],
|
||||
'Lord Montague': ['Family'],
|
||||
'Friar Laurence': ['friends & acquaintences'],
|
||||
'Tybalt': ['friends & acquaintences'],
|
||||
'Lady Capulet': ['ænemies'],
|
||||
'Benviolo': ['friends & acquaintences'],
|
||||
'Balthasar': ['Colleagues'],
|
||||
'Peter': ['Colleagues'],
|
||||
'Abram': ['Colleagues'],
|
||||
'Sampson': ['Colleagues'],
|
||||
'Gregory': ['friends & acquaintences'],
|
||||
'Potpan': [],
|
||||
'Friar John': []
|
||||
};
|
||||
|
||||
const map = mock.current_contacts_map;
|
||||
const groups_map = {};
|
||||
Object.keys(map).forEach(k => {
|
||||
const groups = map[k].length ? map[k] : ["Ungrouped"];
|
||||
Object.values(groups).forEach(g => {
|
||||
groups_map[g] = groups_map[g] ? [...groups_map[g], k] : [k]
|
||||
});
|
||||
});
|
||||
mock.groups_map = groups_map;
|
||||
|
||||
mock.cur_names = Object.keys(mock.current_contacts_map);
|
||||
mock.num_contacts = mock.req_names.length + mock.pend_names.length + mock.cur_names.length;
|
||||
|
||||
mock.groups = {
|
||||
'colleagues': 3,
|
||||
'friends & acquaintences': 3,
|
||||
'Family': 4,
|
||||
'ænemies': 3,
|
||||
'Ungrouped': 2
|
||||
};
|
||||
|
||||
mock.chatroom_names = [
|
||||
'Dyon van de Wege',
|
||||
'Thomas Kalb',
|
||||
'Dirk Theissen',
|
||||
'Felix Hofmann',
|
||||
'Ka Lek',
|
||||
'Anne Ebersbacher'
|
||||
];
|
||||
// TODO: need to also test other roles and affiliations
|
||||
mock.chatroom_roles = {
|
||||
'Anne Ebersbacher': { affiliation: "owner", role: "moderator" },
|
||||
'Dirk Theissen': { affiliation: "admin", role: "moderator" },
|
||||
'Dyon van de Wege': { affiliation: "member", role: "occupant" },
|
||||
'Felix Hofmann': { affiliation: "member", role: "occupant" },
|
||||
'Ka Lek': { affiliation: "member", role: "occupant" },
|
||||
'Thomas Kalb': { affiliation: "member", role: "occupant" }
|
||||
};
|
||||
|
||||
mock.event = {
|
||||
'preventDefault': function () {}
|
||||
};
|
||||
|
||||
function clearIndexedDB () {
|
||||
const promise = u.getResolveablePromise();
|
||||
const db_request = window.indexedDB.open("converse-test-persistent");
|
||||
db_request.onsuccess = function () {
|
||||
const db = db_request.result;
|
||||
const bare_jid = "romeo@montague.lit";
|
||||
let store;
|
||||
try {
|
||||
store= db.transaction([bare_jid], "readwrite").objectStore(bare_jid);
|
||||
} catch (e) {
|
||||
return promise.resolve();
|
||||
}
|
||||
const request = store.clear();
|
||||
request.onsuccess = promise.resolve();
|
||||
request.onerror = promise.resolve();
|
||||
};
|
||||
db_request.onerror = function (ev) {
|
||||
return promise.reject(ev.target.error);
|
||||
}
|
||||
return promise;
|
||||
}
|
||||
|
||||
function clearStores () {
|
||||
[localStorage, sessionStorage].forEach(
|
||||
s => Object.keys(s).forEach(k => k.match(/^converse-test-/) && s.removeItem(k))
|
||||
);
|
||||
const cache_key = `converse.room-bookmarksromeo@montague.lit`;
|
||||
window.sessionStorage.removeItem(cache_key+'fetched');
|
||||
}
|
||||
|
||||
initConverse = async (settings) => {
|
||||
clearStores();
|
||||
await clearIndexedDB();
|
||||
|
||||
_converse = await converse.initialize(Object.assign({
|
||||
'animate': false,
|
||||
'auto_subscribe': false,
|
||||
'bosh_service_url': 'montague.lit/http-bind',
|
||||
'discover_connection_methods': false,
|
||||
'enable_smacks': false,
|
||||
'i18n': 'en',
|
||||
// 'persistent_store': 'IndexedDB',
|
||||
'loglevel': 'warn',
|
||||
'no_trimming': true,
|
||||
'play_sounds': false,
|
||||
'use_emojione': false,
|
||||
'view_mode': mock.view_mode
|
||||
}, settings || {}));
|
||||
|
||||
_converse.ChatBoxViews.prototype.trimChat = function () {};
|
||||
|
||||
_converse.api.vcard.get = function (model, force) {
|
||||
let jid;
|
||||
if (typeof model === 'string' || model instanceof String) {
|
||||
jid = model;
|
||||
} else if (!model.get('vcard_updated') || force) {
|
||||
jid = model.get('jid') || model.get('muc_jid');
|
||||
}
|
||||
let fullname;
|
||||
if (!jid || jid == 'romeo@montague.lit') {
|
||||
jid = 'romeo@montague.lit';
|
||||
fullname = 'Romeo Montague' ;
|
||||
} else {
|
||||
const name = jid.split('@')[0].replace(/\./g, ' ').split(' ');
|
||||
const last = name.length-1;
|
||||
name[0] = name[0].charAt(0).toUpperCase()+name[0].slice(1);
|
||||
name[last] = name[last].charAt(0).toUpperCase()+name[last].slice(1);
|
||||
fullname = name.join(' ');
|
||||
}
|
||||
const vcard = $iq().c('vCard').c('FN').t(fullname).nodeTree;
|
||||
return {
|
||||
'vcard': vcard,
|
||||
'fullname': vcard.querySelector('FN')?.textContent,
|
||||
'image': vcard.querySelector('PHOTO BINVAL')?.textContent,
|
||||
'image_type': vcard.querySelector('PHOTO TYPE')?.textContent,
|
||||
'url': vcard.querySelector('URL')?.textContent,
|
||||
'vcard_updated': dayjs().format(),
|
||||
'vcard_error': undefined
|
||||
};
|
||||
};
|
||||
if (settings?.auto_login !== false) {
|
||||
_converse.api.user.login('romeo@montague.lit/orchard', 'secret');
|
||||
await _converse.api.waitUntil('afterResourceBinding');
|
||||
}
|
||||
window.converse_disable_effects = true;
|
||||
return _converse;
|
||||
}
|
||||
});
|
||||
|
||||
converse.load();
|
@ -1,705 +0,0 @@
|
||||
/*global mock, converse */
|
||||
|
||||
const { Promise, Strophe, $msg, $pres, sizzle, stanza_utils } = converse.env;
|
||||
const u = converse.env.utils;
|
||||
const original_timeout = jasmine.DEFAULT_TIMEOUT_INTERVAL;
|
||||
|
||||
describe("A Groupchat Message", function () {
|
||||
|
||||
beforeEach(() => (jasmine.DEFAULT_TIMEOUT_INTERVAL = 7000));
|
||||
afterEach(() => (jasmine.DEFAULT_TIMEOUT_INTERVAL = original_timeout));
|
||||
|
||||
describe("which is succeeded by an error message", function () {
|
||||
|
||||
it("will have the error displayed below it",
|
||||
mock.initConverse(
|
||||
['rosterGroupsFetched'], {},
|
||||
async function (done, _converse) {
|
||||
|
||||
const muc_jid = 'lounge@montague.lit';
|
||||
await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
|
||||
const view = _converse.api.chatviews.get(muc_jid);
|
||||
const textarea = view.el.querySelector('textarea.chat-textarea');
|
||||
textarea.value = 'hello world'
|
||||
const enter_event = {
|
||||
'target': textarea,
|
||||
'preventDefault': function preventDefault () {},
|
||||
'stopPropagation': function stopPropagation () {},
|
||||
'keyCode': 13 // Enter
|
||||
}
|
||||
view.onKeyDown(enter_event);
|
||||
await new Promise(resolve => view.model.messages.once('rendered', resolve));
|
||||
|
||||
const msg = view.model.messages.at(0);
|
||||
const err_msg_text = "Message rejected because you're sending messages too quickly";
|
||||
const error = u.toStanza(`
|
||||
<message xmlns="jabber:client" id="${msg.get('msgid')}" from="${muc_jid}" to="${_converse.jid}" type="error">
|
||||
<error type="wait">
|
||||
<policy-violation xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>
|
||||
<text xmlns="urn:ietf:params:xml:ns:xmpp-stanzas">${err_msg_text}</text>
|
||||
</error>
|
||||
<body>hello world</body>
|
||||
</message>
|
||||
`);
|
||||
_converse.connection._dataRecv(mock.createRequest(error));
|
||||
expect(await u.waitUntil(() => view.el.querySelector('.chat-msg__error')?.textContent?.trim())).toBe(err_msg_text);
|
||||
expect(view.model.messages.length).toBe(1);
|
||||
const message = view.model.messages.at(0);
|
||||
expect(message.get('received')).toBeUndefined();
|
||||
expect(message.get('body')).toBe('hello world');
|
||||
expect(message.get('error_text')).toBe(err_msg_text);
|
||||
expect(message.get('editable')).toBe(false);
|
||||
done();
|
||||
}));
|
||||
});
|
||||
|
||||
|
||||
describe("an info message", function () {
|
||||
|
||||
it("is not rendered as a followup message",
|
||||
mock.initConverse(
|
||||
['rosterGroupsFetched', 'chatBoxesFetched'], {},
|
||||
async function (done, _converse) {
|
||||
|
||||
const muc_jid = 'lounge@montague.lit';
|
||||
await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
|
||||
const view = _converse.api.chatviews.get(muc_jid);
|
||||
let presence = u.toStanza(`
|
||||
<presence xmlns="jabber:client" to="${_converse.jid}" from="${muc_jid}/romeo">
|
||||
<x xmlns="http://jabber.org/protocol/muc#user">
|
||||
<status code="201"/>
|
||||
<item role="moderator" affiliation="owner" jid="${_converse.jid}"/>
|
||||
<status code="110"/>
|
||||
</x>
|
||||
</presence>
|
||||
`);
|
||||
_converse.connection._dataRecv(mock.createRequest(presence));
|
||||
await u.waitUntil(() => view.el.querySelectorAll('.chat-info').length === 1);
|
||||
|
||||
presence = u.toStanza(`
|
||||
<presence xmlns="jabber:client" to="${_converse.jid}" from="${muc_jid}/romeo1">
|
||||
<x xmlns="http://jabber.org/protocol/muc#user">
|
||||
<status code="210"/>
|
||||
<item role="moderator" affiliation="owner" jid="${_converse.jid}"/>
|
||||
<status code="110"/>
|
||||
</x>
|
||||
</presence>
|
||||
`);
|
||||
_converse.connection._dataRecv(mock.createRequest(presence));
|
||||
await u.waitUntil(() => view.el.querySelectorAll('.chat-info').length === 2);
|
||||
|
||||
const messages = view.el.querySelectorAll('.chat-info');
|
||||
expect(u.hasClass('chat-msg--followup', messages[0])).toBe(false);
|
||||
expect(u.hasClass('chat-msg--followup', messages[1])).toBe(false);
|
||||
done();
|
||||
}));
|
||||
|
||||
it("is not shown if its a duplicate",
|
||||
mock.initConverse(
|
||||
['rosterGroupsFetched', 'chatBoxesFetched'], {},
|
||||
async function (done, _converse) {
|
||||
|
||||
const muc_jid = 'lounge@montague.lit';
|
||||
await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
|
||||
const view = _converse.api.chatviews.get(muc_jid);
|
||||
const presence = u.toStanza(`
|
||||
<presence xmlns="jabber:client" to="${_converse.jid}" from="${muc_jid}/romeo">
|
||||
<x xmlns="http://jabber.org/protocol/muc#user">
|
||||
<status code="201"/>
|
||||
<item role="moderator" affiliation="owner" jid="${_converse.jid}"/>
|
||||
<status code="110"/>
|
||||
</x>
|
||||
</presence>
|
||||
`);
|
||||
// XXX: We wait for createInfoMessages to complete, if we don't
|
||||
// we still get two info messages due to messages
|
||||
// created from presences not being queued and run
|
||||
// sequentially (i.e. by waiting for promises to resolve)
|
||||
// like we do with message stanzas.
|
||||
spyOn(view.model, 'createInfoMessages').and.callThrough();
|
||||
_converse.connection._dataRecv(mock.createRequest(presence));
|
||||
await u.waitUntil(() => view.model.createInfoMessages.calls.count());
|
||||
await u.waitUntil(() => view.el.querySelectorAll('.chat-info').length === 1);
|
||||
|
||||
_converse.connection._dataRecv(mock.createRequest(presence));
|
||||
await u.waitUntil(() => view.model.createInfoMessages.calls.count() === 2);
|
||||
expect(view.el.querySelectorAll('.chat-info').length).toBe(1);
|
||||
done();
|
||||
}));
|
||||
});
|
||||
|
||||
|
||||
it("is rejected if it's an unencapsulated forwarded message",
|
||||
mock.initConverse(
|
||||
['rosterGroupsFetched', 'chatBoxesFetched'], {},
|
||||
async function (done, _converse) {
|
||||
|
||||
const muc_jid = 'lounge@montague.lit';
|
||||
await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
|
||||
const impersonated_jid = `${muc_jid}/alice`;
|
||||
const received_stanza = u.toStanza(`
|
||||
<message to='${_converse.jid}' from='${muc_jid}/mallory' type='groupchat' id='${_converse.connection.getUniqueId()}'>
|
||||
<forwarded xmlns='urn:xmpp:forward:0'>
|
||||
<delay xmlns='urn:xmpp:delay' stamp='2019-07-10T23:08:25Z'/>
|
||||
<message from='${impersonated_jid}'
|
||||
id='0202197'
|
||||
to='${_converse.bare_jid}'
|
||||
type='groupchat'
|
||||
xmlns='jabber:client'>
|
||||
<body>Yet I should kill thee with much cherishing.</body>
|
||||
</message>
|
||||
</forwarded>
|
||||
</message>
|
||||
`);
|
||||
const view = _converse.api.chatviews.get(muc_jid);
|
||||
spyOn(view.model, 'onMessage').and.callThrough();
|
||||
spyOn(converse.env.log, 'error');
|
||||
_converse.connection._dataRecv(mock.createRequest(received_stanza));
|
||||
await u.waitUntil(() => view.model.onMessage.calls.count() === 1);
|
||||
expect(converse.env.log.error).toHaveBeenCalledWith(
|
||||
`Ignoring unencapsulated forwarded message from ${muc_jid}/mallory`
|
||||
);
|
||||
expect(view.el.querySelectorAll('.chat-msg').length).toBe(0);
|
||||
expect(view.model.messages.length).toBe(0);
|
||||
done();
|
||||
}));
|
||||
|
||||
it("can contain a chat state notification and will still be shown",
|
||||
mock.initConverse(
|
||||
['rosterGroupsFetched', 'chatBoxesFetched'], {},
|
||||
async function (done, _converse) {
|
||||
|
||||
const muc_jid = 'lounge@montague.lit';
|
||||
await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
|
||||
const view = _converse.api.chatviews.get(muc_jid);
|
||||
if (!view.el.querySelectorAll('.chat-area').length) { view.renderChatArea(); }
|
||||
const message = 'romeo: Your attention is required';
|
||||
const nick = mock.chatroom_names[0],
|
||||
msg = $msg({
|
||||
from: 'lounge@montague.lit/'+nick,
|
||||
id: u.getUniqueId(),
|
||||
to: 'romeo@montague.lit',
|
||||
type: 'groupchat'
|
||||
}).c('body').t(message)
|
||||
.c('active', {'xmlns': "http://jabber.org/protocol/chatstates"})
|
||||
.tree();
|
||||
await view.model.handleMessageStanza(msg);
|
||||
await new Promise(resolve => view.model.messages.once('rendered', resolve));
|
||||
expect(view.el.querySelector('.chat-msg')).not.toBe(null);
|
||||
done();
|
||||
}));
|
||||
|
||||
it("can not be expected to have a unique id attribute",
|
||||
mock.initConverse(
|
||||
['rosterGroupsFetched', 'chatBoxesFetched'], {},
|
||||
async function (done, _converse) {
|
||||
|
||||
const muc_jid = 'lounge@montague.lit';
|
||||
await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
|
||||
const view = _converse.api.chatviews.get(muc_jid);
|
||||
if (!view.el.querySelectorAll('.chat-area').length) { view.renderChatArea(); }
|
||||
const id = u.getUniqueId();
|
||||
let msg = $msg({
|
||||
from: 'lounge@montague.lit/some1',
|
||||
id: id,
|
||||
to: 'romeo@montague.lit',
|
||||
type: 'groupchat'
|
||||
}).c('body').t('First message').tree();
|
||||
await view.model.handleMessageStanza(msg);
|
||||
await u.waitUntil(() => view.el.querySelectorAll('.chat-msg').length === 1);
|
||||
|
||||
msg = $msg({
|
||||
from: 'lounge@montague.lit/some2',
|
||||
id: id,
|
||||
to: 'romeo@montague.lit',
|
||||
type: 'groupchat'
|
||||
}).c('body').t('Another message').tree();
|
||||
await view.model.handleMessageStanza(msg);
|
||||
await u.waitUntil(() => view.el.querySelectorAll('.chat-msg').length === 2);
|
||||
expect(view.model.messages.length).toBe(2);
|
||||
done();
|
||||
}));
|
||||
|
||||
it("is ignored if it has the same archive-id of an already received one",
|
||||
mock.initConverse(
|
||||
['rosterGroupsFetched'], {},
|
||||
async function (done, _converse) {
|
||||
|
||||
const muc_jid = 'room@muc.example.com';
|
||||
await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
|
||||
const view = _converse.api.chatviews.get(muc_jid);
|
||||
spyOn(view.model, 'getDuplicateMessage').and.callThrough();
|
||||
let stanza = u.toStanza(`
|
||||
<message xmlns="jabber:client"
|
||||
from="room@muc.example.com/some1"
|
||||
to="${_converse.connection.jid}"
|
||||
type="groupchat">
|
||||
<body>Typical body text</body>
|
||||
<stanza-id xmlns="urn:xmpp:sid:0"
|
||||
id="5f3dbc5e-e1d3-4077-a492-693f3769c7ad"
|
||||
by="room@muc.example.com"/>
|
||||
</message>`);
|
||||
_converse.connection._dataRecv(mock.createRequest(stanza));
|
||||
await u.waitUntil(() => view.model.messages.length === 1);
|
||||
await u.waitUntil(() => view.model.getDuplicateMessage.calls.count() === 1);
|
||||
let result = await view.model.getDuplicateMessage.calls.all()[0].returnValue;
|
||||
expect(result).toBe(undefined);
|
||||
|
||||
stanza = u.toStanza(`
|
||||
<message xmlns="jabber:client"
|
||||
to="${_converse.connection.jid}"
|
||||
from="room@muc.example.com">
|
||||
<result xmlns="urn:xmpp:mam:2" queryid="82d9db27-6cf8-4787-8c2c-5a560263d823" id="5f3dbc5e-e1d3-4077-a492-693f3769c7ad">
|
||||
<forwarded xmlns="urn:xmpp:forward:0">
|
||||
<delay xmlns="urn:xmpp:delay" stamp="2018-01-09T06:17:23Z"/>
|
||||
<message from="room@muc.example.com/some1" type="groupchat">
|
||||
<body>Typical body text</body>
|
||||
</message>
|
||||
</forwarded>
|
||||
</result>
|
||||
</message>`);
|
||||
|
||||
spyOn(view.model, 'updateMessage');
|
||||
view.model.handleMAMResult({ 'messages': [stanza] });
|
||||
await u.waitUntil(() => view.model.getDuplicateMessage.calls.count() === 2);
|
||||
result = await view.model.getDuplicateMessage.calls.all()[1].returnValue;
|
||||
expect(result instanceof _converse.Message).toBe(true);
|
||||
expect(view.model.messages.length).toBe(1);
|
||||
await u.waitUntil(() => view.model.updateMessage.calls.count());
|
||||
done();
|
||||
}));
|
||||
|
||||
it("is ignored if it has the same stanza-id of an already received one",
|
||||
mock.initConverse(
|
||||
['rosterGroupsFetched'], {},
|
||||
async function (done, _converse) {
|
||||
|
||||
const muc_jid = 'room@muc.example.com';
|
||||
await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
|
||||
const view = _converse.api.chatviews.get(muc_jid);
|
||||
spyOn(view.model, 'getStanzaIdQueryAttrs').and.callThrough();
|
||||
let stanza = u.toStanza(`
|
||||
<message xmlns="jabber:client"
|
||||
from="room@muc.example.com/some1"
|
||||
to="${_converse.connection.jid}"
|
||||
type="groupchat">
|
||||
<body>Typical body text</body>
|
||||
<stanza-id xmlns="urn:xmpp:sid:0"
|
||||
id="5f3dbc5e-e1d3-4077-a492-693f3769c7ad"
|
||||
by="room@muc.example.com"/>
|
||||
</message>`);
|
||||
_converse.connection._dataRecv(mock.createRequest(stanza));
|
||||
await u.waitUntil(() => view.model.messages.length === 1);
|
||||
await u.waitUntil(() => view.model.getStanzaIdQueryAttrs.calls.count() === 1);
|
||||
let result = await view.model.getStanzaIdQueryAttrs.calls.all()[0].returnValue;
|
||||
expect(result instanceof Array).toBe(true);
|
||||
expect(result[0] instanceof Object).toBe(true);
|
||||
expect(result[0]['stanza_id room@muc.example.com']).toBe("5f3dbc5e-e1d3-4077-a492-693f3769c7ad");
|
||||
|
||||
stanza = u.toStanza(`
|
||||
<message xmlns="jabber:client"
|
||||
from="room@muc.example.com/some1"
|
||||
to="${_converse.connection.jid}"
|
||||
type="groupchat">
|
||||
<body>Typical body text</body>
|
||||
<stanza-id xmlns="urn:xmpp:sid:0"
|
||||
id="5f3dbc5e-e1d3-4077-a492-693f3769c7ad"
|
||||
by="room@muc.example.com"/>
|
||||
</message>`);
|
||||
spyOn(view.model, 'updateMessage');
|
||||
spyOn(view.model, 'getDuplicateMessage').and.callThrough();
|
||||
_converse.connection._dataRecv(mock.createRequest(stanza));
|
||||
await u.waitUntil(() => view.model.getDuplicateMessage.calls.count());
|
||||
result = await view.model.getDuplicateMessage.calls.all()[0].returnValue;
|
||||
expect(result instanceof _converse.Message).toBe(true);
|
||||
expect(view.model.messages.length).toBe(1);
|
||||
await u.waitUntil(() => view.model.updateMessage.calls.count());
|
||||
done();
|
||||
}));
|
||||
|
||||
it("will be discarded if it's a malicious message meant to look like a carbon copy",
|
||||
mock.initConverse(
|
||||
['rosterGroupsFetched'], {},
|
||||
async function (done, _converse) {
|
||||
|
||||
await mock.waitForRoster(_converse, 'current');
|
||||
await mock.openControlBox(_converse);
|
||||
const muc_jid = 'xsf@muc.xmpp.org';
|
||||
const sender_jid = `${muc_jid}/romeo`;
|
||||
const impersonated_jid = `${muc_jid}/i_am_groot`
|
||||
await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
|
||||
const stanza = $pres({
|
||||
to: 'romeo@montague.lit/_converse.js-29092160',
|
||||
from: sender_jid
|
||||
})
|
||||
.c('x', {xmlns: Strophe.NS.MUC_USER})
|
||||
.c('item', {
|
||||
'affiliation': 'owner',
|
||||
'jid': 'newguy@montague.lit/_converse.js-290929789',
|
||||
'role': 'participant'
|
||||
}).tree();
|
||||
_converse.connection._dataRecv(mock.createRequest(stanza));
|
||||
/*
|
||||
* <message to="romeo@montague.im/poezio" id="718d40df-3948-4798-a99b-35cc9f03cc4f-641" type="groupchat" from="xsf@muc.xmpp.org/romeo">
|
||||
* <received xmlns="urn:xmpp:carbons:2">
|
||||
* <forwarded xmlns="urn:xmpp:forward:0">
|
||||
* <message xmlns="jabber:client" to="xsf@muc.xmpp.org" type="groupchat" from="xsf@muc.xmpp.org/i_am_groot">
|
||||
* <body>I am groot.</body>
|
||||
* </message>
|
||||
* </forwarded>
|
||||
* </received>
|
||||
* </message>
|
||||
*/
|
||||
const msg = $msg({
|
||||
'from': sender_jid,
|
||||
'id': _converse.connection.getUniqueId(),
|
||||
'to': _converse.connection.jid,
|
||||
'type': 'groupchat',
|
||||
'xmlns': 'jabber:client'
|
||||
}).c('received', {'xmlns': 'urn:xmpp:carbons:2'})
|
||||
.c('forwarded', {'xmlns': 'urn:xmpp:forward:0'})
|
||||
.c('message', {
|
||||
'xmlns': 'jabber:client',
|
||||
'from': impersonated_jid,
|
||||
'to': muc_jid,
|
||||
'type': 'groupchat'
|
||||
}).c('body').t('I am groot').tree();
|
||||
const view = _converse.api.chatviews.get(muc_jid);
|
||||
spyOn(converse.env.log, 'error');
|
||||
await view.model.handleMAMResult({ 'messages': [msg] });
|
||||
await u.waitUntil(() => converse.env.log.error.calls.count());
|
||||
expect(converse.env.log.error).toHaveBeenCalledWith(
|
||||
'Invalid Stanza: MUC messages SHOULD NOT be XEP-0280 carbon copied'
|
||||
);
|
||||
expect(view.el.querySelectorAll('.chat-msg').length).toBe(0);
|
||||
expect(view.model.messages.length).toBe(0);
|
||||
done();
|
||||
}));
|
||||
|
||||
it("keeps track of the sender's role and affiliation",
|
||||
mock.initConverse(
|
||||
['rosterGroupsFetched'], {},
|
||||
async function (done, _converse) {
|
||||
|
||||
const muc_jid = 'lounge@montague.lit';
|
||||
await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
|
||||
const view = _converse.api.chatviews.get(muc_jid);
|
||||
let msg = $msg({
|
||||
from: 'lounge@montague.lit/romeo',
|
||||
id: u.getUniqueId(),
|
||||
to: 'romeo@montague.lit',
|
||||
type: 'groupchat'
|
||||
}).c('body').t('I wrote this message!').tree();
|
||||
await view.model.handleMessageStanza(msg);
|
||||
await u.waitUntil(() => view.el.querySelectorAll('.chat-msg').length);
|
||||
expect(view.model.messages.last().occupant.get('affiliation')).toBe('owner');
|
||||
expect(view.model.messages.last().occupant.get('role')).toBe('moderator');
|
||||
expect(view.el.querySelectorAll('.chat-msg').length).toBe(1);
|
||||
expect(sizzle('.chat-msg', view.el).pop().classList.value.trim()).toBe('message chat-msg groupchat chat-msg--with-avatar moderator owner');
|
||||
let presence = $pres({
|
||||
to:'romeo@montague.lit/orchard',
|
||||
from:'lounge@montague.lit/romeo',
|
||||
id: u.getUniqueId()
|
||||
}).c('x').attrs({xmlns:'http://jabber.org/protocol/muc#user'})
|
||||
.c('item').attrs({
|
||||
affiliation: 'member',
|
||||
jid: 'romeo@montague.lit/orchard',
|
||||
role: 'participant'
|
||||
}).up()
|
||||
.c('status').attrs({code:'110'}).up()
|
||||
.c('status').attrs({code:'210'}).nodeTree;
|
||||
_converse.connection._dataRecv(mock.createRequest(presence));
|
||||
|
||||
msg = $msg({
|
||||
from: 'lounge@montague.lit/romeo',
|
||||
id: u.getUniqueId(),
|
||||
to: 'romeo@montague.lit',
|
||||
type: 'groupchat'
|
||||
}).c('body').t('Another message!').tree();
|
||||
await view.model.handleMessageStanza(msg);
|
||||
await new Promise(resolve => view.model.messages.once('rendered', resolve));
|
||||
expect(view.model.messages.last().occupant.get('affiliation')).toBe('member');
|
||||
expect(view.model.messages.last().occupant.get('role')).toBe('participant');
|
||||
expect(view.el.querySelectorAll('.chat-msg').length).toBe(2);
|
||||
expect(sizzle('.chat-msg', view.el).pop().classList.value.trim()).toBe('message chat-msg groupchat chat-msg--with-avatar participant member');
|
||||
|
||||
presence = $pres({
|
||||
to:'romeo@montague.lit/orchard',
|
||||
from:'lounge@montague.lit/romeo',
|
||||
id: u.getUniqueId()
|
||||
}).c('x').attrs({xmlns:'http://jabber.org/protocol/muc#user'})
|
||||
.c('item').attrs({
|
||||
affiliation: 'owner',
|
||||
jid: 'romeo@montague.lit/orchard',
|
||||
role: 'moderator'
|
||||
}).up()
|
||||
.c('status').attrs({code:'110'}).up()
|
||||
.c('status').attrs({code:'210'}).nodeTree;
|
||||
_converse.connection._dataRecv(mock.createRequest(presence));
|
||||
|
||||
view.model.sendMessage('hello world');
|
||||
await u.waitUntil(() => view.el.querySelectorAll('.chat-msg').length === 3);
|
||||
|
||||
const occupant = await u.waitUntil(() => view.model.messages.filter(m => m.get('type') === 'groupchat')[2].occupant);
|
||||
expect(occupant.get('affiliation')).toBe('owner');
|
||||
expect(occupant.get('role')).toBe('moderator');
|
||||
expect(view.el.querySelectorAll('.chat-msg').length).toBe(3);
|
||||
await u.waitUntil(() => sizzle('.chat-msg', view.el).pop().classList.value.trim() === 'message chat-msg groupchat chat-msg--with-avatar moderator owner');
|
||||
|
||||
const add_events = view.model.occupants._events.add.length;
|
||||
msg = $msg({
|
||||
from: 'lounge@montague.lit/some1',
|
||||
id: u.getUniqueId(),
|
||||
to: 'romeo@montague.lit',
|
||||
type: 'groupchat'
|
||||
}).c('body').t('Message from someone not in the MUC right now').tree();
|
||||
await view.model.handleMessageStanza(msg);
|
||||
await new Promise(resolve => view.model.messages.once('rendered', resolve));
|
||||
expect(view.model.messages.last().occupant).toBeUndefined();
|
||||
// Check that there's a new "add" event handler, for when the occupant appears.
|
||||
expect(view.model.occupants._events.add.length).toBe(add_events+1);
|
||||
|
||||
// Check that the occupant gets added/removed to the message as it
|
||||
// gets removed or added.
|
||||
presence = $pres({
|
||||
to:'romeo@montague.lit/orchard',
|
||||
from:'lounge@montague.lit/some1',
|
||||
id: u.getUniqueId()
|
||||
}).c('x').attrs({xmlns:'http://jabber.org/protocol/muc#user'})
|
||||
.c('item').attrs({jid: 'some1@montague.lit/orchard'});
|
||||
_converse.connection._dataRecv(mock.createRequest(presence));
|
||||
await u.waitUntil(() => view.model.messages.last().occupant);
|
||||
expect(view.model.messages.last().get('message')).toBe('Message from someone not in the MUC right now');
|
||||
expect(view.model.messages.last().occupant.get('nick')).toBe('some1');
|
||||
// Check that the "add" event handler was removed.
|
||||
expect(view.model.occupants._events.add.length).toBe(add_events);
|
||||
|
||||
presence = $pres({
|
||||
to:'romeo@montague.lit/orchard',
|
||||
type: 'unavailable',
|
||||
from:'lounge@montague.lit/some1',
|
||||
id: u.getUniqueId()
|
||||
}).c('x').attrs({xmlns:'http://jabber.org/protocol/muc#user'})
|
||||
.c('item').attrs({jid: 'some1@montague.lit/orchard'});
|
||||
_converse.connection._dataRecv(mock.createRequest(presence));
|
||||
await u.waitUntil(() => !view.model.messages.last().occupant);
|
||||
expect(view.model.messages.last().get('message')).toBe('Message from someone not in the MUC right now');
|
||||
expect(view.model.messages.last().occupant).toBeUndefined();
|
||||
// Check that there's a new "add" event handler, for when the occupant appears.
|
||||
expect(view.model.occupants._events.add.length).toBe(add_events+1);
|
||||
|
||||
presence = $pres({
|
||||
to:'romeo@montague.lit/orchard',
|
||||
from:'lounge@montague.lit/some1',
|
||||
id: u.getUniqueId()
|
||||
}).c('x').attrs({xmlns:'http://jabber.org/protocol/muc#user'})
|
||||
.c('item').attrs({jid: 'some1@montague.lit/orchard'});
|
||||
_converse.connection._dataRecv(mock.createRequest(presence));
|
||||
await u.waitUntil(() => view.model.messages.last().occupant);
|
||||
expect(view.model.messages.last().get('message')).toBe('Message from someone not in the MUC right now');
|
||||
expect(view.model.messages.last().occupant.get('nick')).toBe('some1');
|
||||
// Check that the "add" event handler was removed.
|
||||
expect(view.model.occupants._events.add.length).toBe(add_events);
|
||||
done();
|
||||
}));
|
||||
|
||||
|
||||
it("keeps track whether you are the sender or not",
|
||||
mock.initConverse(
|
||||
['rosterGroupsFetched'], {},
|
||||
async function (done, _converse) {
|
||||
|
||||
const muc_jid = 'lounge@montague.lit';
|
||||
await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
|
||||
const view = _converse.api.chatviews.get(muc_jid);
|
||||
const msg = $msg({
|
||||
from: 'lounge@montague.lit/romeo',
|
||||
id: u.getUniqueId(),
|
||||
to: 'romeo@montague.lit',
|
||||
type: 'groupchat'
|
||||
}).c('body').t('I wrote this message!').tree();
|
||||
await view.model.handleMessageStanza(msg);
|
||||
expect(view.model.messages.last().get('sender')).toBe('me');
|
||||
done();
|
||||
}));
|
||||
|
||||
it("will be shown as received upon MUC reflection",
|
||||
mock.initConverse(
|
||||
['rosterGroupsFetched'], {},
|
||||
async function (done, _converse) {
|
||||
|
||||
await mock.waitForRoster(_converse, 'current');
|
||||
const muc_jid = 'lounge@montague.lit';
|
||||
await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
|
||||
const view = _converse.api.chatviews.get(muc_jid);
|
||||
const textarea = view.el.querySelector('textarea.chat-textarea');
|
||||
textarea.value = 'But soft, what light through yonder airlock breaks?';
|
||||
view.onKeyDown({
|
||||
target: textarea,
|
||||
preventDefault: function preventDefault () {},
|
||||
keyCode: 13 // Enter
|
||||
});
|
||||
await new Promise(resolve => view.model.messages.once('rendered', resolve));
|
||||
expect(view.el.querySelectorAll('.chat-msg__body.chat-msg__body--received').length).toBe(0);
|
||||
|
||||
const msg_obj = view.model.messages.at(0);
|
||||
const stanza = u.toStanza(`
|
||||
<message xmlns="jabber:client"
|
||||
from="${msg_obj.get('from')}"
|
||||
to="${_converse.connection.jid}"
|
||||
type="groupchat">
|
||||
<body>${msg_obj.get('message')}</body>
|
||||
<stanza-id xmlns="urn:xmpp:sid:0"
|
||||
id="5f3dbc5e-e1d3-4077-a492-693f3769c7ad"
|
||||
by="lounge@montague.lit"/>
|
||||
<origin-id xmlns="urn:xmpp:sid:0" id="${msg_obj.get('origin_id')}"/>
|
||||
</message>`);
|
||||
await view.model.handleMessageStanza(stanza);
|
||||
await u.waitUntil(() => view.el.querySelectorAll('.chat-msg__body.chat-msg__body--received').length, 500);
|
||||
expect(view.el.querySelectorAll('.chat-msg__receipt').length).toBe(0);
|
||||
expect(view.el.querySelectorAll('.chat-msg__body.chat-msg__body--received').length).toBe(1);
|
||||
expect(view.model.messages.length).toBe(1);
|
||||
|
||||
const message = view.model.messages.at(0);
|
||||
expect(message.get('stanza_id lounge@montague.lit')).toBe('5f3dbc5e-e1d3-4077-a492-693f3769c7ad');
|
||||
expect(message.get('origin_id')).toBe(msg_obj.get('origin_id'));
|
||||
done();
|
||||
}));
|
||||
|
||||
it("gets updated with its stanza-id upon MUC reflection",
|
||||
mock.initConverse(
|
||||
['rosterGroupsFetched'], {},
|
||||
async function (done, _converse) {
|
||||
|
||||
const muc_jid = 'room@muc.example.com';
|
||||
await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
|
||||
const view = _converse.api.chatviews.get(muc_jid);
|
||||
|
||||
view.model.sendMessage('hello world');
|
||||
await u.waitUntil(() => view.model.messages.length === 1);
|
||||
const msg = view.model.messages.at(0);
|
||||
expect(msg.get('stanza_id')).toBeUndefined();
|
||||
expect(msg.get('origin_id')).toBe(msg.get('origin_id'));
|
||||
|
||||
const stanza = u.toStanza(`
|
||||
<message xmlns="jabber:client"
|
||||
from="room@muc.example.com/romeo"
|
||||
to="${_converse.connection.jid}"
|
||||
type="groupchat">
|
||||
<body>Hello world</body>
|
||||
<stanza-id xmlns="urn:xmpp:sid:0"
|
||||
id="5f3dbc5e-e1d3-4077-a492-693f3769c7ad"
|
||||
by="room@muc.example.com"/>
|
||||
<origin-id xmlns="urn:xmpp:sid:0" id="${msg.get('origin_id')}"/>
|
||||
</message>`);
|
||||
spyOn(view.model, 'updateMessage').and.callThrough();
|
||||
_converse.connection._dataRecv(mock.createRequest(stanza));
|
||||
await u.waitUntil(() => view.model.updateMessage.calls.count() === 1);
|
||||
expect(view.model.messages.length).toBe(1);
|
||||
expect(view.model.messages.at(0).get('stanza_id room@muc.example.com')).toBe("5f3dbc5e-e1d3-4077-a492-693f3769c7ad");
|
||||
expect(view.model.messages.at(0).get('origin_id')).toBe(msg.get('origin_id'));
|
||||
done();
|
||||
}));
|
||||
|
||||
it("can cause a delivery receipt to be returned",
|
||||
mock.initConverse(
|
||||
['rosterGroupsFetched'], {},
|
||||
async function (done, _converse) {
|
||||
|
||||
await mock.waitForRoster(_converse, 'current');
|
||||
const muc_jid = 'lounge@montague.lit';
|
||||
await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
|
||||
const view = _converse.api.chatviews.get(muc_jid);
|
||||
const textarea = view.el.querySelector('textarea.chat-textarea');
|
||||
textarea.value = 'But soft, what light through yonder airlock breaks?';
|
||||
view.onKeyDown({
|
||||
target: textarea,
|
||||
preventDefault: function preventDefault () {},
|
||||
keyCode: 13 // Enter
|
||||
});
|
||||
await new Promise(resolve => view.model.messages.once('rendered', resolve));
|
||||
expect(view.el.querySelectorAll('.chat-msg').length).toBe(1);
|
||||
|
||||
const msg_obj = view.model.messages.at(0);
|
||||
const stanza = u.toStanza(`
|
||||
<message xml:lang="en" to="romeo@montague.lit/orchard"
|
||||
from="lounge@montague.lit/some1" type="groupchat" xmlns="jabber:client">
|
||||
<received xmlns="urn:xmpp:receipts" id="${msg_obj.get('msgid')}"/>
|
||||
<origin-id xmlns="urn:xmpp:sid:0" id="CE08D448-5ED8-4B6A-BB5B-07ED9DFE4FF0"/>
|
||||
</message>`);
|
||||
spyOn(stanza_utils, "parseMUCMessage").and.callThrough();
|
||||
_converse.connection._dataRecv(mock.createRequest(stanza));
|
||||
await u.waitUntil(() => stanza_utils.parseMUCMessage.calls.count() === 1);
|
||||
expect(view.el.querySelectorAll('.chat-msg').length).toBe(1);
|
||||
expect(view.el.querySelectorAll('.chat-msg__receipt').length).toBe(0);
|
||||
done();
|
||||
}));
|
||||
|
||||
it("can cause a chat marker to be returned",
|
||||
mock.initConverse(
|
||||
['rosterGroupsFetched'], {},
|
||||
async function (done, _converse) {
|
||||
|
||||
await mock.waitForRoster(_converse, 'current');
|
||||
const muc_jid = 'lounge@montague.lit';
|
||||
await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
|
||||
const view = _converse.api.chatviews.get(muc_jid);
|
||||
const textarea = view.el.querySelector('textarea.chat-textarea');
|
||||
textarea.value = 'But soft, what light through yonder airlock breaks?';
|
||||
view.onKeyDown({
|
||||
target: textarea,
|
||||
preventDefault: function preventDefault () {},
|
||||
keyCode: 13 // Enter
|
||||
});
|
||||
await new Promise(resolve => view.model.messages.once('rendered', resolve));
|
||||
expect(view.el.querySelectorAll('.chat-msg').length).toBe(1);
|
||||
expect(view.el.querySelector('.chat-msg .chat-msg__body').textContent.trim())
|
||||
.toBe("But soft, what light through yonder airlock breaks?");
|
||||
|
||||
const msg_obj = view.model.messages.at(0);
|
||||
let stanza = u.toStanza(`
|
||||
<message xml:lang="en" to="romeo@montague.lit/orchard"
|
||||
from="lounge@montague.lit/some1" type="groupchat" xmlns="jabber:client">
|
||||
<received xmlns="urn:xmpp:chat-markers:0" id="${msg_obj.get('msgid')}"/>
|
||||
</message>`);
|
||||
const stanza_utils = converse.env.stanza_utils;
|
||||
spyOn(stanza_utils, "getChatMarker").and.callThrough();
|
||||
_converse.connection._dataRecv(mock.createRequest(stanza));
|
||||
await u.waitUntil(() => stanza_utils.getChatMarker.calls.count() === 1);
|
||||
expect(view.el.querySelectorAll('.chat-msg').length).toBe(1);
|
||||
expect(view.el.querySelectorAll('.chat-msg__receipt').length).toBe(0);
|
||||
|
||||
stanza = u.toStanza(`
|
||||
<message xml:lang="en" to="romeo@montague.lit/orchard"
|
||||
from="lounge@montague.lit/some1" type="groupchat" xmlns="jabber:client">
|
||||
<displayed xmlns="urn:xmpp:chat-markers:0" id="${msg_obj.get('msgid')}"/>
|
||||
</message>`);
|
||||
_converse.connection._dataRecv(mock.createRequest(stanza));
|
||||
await u.waitUntil(() => stanza_utils.getChatMarker.calls.count() === 2);
|
||||
expect(view.el.querySelectorAll('.chat-msg').length).toBe(1);
|
||||
expect(view.el.querySelectorAll('.chat-msg__receipt').length).toBe(0);
|
||||
|
||||
stanza = u.toStanza(`
|
||||
<message xml:lang="en" to="romeo@montague.lit/orchard"
|
||||
from="lounge@montague.lit/some1" type="groupchat" xmlns="jabber:client">
|
||||
<acknowledged xmlns="urn:xmpp:chat-markers:0" id="${msg_obj.get('msgid')}"/>
|
||||
</message>`);
|
||||
_converse.connection._dataRecv(mock.createRequest(stanza));
|
||||
|
||||
await u.waitUntil(() => stanza_utils.getChatMarker.calls.count() === 3);
|
||||
expect(view.el.querySelectorAll('.chat-msg').length).toBe(1);
|
||||
expect(view.el.querySelectorAll('.chat-msg__receipt').length).toBe(0);
|
||||
|
||||
stanza = u.toStanza(`
|
||||
<message xml:lang="en" to="romeo@montague.lit/orchard"
|
||||
from="lounge@montague.lit/some1" type="groupchat" xmlns="jabber:client">
|
||||
<body>'tis I!</body>
|
||||
<markable xmlns="urn:xmpp:chat-markers:0"/>
|
||||
</message>`);
|
||||
_converse.connection._dataRecv(mock.createRequest(stanza));
|
||||
await u.waitUntil(() => stanza_utils.getChatMarker.calls.count() === 4);
|
||||
await u.waitUntil(() => view.el.querySelectorAll('.chat-msg').length === 2);
|
||||
expect(view.el.querySelectorAll('.chat-msg__receipt').length).toBe(0);
|
||||
done();
|
||||
}));
|
||||
});
|
@ -1,119 +0,0 @@
|
||||
/*global mock */
|
||||
|
||||
const _ = converse.env._,
|
||||
$iq = converse.env.$iq,
|
||||
Strophe = converse.env.Strophe,
|
||||
sizzle = converse.env.sizzle,
|
||||
u = converse.env.utils;
|
||||
|
||||
describe("Chatrooms", function () {
|
||||
|
||||
|
||||
describe("The /register commmand", function () {
|
||||
|
||||
it("allows you to register your nickname in a room",
|
||||
mock.initConverse(
|
||||
['rosterGroupsFetched', 'chatBoxesFetched'], {'auto_register_muc_nickname': true},
|
||||
async function (done, _converse) {
|
||||
|
||||
const muc_jid = 'coven@chat.shakespeare.lit';
|
||||
await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo')
|
||||
const view = _converse.chatboxviews.get(muc_jid);
|
||||
const textarea = view.el.querySelector('.chat-textarea')
|
||||
textarea.value = '/register';
|
||||
view.onKeyDown({
|
||||
target: textarea,
|
||||
preventDefault: function preventDefault () {},
|
||||
keyCode: 13
|
||||
});
|
||||
let stanza = await u.waitUntil(() => _.filter(
|
||||
_converse.connection.IQ_stanzas,
|
||||
iq => sizzle(`iq[to="${muc_jid}"][type="get"] query[xmlns="jabber:iq:register"]`, iq).length
|
||||
).pop());
|
||||
expect(Strophe.serialize(stanza))
|
||||
.toBe(`<iq from="romeo@montague.lit/orchard" id="${stanza.getAttribute('id')}" to="coven@chat.shakespeare.lit" `+
|
||||
`type="get" xmlns="jabber:client">`+
|
||||
`<query xmlns="jabber:iq:register"/></iq>`);
|
||||
const result = $iq({
|
||||
'from': view.model.get('jid'),
|
||||
'id': stanza.getAttribute('id'),
|
||||
'to': _converse.bare_jid,
|
||||
'type': 'result',
|
||||
}).c('query', {'type': 'jabber:iq:register'})
|
||||
.c('x', {'xmlns': 'jabber:x:data', 'type': 'form'})
|
||||
.c('field', {
|
||||
'label': 'Desired Nickname',
|
||||
'type': 'text-single',
|
||||
'var': 'muc#register_roomnick'
|
||||
}).c('required');
|
||||
_converse.connection._dataRecv(mock.createRequest(result));
|
||||
stanza = await u.waitUntil(() => _.filter(
|
||||
_converse.connection.IQ_stanzas,
|
||||
iq => sizzle(`iq[to="${muc_jid}"][type="set"] query[xmlns="jabber:iq:register"]`, iq).length
|
||||
).pop());
|
||||
|
||||
expect(Strophe.serialize(stanza)).toBe(
|
||||
`<iq from="romeo@montague.lit/orchard" id="${stanza.getAttribute('id')}" to="coven@chat.shakespeare.lit" type="set" xmlns="jabber:client">`+
|
||||
`<query xmlns="jabber:iq:register">`+
|
||||
`<x type="submit" xmlns="jabber:x:data">`+
|
||||
`<field var="FORM_TYPE"><value>http://jabber.org/protocol/muc#register</value></field>`+
|
||||
`<field var="muc#register_roomnick"><value>romeo</value></field>`+
|
||||
`</x>`+
|
||||
`</query>`+
|
||||
`</iq>`);
|
||||
done();
|
||||
}));
|
||||
|
||||
});
|
||||
|
||||
describe("The auto_register_muc_nickname option", function () {
|
||||
|
||||
it("allows you to automatically register your nickname when joining a room",
|
||||
mock.initConverse(
|
||||
['rosterGroupsFetched', 'chatBoxesFetched'], {'auto_register_muc_nickname': true},
|
||||
async function (done, _converse) {
|
||||
|
||||
const muc_jid = 'coven@chat.shakespeare.lit';
|
||||
await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
|
||||
const view = _converse.chatboxviews.get(muc_jid);
|
||||
|
||||
let stanza = await u.waitUntil(() => _.filter(
|
||||
_converse.connection.IQ_stanzas,
|
||||
iq => sizzle(`iq[to="coven@chat.shakespeare.lit"][type="get"] query[xmlns="jabber:iq:register"]`, iq).length
|
||||
).pop());
|
||||
|
||||
expect(Strophe.serialize(stanza))
|
||||
.toBe(`<iq from="romeo@montague.lit/orchard" id="${stanza.getAttribute('id')}" to="coven@chat.shakespeare.lit" `+
|
||||
`type="get" xmlns="jabber:client">`+
|
||||
`<query xmlns="jabber:iq:register"/></iq>`);
|
||||
const result = $iq({
|
||||
'from': view.model.get('jid'),
|
||||
'id': stanza.getAttribute('id'),
|
||||
'to': _converse.bare_jid,
|
||||
'type': 'result',
|
||||
}).c('query', {'type': 'jabber:iq:register'})
|
||||
.c('x', {'xmlns': 'jabber:x:data', 'type': 'form'})
|
||||
.c('field', {
|
||||
'label': 'Desired Nickname',
|
||||
'type': 'text-single',
|
||||
'var': 'muc#register_roomnick'
|
||||
}).c('required');
|
||||
_converse.connection._dataRecv(mock.createRequest(result));
|
||||
stanza = await u.waitUntil(() => _.filter(
|
||||
_converse.connection.IQ_stanzas,
|
||||
iq => sizzle(`iq[to="coven@chat.shakespeare.lit"][type="set"] query[xmlns="jabber:iq:register"]`, iq).length
|
||||
).pop());
|
||||
|
||||
expect(Strophe.serialize(stanza)).toBe(
|
||||
`<iq from="romeo@montague.lit/orchard" id="${stanza.getAttribute('id')}" to="coven@chat.shakespeare.lit" type="set" xmlns="jabber:client">`+
|
||||
`<query xmlns="jabber:iq:register">`+
|
||||
`<x type="submit" xmlns="jabber:x:data">`+
|
||||
`<field var="FORM_TYPE"><value>http://jabber.org/protocol/muc#register</value></field>`+
|
||||
`<field var="muc#register_roomnick"><value>romeo</value></field>`+
|
||||
`</x>`+
|
||||
`</query>`+
|
||||
`</iq>`);
|
||||
done();
|
||||
}));
|
||||
});
|
||||
});
|
@ -1,246 +0,0 @@
|
||||
import "./autocomplete.js"
|
||||
import log from "@converse/headless/log";
|
||||
import sizzle from "sizzle";
|
||||
import { CustomElement } from './element.js';
|
||||
import { __ } from '../i18n';
|
||||
import { api, converse } from "@converse/headless/converse-core";
|
||||
import { html } from "lit-html";
|
||||
import { unsafeHTML } from 'lit-html/directives/unsafe-html.js';
|
||||
|
||||
const { Strophe, $iq } = converse.env;
|
||||
const u = converse.env.utils;
|
||||
|
||||
|
||||
const tpl_command_form = (o, command) => {
|
||||
const i18n_hide = __('Hide');
|
||||
const i18n_run = __('Execute');
|
||||
return html`
|
||||
<form @submit=${o.runCommand}>
|
||||
${ command.alert ? html`<div class="alert alert-${command.alert_type}" role="alert">${command.alert}</div>` : '' }
|
||||
<fieldset class="form-group">
|
||||
<input type="hidden" name="command_node" value="${command.node}"/>
|
||||
<input type="hidden" name="command_jid" value="${command.jid}"/>
|
||||
|
||||
<p class="form-help">${command.instructions}</p>
|
||||
<!-- Fields are generated internally, with xForm2webForm -->
|
||||
${ command.fields.map(field => unsafeHTML(field)) }
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<input type="submit" class="btn btn-primary" value="${i18n_run}">
|
||||
<input type="button" class="btn btn-secondary button-cancel" value="${i18n_hide}" @click=${o.hideCommandForm}>
|
||||
</fieldset>
|
||||
</form>
|
||||
`;
|
||||
}
|
||||
|
||||
|
||||
const tpl_command = (o, command) => html`
|
||||
<li class="room-item list-group-item">
|
||||
<div class="available-chatroom d-flex flex-row">
|
||||
<a class="open-room available-room w-100"
|
||||
@click=${o.toggleCommandForm}
|
||||
data-command-node="${command.node}"
|
||||
data-command-jid="${command.jid}"
|
||||
data-command-name="${command.name}"
|
||||
title="${command.name}"
|
||||
href="#">${command.name || command.jid}</a>
|
||||
</div>
|
||||
${ command.node === o.showform ? tpl_command_form(o, command) : '' }
|
||||
</li>
|
||||
`;
|
||||
|
||||
|
||||
async function getAutoCompleteList () {
|
||||
const models = [...(await api.rooms.get()), ...(await api.contacts.get())];
|
||||
const jids = [...new Set(models.map(o => Strophe.getDomainFromJid(o.get('jid'))))];
|
||||
return jids;
|
||||
}
|
||||
|
||||
const tpl_adhoc = (o) => {
|
||||
const i18n_choose_service = __('On which entity do you want to run commands?');
|
||||
const i18n_choose_service_instructions = __(
|
||||
'Certain XMPP services and entities allow privileged users to execute ad-hoc commands on them.');
|
||||
const i18n_commands_found = __('Commands found');
|
||||
const i18n_fetch_commands = __('List available commands');
|
||||
const i18n_jid_placeholder = __('XMPP Address');
|
||||
const i18n_no_commands_found = __('No commands found');
|
||||
return html`
|
||||
${ o.alert ? html`<div class="alert alert-${o.alert_type}" role="alert">${o.alert}</div>` : '' }
|
||||
<form class="converse-form" @submit=${o.fetchCommands}>
|
||||
<fieldset class="form-group">
|
||||
<label>
|
||||
${i18n_choose_service}
|
||||
<p class="form-help">${i18n_choose_service_instructions}</p>
|
||||
<converse-autocomplete
|
||||
.getAutoCompleteList="${getAutoCompleteList}"
|
||||
placeholder="${i18n_jid_placeholder}"
|
||||
name="jid"/>
|
||||
</label>
|
||||
</fieldset>
|
||||
<fieldset class="form-group">
|
||||
<input type="submit" class="btn btn-primary" value="${i18n_fetch_commands}">
|
||||
</fieldset>
|
||||
${ o.view === 'list-commands' ? html`
|
||||
<fieldset class="form-group">
|
||||
<ul class="list-group">
|
||||
<li class="list-group-item active">${ o.commands.length ? i18n_commands_found : i18n_no_commands_found }:</li>
|
||||
${ o.commands.map(cmd => tpl_command(o, cmd)) }
|
||||
</ul>
|
||||
</fieldset>`
|
||||
: '' }
|
||||
|
||||
</form>
|
||||
`;
|
||||
}
|
||||
|
||||
|
||||
async function fetchCommandForm (command) {
|
||||
const node = command.node;
|
||||
const jid = command.jid;
|
||||
const stanza = $iq({
|
||||
'type': 'set',
|
||||
'to': jid
|
||||
}).c('command', {
|
||||
'xmlns': Strophe.NS.ADHOC,
|
||||
'node': node,
|
||||
'action': 'execute'
|
||||
});
|
||||
try {
|
||||
const iq = await api.sendIQ(stanza);
|
||||
const cmd_el = sizzle(`command[xmlns="${Strophe.NS.ADHOC}"]`, iq).pop();
|
||||
command.sessionid = cmd_el.getAttribute('sessionid');
|
||||
command.instructions = sizzle('x[type="form"][xmlns="jabber:x:data"] instructions', cmd_el).pop()?.textContent;
|
||||
command.fields = sizzle('x[type="form"][xmlns="jabber:x:data"] field', cmd_el)
|
||||
.map(f => u.xForm2webForm(f, cmd_el));
|
||||
|
||||
} catch (e) {
|
||||
if (e === null) {
|
||||
log.error(`Error: timeout while trying to execute command for ${jid}`);
|
||||
} else {
|
||||
log.error(`Error while trying to execute command for ${jid}`);
|
||||
log.error(e);
|
||||
}
|
||||
command.fields = [];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export default class AdHocCommands extends CustomElement {
|
||||
|
||||
static get properties () {
|
||||
return {
|
||||
'alert': { type: String },
|
||||
'alert_type': { type: String },
|
||||
'nonce': { type: String }, // Used to force re-rendering
|
||||
'showform': { type: String },
|
||||
'view': { type: String },
|
||||
}
|
||||
}
|
||||
|
||||
constructor () {
|
||||
super();
|
||||
this.view = 'choose-service';
|
||||
this.showform = '';
|
||||
this.commands = [];
|
||||
}
|
||||
|
||||
render () {
|
||||
return tpl_adhoc({
|
||||
'alert': this.alert,
|
||||
'alert_type': this.alert_type,
|
||||
'commands': this.commands,
|
||||
'fetchCommands': ev => this.fetchCommands(ev),
|
||||
'hideCommandForm': ev => this.hideCommandForm(ev),
|
||||
'runCommand': ev => this.runCommand(ev),
|
||||
'showform': this.showform,
|
||||
'toggleCommandForm': ev => this.toggleCommandForm(ev),
|
||||
'view': this.view,
|
||||
});
|
||||
}
|
||||
|
||||
async fetchCommands (ev) {
|
||||
ev.preventDefault();
|
||||
delete this.alert_type;
|
||||
delete this.alert;
|
||||
|
||||
const form_data = new FormData(ev.target);
|
||||
const jid = form_data.get('jid').trim();
|
||||
let supported;
|
||||
try {
|
||||
supported = await api.disco.supports(Strophe.NS.ADHOC, jid)
|
||||
} catch (e) {
|
||||
log.error(e);
|
||||
}
|
||||
if (supported) {
|
||||
try {
|
||||
this.commands = await api.adhoc.getCommands(jid);
|
||||
this.view = 'list-commands';
|
||||
} catch (e) {
|
||||
log.error(e);
|
||||
this.alert_type = 'danger';
|
||||
this.alert = __('Sorry, an error occurred while looking for commands on that entity.');
|
||||
this.commands = [];
|
||||
log.error(e);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
this.alert_type = 'danger';
|
||||
this.alert = __("The specified entity doesn't support ad-hoc commands");
|
||||
}
|
||||
}
|
||||
|
||||
async toggleCommandForm (ev) {
|
||||
ev.preventDefault();
|
||||
const node = ev.target.getAttribute('data-command-node');
|
||||
const cmd = this.commands.filter(c => c.node === node)[0];
|
||||
this.showform !== node && await fetchCommandForm(cmd);
|
||||
this.showform = node;
|
||||
}
|
||||
|
||||
hideCommandForm (ev) {
|
||||
ev.preventDefault();
|
||||
this.showform = ''
|
||||
}
|
||||
|
||||
async runCommand (ev) {
|
||||
ev.preventDefault();
|
||||
const form_data = new FormData(ev.target);
|
||||
const jid = form_data.get('command_jid').trim();
|
||||
const node = form_data.get('command_node').trim();
|
||||
|
||||
const cmd = this.commands.filter(c => c.node === node)[0];
|
||||
const inputs = sizzle(':input:not([type=button]):not([type=submit])', ev.target);
|
||||
const config_array = inputs
|
||||
.filter(i => !['command_jid', 'command_node'].includes(i.getAttribute('name')))
|
||||
.map(u.webForm2xForm)
|
||||
.filter(n => n);
|
||||
|
||||
const iq = $iq({to: jid, type: "set"})
|
||||
.c("command", {
|
||||
'sessionid': cmd.sessionid,
|
||||
'node': cmd.node,
|
||||
'xmlns': Strophe.NS.ADHOC
|
||||
}).c("x", {xmlns: Strophe.NS.XFORM, type: "submit"});
|
||||
config_array.forEach(node => iq.cnode(node).up());
|
||||
|
||||
let result;
|
||||
try {
|
||||
result = await api.sendIQ(iq);
|
||||
} catch (e) {
|
||||
cmd.alert_type = 'danger';
|
||||
cmd.alert = __('Sorry, an error occurred while trying to execute the command. See the developer console for details');
|
||||
log.error('Error while trying to execute an ad-hoc command');
|
||||
log.error(e);
|
||||
}
|
||||
|
||||
if (result) {
|
||||
cmd.alert = result.querySelector('note')?.textContent;
|
||||
} else {
|
||||
cmd.alert = 'Done';
|
||||
}
|
||||
cmd.alert_type = 'primary';
|
||||
this.nonce = u.getUniqueId();
|
||||
}
|
||||
}
|
||||
|
||||
api.elements.define('converse-adhoc-commands', AdHocCommands);
|
@ -1,73 +0,0 @@
|
||||
import { AutoComplete, FILTER_CONTAINS, FILTER_STARTSWITH } from "../converse-autocomplete.js";
|
||||
import { CustomElement } from './element.js';
|
||||
import { html } from 'lit-element';
|
||||
import { api } from "@converse/headless/converse-core";
|
||||
|
||||
export default class AutoCompleteComponent extends CustomElement {
|
||||
|
||||
static get properties () {
|
||||
return {
|
||||
'getAutoCompleteList': { type: Function },
|
||||
'auto_evaluate': { type: Boolean },
|
||||
'auto_first': { type: Boolean }, // Should the first element be automatically selected?
|
||||
'filter': { type: String },
|
||||
'include_triggers': { type: String },
|
||||
'min_chars': { type: Number },
|
||||
'name': { type: String },
|
||||
'placeholder': { type: String },
|
||||
'triggers': { type: String },
|
||||
}
|
||||
}
|
||||
|
||||
constructor () {
|
||||
super();
|
||||
this.auto_evaluate = true; // Should evaluation happen automatically without any particular key as trigger?
|
||||
this.auto_first = false; // Should the first element be automatically selected?
|
||||
this.filter = 'contains';
|
||||
this.include_triggers = ''; // Space separated chars which should be included in the returned value
|
||||
this.match_current_word = false; // Match only the current word, otherwise all input is matched
|
||||
this.max_items = 10;
|
||||
this.min_chars = 1;
|
||||
this.triggers = ''; // String of space separated chars
|
||||
}
|
||||
|
||||
render () {
|
||||
return html`
|
||||
<div class="suggestion-box suggestion-box__name">
|
||||
<ul class="suggestion-box__results suggestion-box__results--above" hidden=""></ul>
|
||||
<input type="text" name="${this.name}"
|
||||
autocomplete="off"
|
||||
@keydown=${this.onKeyDown}
|
||||
@keyup=${this.onKeyUp}
|
||||
class="form-control suggestion-box__input"
|
||||
placeholder="${this.placeholder}"/>
|
||||
<span class="suggestion-box__additions visually-hidden" role="status" aria-live="assertive" aria-relevant="additions"></span>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
firstUpdated () {
|
||||
this.auto_complete = new AutoComplete(this.firstElementChild, {
|
||||
'ac_triggers': this.triggers.split(' '),
|
||||
'auto_evaluate': this.auto_evaluate,
|
||||
'auto_first': this.auto_first,
|
||||
'filter': this.filter == 'contains' ? FILTER_CONTAINS : FILTER_STARTSWITH,
|
||||
'include_triggers': [],
|
||||
'list': () => this.getAutoCompleteList(),
|
||||
'match_current_word': true,
|
||||
'max_items': this.max_items,
|
||||
'min_chars': this.min_chars,
|
||||
});
|
||||
this.auto_complete.on('suggestion-box-selectcomplete', () => (this.auto_completing = false));
|
||||
}
|
||||
|
||||
onKeyDown (ev) {
|
||||
this.auto_complete.onKeyDown(ev);
|
||||
}
|
||||
|
||||
onKeyUp (ev) {
|
||||
this.auto_complete.evaluate(ev);
|
||||
}
|
||||
}
|
||||
|
||||
api.elements.define('converse-autocomplete', AutoCompleteComponent);
|
@ -1,42 +0,0 @@
|
||||
import { api } from "@converse/headless/converse-core";
|
||||
import { component } from 'haunted';
|
||||
import { html } from 'lit-html';
|
||||
|
||||
export const ConverseBrandHeading = (o) => {
|
||||
const is_fullscreen = api.settings.get('view_mode') === 'fullscreen';
|
||||
return html`
|
||||
<a class="brand-heading" href="https://conversejs.org" target="_blank" rel="noopener">
|
||||
<span class="brand-name-wrapper ${is_fullscreen ? 'brand-name-wrapper--fullscreen' : '' }">
|
||||
<svg class="converse-svg-logo"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
viewBox="0 0 364 364">
|
||||
<title>Converse</title>
|
||||
<g class="cls-1" id="g904">
|
||||
<g data-name="Layer 2">
|
||||
<g data-name="Layer 7">
|
||||
<path
|
||||
class="cls-3"
|
||||
d="M221.46,103.71c0,18.83-29.36,18.83-29.12,0C192.1,84.88,221.46,84.88,221.46,103.71Z" />
|
||||
<path
|
||||
class="cls-4"
|
||||
d="M179.9,4.15A175.48,175.48,0,1,0,355.38,179.63,175.48,175.48,0,0,0,179.9,4.15Zm-40.79,264.5c-.23-17.82,27.58-17.82,27.58,0S138.88,286.48,139.11,268.65ZM218.6,168.24A79.65,79.65,0,0,1,205.15,174a12.76,12.76,0,0,0-6.29,4.65L167.54,222a1.36,1.36,0,0,1-2.46-.8v-35.8a2.58,2.58,0,0,0-3.06-2.53c-15.43,3-30.23,7.7-42.73,19.94-38.8,38-29.42,105.69,16.09,133.16a162.25,162.25,0,0,1-91.47-67.27C-3.86,182.26,34.5,47.25,138.37,25.66c46.89-9.75,118.25,5.16,123.73,62.83C265.15,120.64,246.56,152.89,218.6,168.24Z" />
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
<span class="brand-name">
|
||||
<span class="brand-name__text">converse<span class="subdued">.js</span></span>
|
||||
${ is_fullscreen ? html`<p class="byline">messaging freedom</p>` : '' }
|
||||
</span>
|
||||
</span>
|
||||
</a>
|
||||
${ is_fullscreen ? html`
|
||||
<p class="brand-subtitle">${o.version_name}</p>
|
||||
<p class="brand-subtitle"><a target="_blank" rel="nofollow" href="https://conversejs.org">Open Source</a> XMPP chat client brought to you by <a target="_blank" rel="nofollow" href="https://opkode.com">Opkode</a> </p>
|
||||
<p class="brand-subtitle"><a target="_blank" rel="nofollow" href="https://hosted.weblate.org/projects/conversejs/#languages">Translate</a> it into your own language</p>` : '' }
|
||||
`;
|
||||
}
|
||||
|
||||
api.elements.define('converse-brand-heading', component(ConverseBrandHeading, {'useShadowDOM': false}));
|
@ -1,30 +0,0 @@
|
||||
import "./message-history";
|
||||
import xss from "xss/dist/xss";
|
||||
import { CustomElement } from './element.js';
|
||||
import { html } from 'lit-element';
|
||||
import { unsafeHTML } from 'lit-html/directives/unsafe-html.js';
|
||||
import { api } from "@converse/headless/converse-core";
|
||||
|
||||
export default class ChatContent extends CustomElement {
|
||||
|
||||
static get properties () {
|
||||
return {
|
||||
chatview: { type: Object},
|
||||
messages: { type: Array},
|
||||
notifications: { type: String }
|
||||
}
|
||||
}
|
||||
|
||||
render () {
|
||||
const notifications = xss.filterXSS(this.notifications, {'whiteList': {}});
|
||||
return html`
|
||||
<converse-message-history
|
||||
.chatview=${this.chatview}
|
||||
.messages=${this.messages}>
|
||||
</converse-message-history>
|
||||
<div class="chat-content__notifications">${unsafeHTML(notifications)}</div>
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
api.elements.define('converse-chat-content', ChatContent);
|
@ -1,19 +0,0 @@
|
||||
import { api, converse } from "@converse/headless/converse-core";
|
||||
|
||||
|
||||
/**
|
||||
* `converse-root` is an optional custom element which can be used to
|
||||
* declaratively insert the Converse UI into the DOM.
|
||||
*
|
||||
* It can be inserted into the DOM before or after Converse has loaded or been
|
||||
* initialized.
|
||||
*/
|
||||
class ConverseRoot extends HTMLElement {
|
||||
|
||||
async connectedCallback () {
|
||||
await api.waitUntil('initialized');
|
||||
converse.insertInto(this);
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define('converse-root', ConverseRoot);
|
@ -1,112 +0,0 @@
|
||||
import DOMNavigator from "../dom-navigator";
|
||||
import { CustomElement } from './element.js';
|
||||
import { converse, api } from "@converse/headless/converse-core";
|
||||
import { html } from 'lit-element';
|
||||
import { until } from 'lit-html/directives/until.js';
|
||||
|
||||
const u = converse.env.utils;
|
||||
|
||||
|
||||
export class BaseDropdown extends CustomElement {
|
||||
|
||||
firstUpdated () {
|
||||
this.menu = this.querySelector('.dropdown-menu');
|
||||
this.dropdown = this.firstElementChild;
|
||||
this.button = this.dropdown.querySelector('button');
|
||||
this.dropdown.addEventListener('click', ev => this.toggleMenu(ev));
|
||||
this.dropdown.addEventListener('keyup', ev => this.handleKeyUp(ev));
|
||||
document.addEventListener('click', ev => !this.contains(ev.composedPath()[0]) && this.hideMenu(ev));
|
||||
}
|
||||
|
||||
hideMenu () {
|
||||
u.removeClass('show', this.menu);
|
||||
this.button?.setAttribute('aria-expanded', false);
|
||||
this.button?.blur();
|
||||
}
|
||||
|
||||
showMenu () {
|
||||
u.addClass('show', this.menu);
|
||||
this.button.setAttribute('aria-expanded', true);
|
||||
}
|
||||
|
||||
toggleMenu (ev) {
|
||||
ev.preventDefault();
|
||||
if (u.hasClass('show', this.menu)) {
|
||||
this.hideMenu();
|
||||
} else {
|
||||
this.showMenu();
|
||||
}
|
||||
}
|
||||
|
||||
handleKeyUp (ev) {
|
||||
if (ev.keyCode === converse.keycodes.ESCAPE) {
|
||||
this.hideMenu();
|
||||
} else if (ev.keyCode === converse.keycodes.DOWN_ARROW && this.navigator && !this.navigator.enabled) {
|
||||
this.enableArrowNavigation(ev);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export default class DropdownList extends BaseDropdown {
|
||||
|
||||
static get properties () {
|
||||
return {
|
||||
'icon_classes': { type: String },
|
||||
'items': { type: Array }
|
||||
}
|
||||
}
|
||||
|
||||
render () {
|
||||
const icon_classes = this.icon_classes || "fa fa-bars";
|
||||
return html`
|
||||
<div class="dropleft">
|
||||
<button type="button" class="btn btn--transparent btn--standalone" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
<i class="${icon_classes} only-icon"></i>
|
||||
</button>
|
||||
<div class="dropdown-menu">
|
||||
${ this.items.map(b => until(b, '')) }
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
hideMenu () {
|
||||
super.hideMenu();
|
||||
this.navigator.disable();
|
||||
}
|
||||
|
||||
|
||||
firstUpdated () {
|
||||
super.firstUpdated();
|
||||
this.initArrowNavigation();
|
||||
}
|
||||
|
||||
initArrowNavigation () {
|
||||
if (!this.navigator) {
|
||||
const options = {
|
||||
'selector': '.dropdown-item',
|
||||
'onSelected': el => el.focus()
|
||||
};
|
||||
this.navigator = new DOMNavigator(this.menu, options);
|
||||
}
|
||||
}
|
||||
|
||||
enableArrowNavigation (ev) {
|
||||
if (ev) {
|
||||
ev.preventDefault();
|
||||
ev.stopPropagation();
|
||||
}
|
||||
this.navigator.enable();
|
||||
this.navigator.select(this.menu.firstElementChild);
|
||||
}
|
||||
|
||||
handleKeyUp (ev) {
|
||||
super.handleKeyUp(ev);
|
||||
if (ev.keyCode === converse.keycodes.DOWN_ARROW && !this.navigator.enabled) {
|
||||
this.enableArrowNavigation(ev);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
api.elements.define('converse-dropdown', DropdownList);
|
@ -1,20 +0,0 @@
|
||||
import { CustomElement } from './element.js';
|
||||
import { html } from "lit-element";
|
||||
import { unsafeSVG } from 'lit-html/directives/unsafe-svg.js';
|
||||
import { until } from 'lit-html/directives/until.js';
|
||||
|
||||
|
||||
export class FontAwesome extends CustomElement {
|
||||
|
||||
constructor () {
|
||||
super();
|
||||
const promise = import(/*webpackChunkName: "icons" */ '../../images/icons.svg');
|
||||
this.data = promise.then(d => html`${unsafeSVG(d.default())}`);
|
||||
}
|
||||
|
||||
render () { // eslint-disable-line class-methods-use-this
|
||||
return html`${until(this.data, '')}`;
|
||||
}
|
||||
}
|
||||
|
||||
window.customElements.define('converse-fontawesome', FontAwesome);
|